From d4a2904e6b58b0f7d4c442a43440cf24c1d4cb32 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Wed, 8 Apr 2020 17:50:06 -0700 Subject: [PATCH 01/20] Remove files --- .../shared_preferences/CHANGELOG.md | 4 + .../lib/shared_preferences.dart | 10 +- .../shared_preferences/pubspec.yaml | 5 +- .../shared_preferences_windows/.metadata | 10 ++ .../shared_preferences_windows/CHANGELOG.md | 3 + .../shared_preferences_windows/LICENSE | 27 ++++ .../shared_preferences_windows/README.md | 23 ++++ .../android/.gitignore | 8 ++ .../android/build.gradle | 43 +++++++ .../android/gradle.properties | 4 + .../gradle/wrapper/gradle-wrapper.properties | 5 + .../android/settings.gradle | 1 + .../android/src/main/AndroidManifest.xml | 3 + .../SharedPreferencesWindowsPlugin.kt | 53 ++++++++ .../example/.gitignore | 43 +++++++ .../example/.metadata | 10 ++ .../example/CHANGELOG.md | 3 + .../example/LICENSE | 1 + .../example/README.md | 16 +++ .../example/lib/main.dart | 87 +++++++++++++ .../example/pubspec.yaml | 24 ++++ .../test_driver/shared_preferences_e2e.dart | 89 +++++++++++++ .../shared_preferences_e2e_test.dart | 15 +++ .../ios/shared_preferences_windows.podspec | 20 +++ .../lib/shared_preferences_windows.dart | 119 ++++++++++++++++++ .../lib/src/win32.dart | 86 +++++++++++++ .../shared_preferences_windows/pubspec.yaml | 27 ++++ .../test/shared_preferences_windows_test.dart | 86 +++++++++++++ 28 files changed, 822 insertions(+), 3 deletions(-) create mode 100644 packages/shared_preferences/shared_preferences_windows/.metadata create mode 100644 packages/shared_preferences/shared_preferences_windows/CHANGELOG.md create mode 100644 packages/shared_preferences/shared_preferences_windows/LICENSE create mode 100644 packages/shared_preferences/shared_preferences_windows/README.md create mode 100644 packages/shared_preferences/shared_preferences_windows/android/.gitignore create mode 100644 packages/shared_preferences/shared_preferences_windows/android/build.gradle create mode 100644 packages/shared_preferences/shared_preferences_windows/android/gradle.properties create mode 100644 packages/shared_preferences/shared_preferences_windows/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 packages/shared_preferences/shared_preferences_windows/android/settings.gradle create mode 100644 packages/shared_preferences/shared_preferences_windows/android/src/main/AndroidManifest.xml create mode 100644 packages/shared_preferences/shared_preferences_windows/android/src/main/kotlin/com/example/shared_preferences_windows/SharedPreferencesWindowsPlugin.kt create mode 100644 packages/shared_preferences/shared_preferences_windows/example/.gitignore create mode 100644 packages/shared_preferences/shared_preferences_windows/example/.metadata create mode 100644 packages/shared_preferences/shared_preferences_windows/example/CHANGELOG.md create mode 100644 packages/shared_preferences/shared_preferences_windows/example/LICENSE create mode 100644 packages/shared_preferences/shared_preferences_windows/example/README.md create mode 100644 packages/shared_preferences/shared_preferences_windows/example/lib/main.dart create mode 100644 packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml create mode 100644 packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart create mode 100644 packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e_test.dart create mode 100644 packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec create mode 100644 packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart create mode 100644 packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart create mode 100644 packages/shared_preferences/shared_preferences_windows/pubspec.yaml create mode 100644 packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 256b084816e9..069391030ab3 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.5.7 + +* Adds support for Windows. + ## 0.5.6+3 * Fix deprecated API usage warning. diff --git a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart index 62160dee20fd..aa601dcc80ab 100644 --- a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart @@ -5,8 +5,10 @@ import 'dart:async'; import 'package:meta/meta.dart'; +import 'package:platform/platform.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; +import 'package:shared_preferences_windows/shared_preferences_windows.dart'; /// Wraps NSUserDefaults (on iOS) and SharedPreferences (on Android), providing /// a persistent store for simple data. @@ -18,8 +20,12 @@ class SharedPreferences { static const String _prefix = 'flutter.'; static Completer _completer; - static SharedPreferencesStorePlatform get _store => - SharedPreferencesStorePlatform.instance; + static SharedPreferencesStorePlatform get _store { + if (LocalPlatform().isWindows) { + return SharedPreferencesWindows(); + } + return SharedPreferencesStorePlatform.instance; + } /// Loads and parses the [SharedPreferences] for this app from disk. /// diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 099c95220b7d..163f86d7878e 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -2,7 +2,7 @@ name: shared_preferences description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences -version: 0.5.6+3 +version: 0.5.7 flutter: plugin: @@ -21,6 +21,7 @@ dependencies: meta: ^1.0.4 flutter: sdk: flutter + platform: 2.2.1 shared_preferences_platform_interface: ^1.0.0 # The design on https://flutter.dev/go/federated-plugins was to leave # this constraint as "any". We cannot do it right now as it fails pub publish @@ -29,6 +30,8 @@ dependencies: # https://github.com/flutter/flutter/issues/46264 shared_preferences_macos: ^0.0.1 shared_preferences_web: ^0.1.2 + shared_preferences_windows: + path: ../shared_preferences_windows dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_windows/.metadata b/packages/shared_preferences/shared_preferences_windows/.metadata new file mode 100644 index 000000000000..55d1df5ced9a --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: df90bb5fd64e2066594151b9e311d45cd687a80c + channel: master + +project_type: plugin diff --git a/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md new file mode 100644 index 000000000000..b3a547cdac34 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* Initial release to support shared_preferences on Windows. diff --git a/packages/shared_preferences/shared_preferences_windows/LICENSE b/packages/shared_preferences/shared_preferences_windows/LICENSE new file mode 100644 index 000000000000..0c382ce171cc --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/LICENSE @@ -0,0 +1,27 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/shared_preferences/shared_preferences_windows/README.md b/packages/shared_preferences/shared_preferences_windows/README.md new file mode 100644 index 000000000000..dd710f4c7336 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/README.md @@ -0,0 +1,23 @@ +# shared_preferences_windows + +The Windows implementation of [`shared_preferences`][1]. + +## Usage + +### Import the package + +This package has been endorsed, meaning that you only need to add `shared_preferences` +as a dependency in your `pubspec.yaml`. It will be automatically included in your app +when you depend on `package:shared_preferences`. + +This is what the above means to your `pubspec.yaml`: + +```yaml +... +dependencies: + ... + shared_preferences: ^0.5.7 + ... +``` + +[1]: ../ diff --git a/packages/shared_preferences/shared_preferences_windows/android/.gitignore b/packages/shared_preferences/shared_preferences_windows/android/.gitignore new file mode 100644 index 000000000000..c6cbe562a427 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/android/.gitignore @@ -0,0 +1,8 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures diff --git a/packages/shared_preferences/shared_preferences_windows/android/build.gradle b/packages/shared_preferences/shared_preferences_windows/android/build.gradle new file mode 100644 index 000000000000..edbf36e5588b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/android/build.gradle @@ -0,0 +1,43 @@ +group 'com.example.shared_preferences_windows' +version '1.0-SNAPSHOT' + +buildscript { + ext.kotlin_version = '1.3.50' + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.5.0' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' + +android { + compileSdkVersion 28 + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + defaultConfig { + minSdkVersion 16 + } + lintOptions { + disable 'InvalidPackage' + } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" +} diff --git a/packages/shared_preferences/shared_preferences_windows/android/gradle.properties b/packages/shared_preferences/shared_preferences_windows/android/gradle.properties new file mode 100644 index 000000000000..38c8d4544ff1 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/android/gradle.properties @@ -0,0 +1,4 @@ +org.gradle.jvmargs=-Xmx1536M +android.enableR8=true +android.useAndroidX=true +android.enableJetifier=true diff --git a/packages/shared_preferences/shared_preferences_windows/android/gradle/wrapper/gradle-wrapper.properties b/packages/shared_preferences/shared_preferences_windows/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000000..01a286e96a21 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/packages/shared_preferences/shared_preferences_windows/android/settings.gradle b/packages/shared_preferences/shared_preferences_windows/android/settings.gradle new file mode 100644 index 000000000000..307c6c67684e --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'shared_preferences_windows' diff --git a/packages/shared_preferences/shared_preferences_windows/android/src/main/AndroidManifest.xml b/packages/shared_preferences/shared_preferences_windows/android/src/main/AndroidManifest.xml new file mode 100644 index 000000000000..e55611ff0c7e --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/packages/shared_preferences/shared_preferences_windows/android/src/main/kotlin/com/example/shared_preferences_windows/SharedPreferencesWindowsPlugin.kt b/packages/shared_preferences/shared_preferences_windows/android/src/main/kotlin/com/example/shared_preferences_windows/SharedPreferencesWindowsPlugin.kt new file mode 100644 index 000000000000..fa4c5b021542 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/android/src/main/kotlin/com/example/shared_preferences_windows/SharedPreferencesWindowsPlugin.kt @@ -0,0 +1,53 @@ +package com.example.shared_preferences_windows + +import androidx.annotation.NonNull; + +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.MethodCall +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugin.common.MethodChannel.MethodCallHandler +import io.flutter.plugin.common.MethodChannel.Result +import io.flutter.plugin.common.PluginRegistry.Registrar + +/** SharedPreferencesWindowsPlugin */ +public class SharedPreferencesWindowsPlugin: FlutterPlugin, MethodCallHandler { + /// The MethodChannel that will the communication between Flutter and native Android + /// + /// This local reference serves to register the plugin with the Flutter Engine and unregister it + /// when the Flutter Engine is detached from the Activity + private lateinit var channel : MethodChannel + + override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { + channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "shared_preferences_windows") + channel.setMethodCallHandler(this); + } + + // This static function is optional and equivalent to onAttachedToEngine. It supports the old + // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting + // plugin registration via this function while apps migrate to use the new Android APIs + // post-flutter-1.12 via https://flutter.dev/go/android-project-migration. + // + // It is encouraged to share logic between onAttachedToEngine and registerWith to keep + // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called + // depending on the user's project. onAttachedToEngine or registerWith must both be defined + // in the same class. + companion object { + @JvmStatic + fun registerWith(registrar: Registrar) { + val channel = MethodChannel(registrar.messenger(), "shared_preferences_windows") + channel.setMethodCallHandler(SharedPreferencesWindowsPlugin()) + } + } + + override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { + if (call.method == "getPlatformVersion") { + result.success("Android ${android.os.Build.VERSION.RELEASE}") + } else { + result.notImplemented() + } + } + + override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { + channel.setMethodCallHandler(null) + } +} diff --git a/packages/shared_preferences/shared_preferences_windows/example/.gitignore b/packages/shared_preferences/shared_preferences_windows/example/.gitignore new file mode 100644 index 000000000000..1ba9c339effb --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/.gitignore @@ -0,0 +1,43 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Exceptions to above rules. +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages diff --git a/packages/shared_preferences/shared_preferences_windows/example/.metadata b/packages/shared_preferences/shared_preferences_windows/example/.metadata new file mode 100644 index 000000000000..d39696748cee --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: df90bb5fd64e2066594151b9e311d45cd687a80c + channel: master + +project_type: app diff --git a/packages/shared_preferences/shared_preferences_windows/example/CHANGELOG.md b/packages/shared_preferences/shared_preferences_windows/example/CHANGELOG.md new file mode 100644 index 000000000000..41cc7d8192ec --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* TODO: Describe initial release. diff --git a/packages/shared_preferences/shared_preferences_windows/example/LICENSE b/packages/shared_preferences/shared_preferences_windows/example/LICENSE new file mode 100644 index 000000000000..ba75c69f7f21 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/LICENSE @@ -0,0 +1 @@ +TODO: Add your license here. diff --git a/packages/shared_preferences/shared_preferences_windows/example/README.md b/packages/shared_preferences/shared_preferences_windows/example/README.md new file mode 100644 index 000000000000..d85bb4107622 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/README.md @@ -0,0 +1,16 @@ +# shared_preferences_windows_example + +Demonstrates how to use the shared_preferences_windows plugin. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart new file mode 100644 index 000000000000..46daeff6706f --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart @@ -0,0 +1,87 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: public_member_api_docs + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'SharedPreferences Demo', + home: SharedPreferencesDemo(), + ); + } +} + +class SharedPreferencesDemo extends StatefulWidget { + SharedPreferencesDemo({Key key}) : super(key: key); + + @override + SharedPreferencesDemoState createState() => SharedPreferencesDemoState(); +} + +class SharedPreferencesDemoState extends State { + Future _prefs = SharedPreferences.getInstance(); + Future _counter; + + Future _incrementCounter() async { + final SharedPreferences prefs = await _prefs; + final int counter = (prefs.getInt('counter') ?? 0) + 1; + + setState(() { + _counter = prefs.setInt("counter", counter).then((bool success) { + return counter; + }); + }); + } + + @override + void initState() { + super.initState(); + _counter = _prefs.then((SharedPreferences prefs) { + return (prefs.getInt('counter') ?? 0); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text("SharedPreferences Demo"), + ), + body: Center( + child: FutureBuilder( + future: _counter, + builder: (BuildContext context, AsyncSnapshot snapshot) { + switch (snapshot.connectionState) { + case ConnectionState.waiting: + return const CircularProgressIndicator(); + default: + if (snapshot.hasError) { + return Text('Error: ${snapshot.error}'); + } else { + return Text( + 'Button tapped ${snapshot.data} time${snapshot.data == 1 ? '' : 's'}.\n\n' + 'This should persist across restarts.', + ); + } + } + })), + floatingActionButton: FloatingActionButton( + onPressed: _incrementCounter, + tooltip: 'Increment', + child: const Icon(Icons.add), + ), + ); + } +} diff --git a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml new file mode 100644 index 000000000000..53c78da33f22 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml @@ -0,0 +1,24 @@ +name: shared_preferences_windows_example +description: Demonstrates how to use the shared_preferences_windows plugin. + +environment: + sdk: ">=2.7.0 <3.0.0" + +dependencies: + flutter: + sdk: flutter + + shared_preferences: + path: ../../shared_preferences + shared_preferences_windows: + path: ../ + +dev_dependencies: + flutter_driver: + sdk: flutter + test: any + e2e: ^0.2.0 + pedantic: ^1.8.0 + +flutter: + uses-material-design: true diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart new file mode 100644 index 000000000000..b693df2131ed --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart @@ -0,0 +1,89 @@ +import 'dart:async'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:e2e/e2e.dart'; + +void main() { + E2EWidgetsFlutterBinding.ensureInitialized(); + + group('$SharedPreferences', () { + const Map kTestValues = { + 'flutter.String': 'hello world', + 'flutter.bool': true, + 'flutter.int': 42, + 'flutter.double': 3.14159, + 'flutter.List': ['foo', 'bar'], + }; + + const Map kTestValues2 = { + 'flutter.String': 'goodbye world', + 'flutter.bool': false, + 'flutter.int': 1337, + 'flutter.double': 2.71828, + 'flutter.List': ['baz', 'quox'], + }; + + SharedPreferences preferences; + + setUp(() async { + preferences = await SharedPreferences.getInstance(); + }); + + tearDown(() { + preferences.clear(); + }); + + test('reading', () async { + expect(preferences.get('String'), isNull); + expect(preferences.get('bool'), isNull); + expect(preferences.get('int'), isNull); + expect(preferences.get('double'), isNull); + expect(preferences.get('List'), isNull); + expect(preferences.getString('String'), isNull); + expect(preferences.getBool('bool'), isNull); + expect(preferences.getInt('int'), isNull); + expect(preferences.getDouble('double'), isNull); + expect(preferences.getStringList('List'), isNull); + }); + + test('writing', () async { + await Future.wait(>[ + preferences.setString('String', kTestValues2['flutter.String']), + preferences.setBool('bool', kTestValues2['flutter.bool']), + preferences.setInt('int', kTestValues2['flutter.int']), + preferences.setDouble('double', kTestValues2['flutter.double']), + preferences.setStringList('List', kTestValues2['flutter.List']) + ]); + expect(preferences.getString('String'), kTestValues2['flutter.String']); + expect(preferences.getBool('bool'), kTestValues2['flutter.bool']); + expect(preferences.getInt('int'), kTestValues2['flutter.int']); + expect(preferences.getDouble('double'), kTestValues2['flutter.double']); + expect(preferences.getStringList('List'), kTestValues2['flutter.List']); + }); + + test('removing', () async { + const String key = 'testKey'; + await preferences.setString(key, kTestValues['flutter.String']); + await preferences.setBool(key, kTestValues['flutter.bool']); + await preferences.setInt(key, kTestValues['flutter.int']); + await preferences.setDouble(key, kTestValues['flutter.double']); + await preferences.setStringList(key, kTestValues['flutter.List']); + await preferences.remove(key); + expect(preferences.get('testKey'), isNull); + }); + + test('clearing', () async { + await preferences.setString('String', kTestValues['flutter.String']); + await preferences.setBool('bool', kTestValues['flutter.bool']); + await preferences.setInt('int', kTestValues['flutter.int']); + await preferences.setDouble('double', kTestValues['flutter.double']); + await preferences.setStringList('List', kTestValues['flutter.List']); + await preferences.clear(); + expect(preferences.getString('String'), null); + expect(preferences.getBool('bool'), null); + expect(preferences.getInt('int'), null); + expect(preferences.getDouble('double'), null); + expect(preferences.getStringList('List'), null); + }); + }); +} diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e_test.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e_test.dart new file mode 100644 index 000000000000..f3aa9e218d82 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e_test.dart @@ -0,0 +1,15 @@ +// Copyright 2019, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; +import 'dart:io'; +import 'package:flutter_driver/flutter_driver.dart'; + +Future main() async { + final FlutterDriver driver = await FlutterDriver.connect(); + final String result = + await driver.requestData(null, timeout: const Duration(minutes: 1)); + await driver.close(); + exit(result == 'pass' ? 0 : 1); +} diff --git a/packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec b/packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec new file mode 100644 index 000000000000..695f8c888c86 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec @@ -0,0 +1,20 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'shared_preferences_windows' + s.version = '0.0.1' + s.summary = 'No-op implementation of shared_preferences Windows plugin to avoid build issues on iOS' + s.description = <<-DESC +temp fake shared_preferences_windows plugin + DESC + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows' + s.license = { :file => '../LICENSE' } + s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + + s.ios.deployment_target = '8.0' +end diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart new file mode 100644 index 000000000000..424422e84c6a --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -0,0 +1,119 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert' show json; +import 'package:file/file.dart'; +import 'package:file/local.dart'; +import 'package:meta/meta.dart'; +import 'package:path/path.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; + +import 'src/win32.dart' as win32; + +/// Wrapper to the win32 ffi functions for testing. +class Win32Wrapper { + /// Calls the win32 function for [getLocalDataPath]. + String getLocalDataPath() { + return win32.getLocalDataPath(); + } + + /// Calls the win32 function for [getModuleFileName]. + String getModuleFileName() { + return win32.getModuleFileName(); + } +} + +/// The Windows implementation of [SharedPreferencesStorePlatform]. +/// +/// This class implements the `package:shared_preferences` functionality for the web. +class SharedPreferencesWindows extends SharedPreferencesStorePlatform { + /// The name of the parent directory for [fileName]. + final String fileDirectory = 'Flutter'; + + /// File system used to store to disk. Exposed for testing only. + @visibleForTesting + FileSystem fs = LocalFileSystem(); + + /// Wrapper for win32 ffi calls. + @visibleForTesting + Win32Wrapper win32Wrapper = Win32Wrapper(); + + String _localDataFilePath; + /// The path to the file in disk were the preferences are stored. + @visibleForTesting + String get getLocalDataFilePath { + if (_localDataFilePath != null) { + return _localDataFilePath; + } + _localDataFilePath = win32Wrapper.getLocalDataPath(); + String appName = _getAppName(); + // Append app-specific identifiers. + _localDataFilePath += '\\$fileDirectory\\$appName.ini'; + return _localDataFilePath; + } + + Map _cachedPreferences; + /// The in-memory representation of the map saved to a file in disk; + @visibleForTesting + Map get getCachedPreferences { + if (_cachedPreferences == null) { + File localDataFile = fs.file(getLocalDataFilePath); + if (!localDataFile.existsSync()) { + localDataFile.createSync(recursive: true); + } + String stringMap = localDataFile.readAsStringSync(); + _cachedPreferences = stringMap.isEmpty + ? {} + : json.decode(stringMap) as Map; + } + return _cachedPreferences; + } + + String _getAppName() { + String appPath = win32Wrapper.getModuleFileName(); + appPath = appPath.replaceAll(extension(appPath), ''); + return basename(appPath); + } + + /// Writes the cached preferences to disk. Returns [true] if the operation + /// succeeded. + bool _writePreferencesToFile() { + try { + File localDataFile = fs.file(getLocalDataFilePath); + if (!localDataFile.existsSync()) { + localDataFile.createSync(recursive: true); + } + String stringMap = json.encode(getCachedPreferences); + localDataFile.writeAsStringSync(stringMap); + } catch (e) { + print("Error saving preferences to disk: $e"); + return false; + } + return true; + } + + @override + Future clear() async { + getCachedPreferences.clear(); + return _writePreferencesToFile(); + } + + @override + Future> getAll() async { + return getCachedPreferences; + } + + @override + Future remove(String key) async { + getCachedPreferences.remove(key); + return _writePreferencesToFile(); + } + + @override + Future setValue(String valueType, String key, Object value) async { + getCachedPreferences[key] = value; + return _writePreferencesToFile(); + } +} diff --git a/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart b/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart new file mode 100644 index 000000000000..2fc46e1a831b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart @@ -0,0 +1,86 @@ +// Copyright 2020 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:ffi'; +import 'dart:typed_data'; +import 'package:ffi/ffi.dart'; + +// Constants: + +/// Typedef for kNull values. +const kNull = 0; + +/// Typedef for MAX_VALUE. +const kMaxPath = 260; + +// Function definitions: + +// Definition for SHGetFolderPathW. Retrieves a folder path given a CSIDL. +// +// SHFOLDERAPI SHGetFolderPathW( +// HWND hwnd, +// int csidl, +// HANDLE hToken, +// DWORD dwFlags, +// LPWSTR pszPath +// ); +typedef shGetFolderPathNative = Int32 Function(Int64 hwnd, Int32 csidl, + Int64 hToken, Int32 dwFlags, Pointer pszPath); +typedef shGetFolderPathDart = int Function( + int hwnd, int csidl, int hToken, int dwFlags, Pointer pszPath); + +// Definition for GetModuleFileNameW. Retrieves the path to the current process. +// +// DWORD GetModuleFileNameW( +// HMODULE hModule, +// LPWSTR lpFilename, +// DWORD nSize +// ); +typedef GetModuleFileNameC = Int32 Function( + Int32 hModule, + Pointer fileName, + Int16 nSize, +); +typedef GetModuleFileNameDart = int Function( + int hModule, + Pointer fileName, + int nSize, +); + +/// Reference to the Shell32 dynamic library. +final shell32 = DynamicLibrary.open('shell32.dll'); + +/// Reference to the Kernel32 dynamic library. +final kernel32 = DynamicLibrary.open('kernel32.dll'); + +/// Dart invocation of the win32 SHGetFolderPathW function. +final shGetFolderPath = + shell32.lookupFunction( + 'SHGetFolderPathW'); + +/// Dart invocation of the win32 GetModuleFileNameW function. +final getModuleFileNameW = + kernel32.lookupFunction( + 'GetModuleFileNameW'); + +/// Convenience method to get the AppData Local folder path. +String getLocalDataPath() { + final CSIDL_LOCAL_APPDATA = 0x001c; + final CSIDL_FLAG_CREATE = 0x8000; + Pointer path = allocate(count: kMaxPath); + shGetFolderPath( + kNull, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, kNull, 0, path); + + Uint16List pathData = path.asTypedList(kMaxPath); + return String.fromCharCodes( + path.asTypedList(kMaxPath), 0, pathData.indexOf(0)); +} + +/// Convenience method to retrieve the path of the current process. +String getModuleFileName() { + Pointer rs = allocate(count: kMaxPath); + getModuleFileNameW(kNull, rs, kMaxPath); + Uint16List pathData = rs.asTypedList(kMaxPath); + return String.fromCharCodes(rs.asTypedList(kMaxPath), 0, pathData.indexOf(0)); +} diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml new file mode 100644 index 000000000000..f4c63d7ee1b3 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -0,0 +1,27 @@ +name: shared_preferences_windows +description: Web platform implementation of shared_preferences +homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows +version: 0.0.1 + +flutter: + plugin: + platforms: + windows: + dartPluginClass: SharedPreferencesWindows + +dependencies: + shared_preferences_platform_interface: ^1.0.0 + flutter: + sdk: flutter + meta: ^1.1.7 + ffi: ^0.1.3 + file: 5.1.0 + +dev_dependencies: + flutter_test: + sdk: flutter + pedantic: ^1.8.0 + +environment: + sdk: ">=2.0.0-dev.28.0 <3.0.0" + flutter: ">=1.12.13+hotfix.4 <2.0.0" diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart new file mode 100644 index 000000000000..1cb35c7f579a --- /dev/null +++ b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart @@ -0,0 +1,86 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:file/memory.dart'; +import 'package:shared_preferences_windows/shared_preferences_windows.dart'; + +MemoryFileSystem fs = MemoryFileSystem.test(); + +void main() { + const String kTestKey = 'testKey'; + const String kTestValue = 'testValue'; + + SharedPreferencesWindows sharedPreferences; + + setUp(() { + sharedPreferences = SharedPreferencesWindows(); + sharedPreferences.win32Wrapper = MockWin32Wrapper(); + sharedPreferences.fs = fs; + }); + + tearDown(() { + fs.file(sharedPreferences.getLocalDataFilePath) + ..deleteSync(recursive: true); + }); + + /// Writes the test file to disk and loads the contents to the + /// sharedPreferences cache. + void _writeTestFile() { + fs.file(sharedPreferences.getLocalDataFilePath) + ..createSync(recursive: true) + ..writeAsStringSync(''' + { + "$kTestKey": "$kTestValue" + } + '''); + // Loads the file contents into the shared preferences store's cache. + sharedPreferences.getCachedPreferences; + } + + String _readTestFile() { + return fs.file(sharedPreferences.getLocalDataFilePath).readAsStringSync(); + } + + group('shared preferences', () { + test('getAll', () async { + _writeTestFile(); + + final Map allData = await sharedPreferences.getAll(); + expect(allData, hasLength(1)); + expect(allData[kTestKey], kTestValue); + }); + + test('remove', () async { + _writeTestFile(); + expect(sharedPreferences.getCachedPreferences[kTestKey], isNotNull); + expect(await sharedPreferences.remove(kTestKey), isTrue); + expect(sharedPreferences.getCachedPreferences.containsKey(kTestKey), + isFalse); + expect(_readTestFile(), '{}'); + }); + + test('setValue', () async { + _writeTestFile(); + const String kNewKey = 'NewKey'; + const String kNewValue = 'NewValue'; + expect(sharedPreferences.getCachedPreferences[kNewKey], isNull); + expect(await sharedPreferences.setValue('String', kNewKey, kNewValue), + isTrue); + expect(sharedPreferences.getCachedPreferences[kNewKey], isNotNull); + expect(_readTestFile(), + '{"$kTestKey":"$kTestValue","$kNewKey":"$kNewValue"}'); + }); + + test('clear', () async { + _writeTestFile(); + expect(await sharedPreferences.clear(), isTrue); + expect(sharedPreferences.getCachedPreferences.isEmpty, isTrue); + expect(_readTestFile(), '{}'); + }); + }); +} + +class MockWin32Wrapper extends Win32Wrapper { + @override + String getLocalDataPath() { + return fs.directory('\\test').path; + } +} From 230600c75c70634737d8466787dc7c3944307d8a Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Wed, 8 Apr 2020 18:34:52 -0700 Subject: [PATCH 02/20] Use path --- .../lib/shared_preferences_windows.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index 424422e84c6a..afcf56982b5e 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -7,7 +7,7 @@ import 'dart:convert' show json; import 'package:file/file.dart'; import 'package:file/local.dart'; import 'package:meta/meta.dart'; -import 'package:path/path.dart'; +import 'package:path/path.dart' as path; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'src/win32.dart' as win32; @@ -47,10 +47,10 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { if (_localDataFilePath != null) { return _localDataFilePath; } - _localDataFilePath = win32Wrapper.getLocalDataPath(); + String localDataPath = win32Wrapper.getLocalDataPath(); String appName = _getAppName(); // Append app-specific identifiers. - _localDataFilePath += '\\$fileDirectory\\$appName.ini'; + _localDataFilePath = path.join(localDataPath, fileDirectory, '$appName.json'); return _localDataFilePath; } @@ -73,8 +73,8 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { String _getAppName() { String appPath = win32Wrapper.getModuleFileName(); - appPath = appPath.replaceAll(extension(appPath), ''); - return basename(appPath); + appPath = appPath.replaceAll(path.extension(appPath), ''); + return path.basename(appPath); } /// Writes the cached preferences to disk. Returns [true] if the operation From 2f8e905190be8e7f04d9373de8f9f287d1a2cec8 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Wed, 8 Apr 2020 18:56:06 -0700 Subject: [PATCH 03/20] Update comments --- .../lib/shared_preferences_windows.dart | 11 +++-------- .../shared_preferences_windows/lib/src/win32.dart | 5 +++++ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index afcf56982b5e..97b75cf97f9b 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -27,7 +27,7 @@ class Win32Wrapper { /// The Windows implementation of [SharedPreferencesStorePlatform]. /// -/// This class implements the `package:shared_preferences` functionality for the web. +/// This class implements the `package:shared_preferences` functionality for Windowds. class SharedPreferencesWindows extends SharedPreferencesStorePlatform { /// The name of the parent directory for [fileName]. final String fileDirectory = 'Flutter'; @@ -47,8 +47,9 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { if (_localDataFilePath != null) { return _localDataFilePath; } + String appPath = win32Wrapper.getModuleFileName(); + String appName = path.basenameWithoutExtension(appPath); String localDataPath = win32Wrapper.getLocalDataPath(); - String appName = _getAppName(); // Append app-specific identifiers. _localDataFilePath = path.join(localDataPath, fileDirectory, '$appName.json'); return _localDataFilePath; @@ -71,12 +72,6 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { return _cachedPreferences; } - String _getAppName() { - String appPath = win32Wrapper.getModuleFileName(); - appPath = appPath.replaceAll(path.extension(appPath), ''); - return path.basename(appPath); - } - /// Writes the cached preferences to disk. Returns [true] if the operation /// succeeded. bool _writePreferencesToFile() { diff --git a/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart b/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart index 2fc46e1a831b..d4d0d65dc3ae 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart @@ -25,6 +25,11 @@ const kMaxPath = 260; // DWORD dwFlags, // LPWSTR pszPath // ); +// +// This is a deprecated API. It is being used in place of the recommended +// API SHGetKnownFolderPath, since it has been challenging to retrieve the REFKNOWNFOLDERID +// parameter with ffi calls. It is safe to use this API since (per Microsoft's documentation) +// as of Windows Vista, this function is merely a wrapper for SHGetKnownFolderPath. typedef shGetFolderPathNative = Int32 Function(Int64 hwnd, Int32 csidl, Int64 hToken, Int32 dwFlags, Pointer pszPath); typedef shGetFolderPathDart = int Function( From 1a99a1adcea5b5fc4c0e6fe23b5b0f9634615c8f Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Wed, 8 Apr 2020 19:19:02 -0700 Subject: [PATCH 04/20] Format --- .../lib/shared_preferences_windows.dart | 5 ++++- .../shared_preferences_windows/pubspec.yaml | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index 97b75cf97f9b..10a74cf81299 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -41,6 +41,7 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { Win32Wrapper win32Wrapper = Win32Wrapper(); String _localDataFilePath; + /// The path to the file in disk were the preferences are stored. @visibleForTesting String get getLocalDataFilePath { @@ -51,11 +52,13 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { String appName = path.basenameWithoutExtension(appPath); String localDataPath = win32Wrapper.getLocalDataPath(); // Append app-specific identifiers. - _localDataFilePath = path.join(localDataPath, fileDirectory, '$appName.json'); + _localDataFilePath = + path.join(localDataPath, fileDirectory, '$appName.json'); return _localDataFilePath; } Map _cachedPreferences; + /// The in-memory representation of the map saved to a file in disk; @visibleForTesting Map get getCachedPreferences { diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index f4c63d7ee1b3..8efee8f5f441 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -15,7 +15,7 @@ dependencies: sdk: flutter meta: ^1.1.7 ffi: ^0.1.3 - file: 5.1.0 + file: ^5.1.0 dev_dependencies: flutter_test: From 1eb343d62bd9769671b61d176f1f4a7ca0bde3ba Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Thu, 9 Apr 2020 10:52:36 -0700 Subject: [PATCH 05/20] Remove create --- .../lib/shared_preferences_windows.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index 10a74cf81299..b612ecf2f937 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -63,14 +63,15 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { @visibleForTesting Map get getCachedPreferences { if (_cachedPreferences == null) { + _cachedPreferences = {}; File localDataFile = fs.file(getLocalDataFilePath); if (!localDataFile.existsSync()) { - localDataFile.createSync(recursive: true); + String stringMap = localDataFile.readAsStringSync(); + if (stringMap.isNotEmpty) { + _cachedPreferences = json.decode(stringMap) as Map; + } + } - String stringMap = localDataFile.readAsStringSync(); - _cachedPreferences = stringMap.isEmpty - ? {} - : json.decode(stringMap) as Map; } return _cachedPreferences; } From 8f2881ce0c95895510ef7120c7aa6f1846965625 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Thu, 9 Apr 2020 10:55:22 -0700 Subject: [PATCH 06/20] fix --- .../lib/shared_preferences_windows.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index b612ecf2f937..18fcd8f05747 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -65,12 +65,11 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { if (_cachedPreferences == null) { _cachedPreferences = {}; File localDataFile = fs.file(getLocalDataFilePath); - if (!localDataFile.existsSync()) { + if (localDataFile.existsSync()) { String stringMap = localDataFile.readAsStringSync(); if (stringMap.isNotEmpty) { _cachedPreferences = json.decode(stringMap) as Map; } - } } return _cachedPreferences; From 946cc68e6a0ce97104370420b11716df9ccab0a1 Mon Sep 17 00:00:00 2001 From: Francisco Madgaleno Date: Thu, 9 Apr 2020 17:21:41 -0700 Subject: [PATCH 07/20] Address messages --- .../lib/shared_preferences.dart | 5 +- .../android/.gitignore | 8 --- .../android/build.gradle | 43 --------------- .../android/gradle.properties | 4 -- .../gradle/wrapper/gradle-wrapper.properties | 5 -- .../android/settings.gradle | 1 - .../android/src/main/AndroidManifest.xml | 3 -- .../SharedPreferencesWindowsPlugin.kt | 53 ------------------- .../example/LICENSE | 28 +++++++++- .../ios/shared_preferences_windows.podspec | 20 ------- 10 files changed, 31 insertions(+), 139 deletions(-) delete mode 100644 packages/shared_preferences/shared_preferences_windows/android/.gitignore delete mode 100644 packages/shared_preferences/shared_preferences_windows/android/build.gradle delete mode 100644 packages/shared_preferences/shared_preferences_windows/android/gradle.properties delete mode 100644 packages/shared_preferences/shared_preferences_windows/android/gradle/wrapper/gradle-wrapper.properties delete mode 100644 packages/shared_preferences/shared_preferences_windows/android/settings.gradle delete mode 100644 packages/shared_preferences/shared_preferences_windows/android/src/main/AndroidManifest.xml delete mode 100644 packages/shared_preferences/shared_preferences_windows/android/src/main/kotlin/com/example/shared_preferences_windows/SharedPreferencesWindowsPlugin.kt delete mode 100644 packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec diff --git a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart index aa601dcc80ab..2493aacee626 100644 --- a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart @@ -4,6 +4,7 @@ import 'dart:async'; +import 'package:flutter/foundation.dart'; import 'package:meta/meta.dart'; import 'package:platform/platform.dart'; @@ -21,7 +22,9 @@ class SharedPreferences { static Completer _completer; static SharedPreferencesStorePlatform get _store { - if (LocalPlatform().isWindows) { + // This is a workaround until https://github.com/flutter/flutter/issues/52267 + // is fixed. There is no way currently to register a Dart-only plugin. + if (!kIsWeb && LocalPlatform().isWindows) { return SharedPreferencesWindows(); } return SharedPreferencesStorePlatform.instance; diff --git a/packages/shared_preferences/shared_preferences_windows/android/.gitignore b/packages/shared_preferences/shared_preferences_windows/android/.gitignore deleted file mode 100644 index c6cbe562a427..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/android/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -*.iml -.gradle -/local.properties -/.idea/workspace.xml -/.idea/libraries -.DS_Store -/build -/captures diff --git a/packages/shared_preferences/shared_preferences_windows/android/build.gradle b/packages/shared_preferences/shared_preferences_windows/android/build.gradle deleted file mode 100644 index edbf36e5588b..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/android/build.gradle +++ /dev/null @@ -1,43 +0,0 @@ -group 'com.example.shared_preferences_windows' -version '1.0-SNAPSHOT' - -buildscript { - ext.kotlin_version = '1.3.50' - repositories { - google() - jcenter() - } - - dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" - } -} - -rootProject.allprojects { - repositories { - google() - jcenter() - } -} - -apply plugin: 'com.android.library' -apply plugin: 'kotlin-android' - -android { - compileSdkVersion 28 - - sourceSets { - main.java.srcDirs += 'src/main/kotlin' - } - defaultConfig { - minSdkVersion 16 - } - lintOptions { - disable 'InvalidPackage' - } -} - -dependencies { - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" -} diff --git a/packages/shared_preferences/shared_preferences_windows/android/gradle.properties b/packages/shared_preferences/shared_preferences_windows/android/gradle.properties deleted file mode 100644 index 38c8d4544ff1..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/android/gradle.properties +++ /dev/null @@ -1,4 +0,0 @@ -org.gradle.jvmargs=-Xmx1536M -android.enableR8=true -android.useAndroidX=true -android.enableJetifier=true diff --git a/packages/shared_preferences/shared_preferences_windows/android/gradle/wrapper/gradle-wrapper.properties b/packages/shared_preferences/shared_preferences_windows/android/gradle/wrapper/gradle-wrapper.properties deleted file mode 100644 index 01a286e96a21..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/android/gradle/wrapper/gradle-wrapper.properties +++ /dev/null @@ -1,5 +0,0 @@ -distributionBase=GRADLE_USER_HOME -distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME -zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip diff --git a/packages/shared_preferences/shared_preferences_windows/android/settings.gradle b/packages/shared_preferences/shared_preferences_windows/android/settings.gradle deleted file mode 100644 index 307c6c67684e..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/android/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'shared_preferences_windows' diff --git a/packages/shared_preferences/shared_preferences_windows/android/src/main/AndroidManifest.xml b/packages/shared_preferences/shared_preferences_windows/android/src/main/AndroidManifest.xml deleted file mode 100644 index e55611ff0c7e..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/android/src/main/AndroidManifest.xml +++ /dev/null @@ -1,3 +0,0 @@ - - diff --git a/packages/shared_preferences/shared_preferences_windows/android/src/main/kotlin/com/example/shared_preferences_windows/SharedPreferencesWindowsPlugin.kt b/packages/shared_preferences/shared_preferences_windows/android/src/main/kotlin/com/example/shared_preferences_windows/SharedPreferencesWindowsPlugin.kt deleted file mode 100644 index fa4c5b021542..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/android/src/main/kotlin/com/example/shared_preferences_windows/SharedPreferencesWindowsPlugin.kt +++ /dev/null @@ -1,53 +0,0 @@ -package com.example.shared_preferences_windows - -import androidx.annotation.NonNull; - -import io.flutter.embedding.engine.plugins.FlutterPlugin -import io.flutter.plugin.common.MethodCall -import io.flutter.plugin.common.MethodChannel -import io.flutter.plugin.common.MethodChannel.MethodCallHandler -import io.flutter.plugin.common.MethodChannel.Result -import io.flutter.plugin.common.PluginRegistry.Registrar - -/** SharedPreferencesWindowsPlugin */ -public class SharedPreferencesWindowsPlugin: FlutterPlugin, MethodCallHandler { - /// The MethodChannel that will the communication between Flutter and native Android - /// - /// This local reference serves to register the plugin with the Flutter Engine and unregister it - /// when the Flutter Engine is detached from the Activity - private lateinit var channel : MethodChannel - - override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { - channel = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "shared_preferences_windows") - channel.setMethodCallHandler(this); - } - - // This static function is optional and equivalent to onAttachedToEngine. It supports the old - // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting - // plugin registration via this function while apps migrate to use the new Android APIs - // post-flutter-1.12 via https://flutter.dev/go/android-project-migration. - // - // It is encouraged to share logic between onAttachedToEngine and registerWith to keep - // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called - // depending on the user's project. onAttachedToEngine or registerWith must both be defined - // in the same class. - companion object { - @JvmStatic - fun registerWith(registrar: Registrar) { - val channel = MethodChannel(registrar.messenger(), "shared_preferences_windows") - channel.setMethodCallHandler(SharedPreferencesWindowsPlugin()) - } - } - - override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { - if (call.method == "getPlatformVersion") { - result.success("Android ${android.os.Build.VERSION.RELEASE}") - } else { - result.notImplemented() - } - } - - override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { - channel.setMethodCallHandler(null) - } -} diff --git a/packages/shared_preferences/shared_preferences_windows/example/LICENSE b/packages/shared_preferences/shared_preferences_windows/example/LICENSE index ba75c69f7f21..c89293372cf3 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/LICENSE +++ b/packages/shared_preferences/shared_preferences_windows/example/LICENSE @@ -1 +1,27 @@ -TODO: Add your license here. +// Copyright 2017 The Chromium Authors. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec b/packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec deleted file mode 100644 index 695f8c888c86..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/ios/shared_preferences_windows.podspec +++ /dev/null @@ -1,20 +0,0 @@ -# -# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html -# -Pod::Spec.new do |s| - s.name = 'shared_preferences_windows' - s.version = '0.0.1' - s.summary = 'No-op implementation of shared_preferences Windows plugin to avoid build issues on iOS' - s.description = <<-DESC -temp fake shared_preferences_windows plugin - DESC - s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows' - s.license = { :file => '../LICENSE' } - s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } - s.source = { :path => '.' } - s.source_files = 'Classes/**/*' - s.public_header_files = 'Classes/**/*.h' - s.dependency 'Flutter' - - s.ios.deployment_target = '8.0' -end From 4ae292668479de7bf8122fb60bd5a0fa37840909 Mon Sep 17 00:00:00 2001 From: Francisco Magdaleno Date: Wed, 15 Apr 2020 14:09:52 -0700 Subject: [PATCH 08/20] License --- .../example/test_driver/shared_preferences_e2e_test.dart | 2 +- .../example/test_driver/shared_preferences_e2e_test.dart | 2 +- packages/shared_preferences/shared_preferences_web/LICENSE | 2 +- .../shared_preferences/shared_preferences_windows/LICENSE | 2 +- .../example/test_driver/shared_preferences_e2e.dart | 4 ++++ .../example/test_driver/shared_preferences_e2e_test.dart | 2 +- .../test/shared_preferences_windows_test.dart | 4 ++++ 7 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart b/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart index f3aa9e218d82..102dfdfef708 100644 --- a/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart +++ b/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. Please see the AUTHORS file +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart b/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart index f3aa9e218d82..102dfdfef708 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. Please see the AUTHORS file +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/shared_preferences/shared_preferences_web/LICENSE b/packages/shared_preferences/shared_preferences_web/LICENSE index 0c382ce171cc..c89293372cf3 100644 --- a/packages/shared_preferences/shared_preferences_web/LICENSE +++ b/packages/shared_preferences/shared_preferences_web/LICENSE @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are diff --git a/packages/shared_preferences/shared_preferences_windows/LICENSE b/packages/shared_preferences/shared_preferences_windows/LICENSE index 0c382ce171cc..c89293372cf3 100644 --- a/packages/shared_preferences/shared_preferences_windows/LICENSE +++ b/packages/shared_preferences/shared_preferences_windows/LICENSE @@ -1,4 +1,4 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. +// Copyright 2017 The Chromium Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart index b693df2131ed..a4c5f5f9f3f1 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart @@ -1,3 +1,7 @@ +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e_test.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e_test.dart index f3aa9e218d82..102dfdfef708 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e_test.dart @@ -1,4 +1,4 @@ -// Copyright 2019, the Chromium project authors. Please see the AUTHORS file +// Copyright 2017, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart index 1cb35c7f579a..b09bac55de71 100644 --- a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart @@ -1,3 +1,7 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + import 'package:flutter_test/flutter_test.dart'; import 'package:file/memory.dart'; import 'package:shared_preferences_windows/shared_preferences_windows.dart'; From 1da556942e7416a765be5dc1b54e44b59de77697 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2020 08:48:07 -0700 Subject: [PATCH 09/20] Minor fixes/updates --- .../lib/shared_preferences_windows.dart | 2 +- .../shared_preferences_windows/pubspec.yaml | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index 18fcd8f05747..57d42553ec68 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -27,7 +27,7 @@ class Win32Wrapper { /// The Windows implementation of [SharedPreferencesStorePlatform]. /// -/// This class implements the `package:shared_preferences` functionality for Windowds. +/// This class implements the `package:shared_preferences` functionality for Windows. class SharedPreferencesWindows extends SharedPreferencesStorePlatform { /// The name of the parent directory for [fileName]. final String fileDirectory = 'Flutter'; diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index 8efee8f5f441..cc0e94de1bf4 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -1,5 +1,5 @@ name: shared_preferences_windows -description: Web platform implementation of shared_preferences +description: Windows implementation of shared_preferences homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_windows version: 0.0.1 @@ -8,12 +8,18 @@ flutter: platforms: windows: dartPluginClass: SharedPreferencesWindows + pluginClass: none + +environment: + sdk: ">=2.1.0 <3.0.0" + flutter: ">=1.12.8 <2.0.0" dependencies: shared_preferences_platform_interface: ^1.0.0 flutter: sdk: flutter meta: ^1.1.7 + path: ^1.6.4 ffi: ^0.1.3 file: ^5.1.0 @@ -21,7 +27,3 @@ dev_dependencies: flutter_test: sdk: flutter pedantic: ^1.8.0 - -environment: - sdk: ">=2.0.0-dev.28.0 <3.0.0" - flutter: ">=1.12.13+hotfix.4 <2.0.0" From de8ff2ec0bdc43a6987fbc04d29322b7a71cd0c1 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2020 08:57:23 -0700 Subject: [PATCH 10/20] Revert everything outside of shared_preferences_windows --- .../shared_preferences/CHANGELOG.md | 4 ---- .../test_driver/shared_preferences_e2e_test.dart | 2 +- .../shared_preferences/lib/shared_preferences.dart | 13 ++++--------- .../shared_preferences/pubspec.yaml | 5 +---- .../test_driver/shared_preferences_e2e_test.dart | 2 +- .../shared_preferences_web/LICENSE | 2 +- 6 files changed, 8 insertions(+), 20 deletions(-) diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index a890441c0452..3f4edca10dc2 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,7 +1,3 @@ -## 0.5.11 - -* Adds support for Windows. - ## 0.5.10 * Update package:e2e -> package:integration_test diff --git a/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart b/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart index 97c34f5452f5..7a2c21338786 100644 --- a/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart +++ b/packages/shared_preferences/shared_preferences/example/test_driver/shared_preferences_e2e_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// Copyright 2019, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart index 034a647e8deb..b8d3452a0a0e 100644 --- a/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart +++ b/packages/shared_preferences/shared_preferences/lib/shared_preferences.dart @@ -7,12 +7,10 @@ import 'dart:io' show Platform; import 'package:flutter/foundation.dart' show kIsWeb; import 'package:meta/meta.dart'; -import 'package:platform/platform.dart'; import 'package:shared_preferences_linux/shared_preferences_linux.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/method_channel_shared_preferences.dart'; -import 'package:shared_preferences_windows/shared_preferences_windows.dart'; /// Wraps NSUserDefaults (on iOS) and SharedPreferences (on Android), providing /// a persistent store for simple data. @@ -26,20 +24,17 @@ class SharedPreferences { static bool _manualDartRegistrationNeeded = true; static SharedPreferencesStorePlatform get _store { - // This is to manually endorse the Linux and Windows implementations until - // automatic registration of dart plugins is implemented. For details see + // This is to manually endorse the Linux implementation until automatic + // registration of dart plugins is implemented. For details see // https://github.com/flutter/flutter/issues/52267. if (_manualDartRegistrationNeeded) { // Only do the initial registration if it hasn't already been overridden // with a non-default instance. if (!kIsWeb && + Platform.isLinux && SharedPreferencesStorePlatform.instance is MethodChannelSharedPreferencesStore) { - if (Platform.isLinux) { - SharedPreferencesStorePlatform.instance = SharedPreferencesLinux(); - } else if (Platform.isWindows) { - SharedPreferencesStorePlatform.instance = SharedPreferencesWindows(); - } + SharedPreferencesStorePlatform.instance = SharedPreferencesLinux(); } _manualDartRegistrationNeeded = false; } diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 03c99ff2f107..04b7813a2a99 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -5,7 +5,7 @@ homepage: https://github.com/flutter/plugins/tree/master/packages/shared_prefere # 0.5.y+z is compatible with 1.0.0, if you land a breaking change bump # the version to 2.0.0. # See more details: https://github.com/flutter/flutter/wiki/Package-migration-to-1.0.0 -version: 0.5.11 +version: 0.5.10 flutter: plugin: @@ -26,7 +26,6 @@ dependencies: meta: ^1.0.4 flutter: sdk: flutter - platform: 2.2.1 shared_preferences_platform_interface: ^1.0.0 # The design on https://flutter.dev/go/federated-plugins was to leave # this constraint as "any". We cannot do it right now as it fails pub publish @@ -36,8 +35,6 @@ dependencies: shared_preferences_linux: ^0.0.2 shared_preferences_macos: ^0.0.1 shared_preferences_web: ^0.1.2 - shared_preferences_windows: - path: ../shared_preferences_windows dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart b/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart index 97c34f5452f5..7a2c21338786 100644 --- a/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart +++ b/packages/shared_preferences/shared_preferences_macos/example/test_driver/shared_preferences_e2e_test.dart @@ -1,4 +1,4 @@ -// Copyright 2017, the Chromium project authors. Please see the AUTHORS file +// Copyright 2019, the Chromium project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. diff --git a/packages/shared_preferences/shared_preferences_web/LICENSE b/packages/shared_preferences/shared_preferences_web/LICENSE index c89293372cf3..0c382ce171cc 100644 --- a/packages/shared_preferences/shared_preferences_web/LICENSE +++ b/packages/shared_preferences/shared_preferences_web/LICENSE @@ -1,4 +1,4 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2019 The Chromium Authors. All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are From 8c82dc311db9cfa64693a90d1de011c51cf49794 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Tue, 1 Sep 2020 09:09:33 -0700 Subject: [PATCH 11/20] Make the example self-contained, following the model of Linux --- .../example/lib/main.dart | 14 +++++++------- .../example/pubspec.yaml | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart index 46daeff6706f..140851c90504 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/lib/main.dart @@ -7,7 +7,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:shared_preferences_windows/shared_preferences_windows.dart'; void main() { runApp(MyApp()); @@ -31,15 +31,15 @@ class SharedPreferencesDemo extends StatefulWidget { } class SharedPreferencesDemoState extends State { - Future _prefs = SharedPreferences.getInstance(); + final prefs = SharedPreferencesWindows.instance; Future _counter; Future _incrementCounter() async { - final SharedPreferences prefs = await _prefs; - final int counter = (prefs.getInt('counter') ?? 0) + 1; + final values = await prefs.getAll(); + final int counter = (values['counter'] as int ?? 0) + 1; setState(() { - _counter = prefs.setInt("counter", counter).then((bool success) { + _counter = prefs.setValue(null, "counter", counter).then((bool success) { return counter; }); }); @@ -48,8 +48,8 @@ class SharedPreferencesDemoState extends State { @override void initState() { super.initState(); - _counter = _prefs.then((SharedPreferences prefs) { - return (prefs.getInt('counter') ?? 0); + _counter = prefs.getAll().then((Map values) { + return (values['counter'] ?? 0); }); } diff --git a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml index 53c78da33f22..6dd7841ea477 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/example/pubspec.yaml @@ -7,9 +7,9 @@ environment: dependencies: flutter: sdk: flutter + shared_preferences_windows: ^0.0.1 - shared_preferences: - path: ../../shared_preferences +dependency_overrides: shared_preferences_windows: path: ../ From 351244a2aedd99ab6d65298ccaa74752aa72f548 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 2 Sep 2020 07:01:42 -0700 Subject: [PATCH 12/20] Update file dependency to resolve analyzer issue --- .../shared_preferences_windows/pubspec.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index cc0e94de1bf4..dfc4e06a40e8 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -18,10 +18,10 @@ dependencies: shared_preferences_platform_interface: ^1.0.0 flutter: sdk: flutter + ffi: ^0.1.3 + file: ">=5.1.0 <7.0.0" meta: ^1.1.7 path: ^1.6.4 - ffi: ^0.1.3 - file: ^5.1.0 dev_dependencies: flutter_test: From 48f0cfbf1ac664bb49970bba585fc279942604a1 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 2 Sep 2020 07:41:26 -0700 Subject: [PATCH 13/20] Fix example test to be self-contained as well, rather than a copy of the main plugin's tests --- .../test_driver/shared_preferences_e2e.dart | 79 +++++++++---------- .../lib/shared_preferences_windows.dart | 3 + 2 files changed, 42 insertions(+), 40 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart index a4c5f5f9f3f1..78b7c8542dc3 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart @@ -4,13 +4,13 @@ import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; -import 'package:shared_preferences/shared_preferences.dart'; +import 'package:shared_preferences_windows/shared_preferences_windows.dart'; import 'package:e2e/e2e.dart'; void main() { E2EWidgetsFlutterBinding.ensureInitialized(); - group('$SharedPreferences', () { + group('SharedPreferencesWindows', () { const Map kTestValues = { 'flutter.String': 'hello world', 'flutter.bool': true, @@ -27,10 +27,10 @@ void main() { 'flutter.List': ['baz', 'quox'], }; - SharedPreferences preferences; + SharedPreferencesWindows preferences; setUp(() async { - preferences = await SharedPreferences.getInstance(); + preferences = SharedPreferencesWindows.instance; }); tearDown(() { @@ -38,56 +38,55 @@ void main() { }); test('reading', () async { - expect(preferences.get('String'), isNull); - expect(preferences.get('bool'), isNull); - expect(preferences.get('int'), isNull); - expect(preferences.get('double'), isNull); - expect(preferences.get('List'), isNull); - expect(preferences.getString('String'), isNull); - expect(preferences.getBool('bool'), isNull); - expect(preferences.getInt('int'), isNull); - expect(preferences.getDouble('double'), isNull); - expect(preferences.getStringList('List'), isNull); + final Map values = await preferences.getAll(); + expect(values['String'], isNull); + expect(values['bool'], isNull); + expect(values['int'], isNull); + expect(values['double'], isNull); + expect(values['List'], isNull); }); test('writing', () async { await Future.wait(>[ - preferences.setString('String', kTestValues2['flutter.String']), - preferences.setBool('bool', kTestValues2['flutter.bool']), - preferences.setInt('int', kTestValues2['flutter.int']), - preferences.setDouble('double', kTestValues2['flutter.double']), - preferences.setStringList('List', kTestValues2['flutter.List']) + preferences.setValue('String', 'String', kTestValues2['flutter.String']), + preferences.setValue('Bool', 'bool', kTestValues2['flutter.bool']), + preferences.setValue('Int', 'int', kTestValues2['flutter.int']), + preferences.setValue('Double', 'double', kTestValues2['flutter.double']), + preferences.setValue('StringList', 'List', kTestValues2['flutter.List']) ]); - expect(preferences.getString('String'), kTestValues2['flutter.String']); - expect(preferences.getBool('bool'), kTestValues2['flutter.bool']); - expect(preferences.getInt('int'), kTestValues2['flutter.int']); - expect(preferences.getDouble('double'), kTestValues2['flutter.double']); - expect(preferences.getStringList('List'), kTestValues2['flutter.List']); + final Map values = await preferences.getAll(); + expect(values['String'], kTestValues2['flutter.String']); + expect(values['bool'], kTestValues2['flutter.bool']); + expect(values['int'], kTestValues2['flutter.int']); + expect(values['double'], kTestValues2['flutter.double']); + expect(values['List'], kTestValues2['flutter.List']); }); test('removing', () async { const String key = 'testKey'; - await preferences.setString(key, kTestValues['flutter.String']); - await preferences.setBool(key, kTestValues['flutter.bool']); - await preferences.setInt(key, kTestValues['flutter.int']); - await preferences.setDouble(key, kTestValues['flutter.double']); - await preferences.setStringList(key, kTestValues['flutter.List']); + await preferences.setValue('String', key, kTestValues['flutter.String']); + await preferences.setValue('Bool', key, kTestValues['flutter.bool']); + await preferences.setValue('Int', key, kTestValues['flutter.int']); + await preferences.setValue('Double', key, kTestValues['flutter.double']); + await preferences.setValue('StringList', key, kTestValues['flutter.List']); await preferences.remove(key); - expect(preferences.get('testKey'), isNull); + final Map values = await preferences.getAll(); + expect(values[key], isNull); }); test('clearing', () async { - await preferences.setString('String', kTestValues['flutter.String']); - await preferences.setBool('bool', kTestValues['flutter.bool']); - await preferences.setInt('int', kTestValues['flutter.int']); - await preferences.setDouble('double', kTestValues['flutter.double']); - await preferences.setStringList('List', kTestValues['flutter.List']); + await preferences.setValue('String', 'String', kTestValues['flutter.String']); + await preferences.setValue('Bool', 'bool', kTestValues['flutter.bool']); + await preferences.setValue('Int', 'int', kTestValues['flutter.int']); + await preferences.setValue('Double', 'double', kTestValues['flutter.double']); + await preferences.setValue('StringList', 'List', kTestValues['flutter.List']); await preferences.clear(); - expect(preferences.getString('String'), null); - expect(preferences.getBool('bool'), null); - expect(preferences.getInt('int'), null); - expect(preferences.getDouble('double'), null); - expect(preferences.getStringList('List'), null); + final Map values = await preferences.getAll(); + expect(values['String'], null); + expect(values['bool'], null); + expect(values['int'], null); + expect(values['double'], null); + expect(values['List'], null); }); }); } diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index 57d42553ec68..071da4c1e624 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -29,6 +29,9 @@ class Win32Wrapper { /// /// This class implements the `package:shared_preferences` functionality for Windows. class SharedPreferencesWindows extends SharedPreferencesStorePlatform { + /// The default instance of [SharedPreferencesWindows] to use. + static SharedPreferencesWindows instance = SharedPreferencesWindows(); + /// The name of the parent directory for [fileName]. final String fileDirectory = 'Flutter'; From dc7dbd3a92d09f071b45706789242983ecb5ca8c Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 2 Sep 2020 07:55:22 -0700 Subject: [PATCH 14/20] Format --- .../test_driver/shared_preferences_e2e.dart | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart index 78b7c8542dc3..44c8129e9405 100644 --- a/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart +++ b/packages/shared_preferences/shared_preferences_windows/example/test_driver/shared_preferences_e2e.dart @@ -48,10 +48,12 @@ void main() { test('writing', () async { await Future.wait(>[ - preferences.setValue('String', 'String', kTestValues2['flutter.String']), + preferences.setValue( + 'String', 'String', kTestValues2['flutter.String']), preferences.setValue('Bool', 'bool', kTestValues2['flutter.bool']), preferences.setValue('Int', 'int', kTestValues2['flutter.int']), - preferences.setValue('Double', 'double', kTestValues2['flutter.double']), + preferences.setValue( + 'Double', 'double', kTestValues2['flutter.double']), preferences.setValue('StringList', 'List', kTestValues2['flutter.List']) ]); final Map values = await preferences.getAll(); @@ -68,18 +70,22 @@ void main() { await preferences.setValue('Bool', key, kTestValues['flutter.bool']); await preferences.setValue('Int', key, kTestValues['flutter.int']); await preferences.setValue('Double', key, kTestValues['flutter.double']); - await preferences.setValue('StringList', key, kTestValues['flutter.List']); + await preferences.setValue( + 'StringList', key, kTestValues['flutter.List']); await preferences.remove(key); final Map values = await preferences.getAll(); expect(values[key], isNull); }); test('clearing', () async { - await preferences.setValue('String', 'String', kTestValues['flutter.String']); + await preferences.setValue( + 'String', 'String', kTestValues['flutter.String']); await preferences.setValue('Bool', 'bool', kTestValues['flutter.bool']); await preferences.setValue('Int', 'int', kTestValues['flutter.int']); - await preferences.setValue('Double', 'double', kTestValues['flutter.double']); - await preferences.setValue('StringList', 'List', kTestValues['flutter.List']); + await preferences.setValue( + 'Double', 'double', kTestValues['flutter.double']); + await preferences.setValue( + 'StringList', 'List', kTestValues['flutter.List']); await preferences.clear(); final Map values = await preferences.getAll(); expect(values['String'], null); From 416694a8e129ff44610170d6f6e25c0e587e9ea7 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 2 Sep 2020 08:11:46 -0700 Subject: [PATCH 15/20] Fix tests on non-Windows platforms --- .../test/shared_preferences_windows_test.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart index b09bac55de71..2b7250f1eaca 100644 --- a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart @@ -85,6 +85,11 @@ void main() { class MockWin32Wrapper extends Win32Wrapper { @override String getLocalDataPath() { - return fs.directory('\\test').path; + return fs.directory('\\data').path; + } + + @override + String getModuleFileName() { + return 'test'; } } From 5f3b240172745a3d871b3930e753f4f75e6d3baa Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 2 Sep 2020 08:12:12 -0700 Subject: [PATCH 16/20] Add a note not to land this version; the storage path doesn't match path_provider_windows --- .../lib/shared_preferences_windows.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index 071da4c1e624..db27e64017e2 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -55,6 +55,10 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { String appName = path.basenameWithoutExtension(appPath); String localDataPath = win32Wrapper.getLocalDataPath(); // Append app-specific identifiers. + // #################### + // # DO NOT LAND! path_provider should be landed and published first, and + // # this plugin should use path_provider_windows, as with Linux. + // #################### _localDataFilePath = path.join(localDataPath, fileDirectory, '$appName.json'); return _localDataFilePath; From af2c1adbcd450dab7367699bfa23934b272cbcb3 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 4 Sep 2020 16:42:36 -0700 Subject: [PATCH 17/20] Rework on top of path_provider_windows; initial verison --- .../lib/shared_preferences_windows.dart | 86 ++++------ .../lib/src/win32.dart | 91 ----------- .../shared_preferences_windows/pubspec.yaml | 5 + .../test/shared_preferences_windows_test.dart | 154 ++++++++++-------- 4 files changed, 122 insertions(+), 214 deletions(-) delete mode 100644 packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index db27e64017e2..ec9bb0124b9c 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -9,21 +9,7 @@ import 'package:file/local.dart'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as path; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; - -import 'src/win32.dart' as win32; - -/// Wrapper to the win32 ffi functions for testing. -class Win32Wrapper { - /// Calls the win32 function for [getLocalDataPath]. - String getLocalDataPath() { - return win32.getLocalDataPath(); - } - - /// Calls the win32 function for [getModuleFileName]. - String getModuleFileName() { - return win32.getModuleFileName(); - } -} +import 'package:path_provider_windows/path_provider_windows.dart'; /// The Windows implementation of [SharedPreferencesStorePlatform]. /// @@ -32,46 +18,39 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { /// The default instance of [SharedPreferencesWindows] to use. static SharedPreferencesWindows instance = SharedPreferencesWindows(); - /// The name of the parent directory for [fileName]. - final String fileDirectory = 'Flutter'; - /// File system used to store to disk. Exposed for testing only. @visibleForTesting FileSystem fs = LocalFileSystem(); - /// Wrapper for win32 ffi calls. + /// The path_provider_windows instance used to find the support directory. + /// + /// DO NOT LAND: See what the testing solution is for path_provider to see if + /// exposing this is actually necessary. @visibleForTesting - Win32Wrapper win32Wrapper = Win32Wrapper(); + PathProviderWindows pathProvider = PathProviderWindows(); - String _localDataFilePath; + /// Local copy of preferences + Map _cachedPreferences; - /// The path to the file in disk were the preferences are stored. - @visibleForTesting - String get getLocalDataFilePath { - if (_localDataFilePath != null) { - return _localDataFilePath; + /// Cached file for storing preferences. + File _localDataFilePath; + + /// Gets the file where the preferences are stored. + Future _getLocalDataFile() async { + if (_localDataFilePath == null) { + final directory = await pathProvider.getApplicationSupportPath(); + _localDataFilePath = + fs.file(path.join(directory, 'shared_preferences.json')); } - String appPath = win32Wrapper.getModuleFileName(); - String appName = path.basenameWithoutExtension(appPath); - String localDataPath = win32Wrapper.getLocalDataPath(); - // Append app-specific identifiers. - // #################### - // # DO NOT LAND! path_provider should be landed and published first, and - // # this plugin should use path_provider_windows, as with Linux. - // #################### - _localDataFilePath = - path.join(localDataPath, fileDirectory, '$appName.json'); return _localDataFilePath; } - Map _cachedPreferences; - - /// The in-memory representation of the map saved to a file in disk; - @visibleForTesting - Map get getCachedPreferences { + /// Gets the preferences from the stored file. Once read, the preferences are + /// maintained in memory. + Future> _readPreferences() async { if (_cachedPreferences == null) { _cachedPreferences = {}; - File localDataFile = fs.file(getLocalDataFilePath); + File localDataFile = await _getLocalDataFile(); if (localDataFile.existsSync()) { String stringMap = localDataFile.readAsStringSync(); if (stringMap.isNotEmpty) { @@ -84,13 +63,13 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { /// Writes the cached preferences to disk. Returns [true] if the operation /// succeeded. - bool _writePreferencesToFile() { + Future _writePreferences(Map preferences) async { try { - File localDataFile = fs.file(getLocalDataFilePath); + File localDataFile = await _getLocalDataFile(); if (!localDataFile.existsSync()) { localDataFile.createSync(recursive: true); } - String stringMap = json.encode(getCachedPreferences); + String stringMap = json.encode(preferences); localDataFile.writeAsStringSync(stringMap); } catch (e) { print("Error saving preferences to disk: $e"); @@ -101,24 +80,27 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { @override Future clear() async { - getCachedPreferences.clear(); - return _writePreferencesToFile(); + var preferences = await _readPreferences(); + preferences.clear(); + return _writePreferences(preferences); } @override Future> getAll() async { - return getCachedPreferences; + return _readPreferences(); } @override Future remove(String key) async { - getCachedPreferences.remove(key); - return _writePreferencesToFile(); + var preferences = await _readPreferences(); + preferences.remove(key); + return _writePreferences(preferences); } @override Future setValue(String valueType, String key, Object value) async { - getCachedPreferences[key] = value; - return _writePreferencesToFile(); + var preferences = await _readPreferences(); + preferences[key] = value; + return _writePreferences(preferences); } } diff --git a/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart b/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart deleted file mode 100644 index d4d0d65dc3ae..000000000000 --- a/packages/shared_preferences/shared_preferences_windows/lib/src/win32.dart +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -import 'dart:ffi'; -import 'dart:typed_data'; -import 'package:ffi/ffi.dart'; - -// Constants: - -/// Typedef for kNull values. -const kNull = 0; - -/// Typedef for MAX_VALUE. -const kMaxPath = 260; - -// Function definitions: - -// Definition for SHGetFolderPathW. Retrieves a folder path given a CSIDL. -// -// SHFOLDERAPI SHGetFolderPathW( -// HWND hwnd, -// int csidl, -// HANDLE hToken, -// DWORD dwFlags, -// LPWSTR pszPath -// ); -// -// This is a deprecated API. It is being used in place of the recommended -// API SHGetKnownFolderPath, since it has been challenging to retrieve the REFKNOWNFOLDERID -// parameter with ffi calls. It is safe to use this API since (per Microsoft's documentation) -// as of Windows Vista, this function is merely a wrapper for SHGetKnownFolderPath. -typedef shGetFolderPathNative = Int32 Function(Int64 hwnd, Int32 csidl, - Int64 hToken, Int32 dwFlags, Pointer pszPath); -typedef shGetFolderPathDart = int Function( - int hwnd, int csidl, int hToken, int dwFlags, Pointer pszPath); - -// Definition for GetModuleFileNameW. Retrieves the path to the current process. -// -// DWORD GetModuleFileNameW( -// HMODULE hModule, -// LPWSTR lpFilename, -// DWORD nSize -// ); -typedef GetModuleFileNameC = Int32 Function( - Int32 hModule, - Pointer fileName, - Int16 nSize, -); -typedef GetModuleFileNameDart = int Function( - int hModule, - Pointer fileName, - int nSize, -); - -/// Reference to the Shell32 dynamic library. -final shell32 = DynamicLibrary.open('shell32.dll'); - -/// Reference to the Kernel32 dynamic library. -final kernel32 = DynamicLibrary.open('kernel32.dll'); - -/// Dart invocation of the win32 SHGetFolderPathW function. -final shGetFolderPath = - shell32.lookupFunction( - 'SHGetFolderPathW'); - -/// Dart invocation of the win32 GetModuleFileNameW function. -final getModuleFileNameW = - kernel32.lookupFunction( - 'GetModuleFileNameW'); - -/// Convenience method to get the AppData Local folder path. -String getLocalDataPath() { - final CSIDL_LOCAL_APPDATA = 0x001c; - final CSIDL_FLAG_CREATE = 0x8000; - Pointer path = allocate(count: kMaxPath); - shGetFolderPath( - kNull, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE, kNull, 0, path); - - Uint16List pathData = path.asTypedList(kMaxPath); - return String.fromCharCodes( - path.asTypedList(kMaxPath), 0, pathData.indexOf(0)); -} - -/// Convenience method to retrieve the path of the current process. -String getModuleFileName() { - Pointer rs = allocate(count: kMaxPath); - getModuleFileNameW(kNull, rs, kMaxPath); - Uint16List pathData = rs.asTypedList(kMaxPath); - return String.fromCharCodes(rs.asTypedList(kMaxPath), 0, pathData.indexOf(0)); -} diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index dfc4e06a40e8..a8de0eac99b9 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -22,6 +22,11 @@ dependencies: file: ">=5.1.0 <7.0.0" meta: ^1.1.7 path: ^1.6.4 + path_provider_platform_interface: ^1.0.3 + path_provider_windows: ^0.0.1 + # DO NOT LAND: Update the above to require the landed version of + # path_provider_windows once it's landed and published; this version doesn't + # use the desired path for application support. dev_dependencies: flutter_test: diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart index 2b7250f1eaca..aad386ae8373 100644 --- a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart @@ -1,95 +1,107 @@ -// Copyright 2017 The Chromium Authors. All rights reserved. +// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:flutter_test/flutter_test.dart'; import 'package:file/memory.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:path/path.dart' as path; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:path_provider_windows/path_provider_windows.dart'; import 'package:shared_preferences_windows/shared_preferences_windows.dart'; -MemoryFileSystem fs = MemoryFileSystem.test(); - void main() { - const String kTestKey = 'testKey'; - const String kTestValue = 'testValue'; - - SharedPreferencesWindows sharedPreferences; + MemoryFileSystem fileSystem; + PathProviderWindows pathProvider; setUp(() { - sharedPreferences = SharedPreferencesWindows(); - sharedPreferences.win32Wrapper = MockWin32Wrapper(); - sharedPreferences.fs = fs; + fileSystem = MemoryFileSystem.test(); + pathProvider = FakePathProviderWindows(); }); - tearDown(() { - fs.file(sharedPreferences.getLocalDataFilePath) - ..deleteSync(recursive: true); - }); + tearDown(() {}); + + Future _getFilePath() async { + final directory = await pathProvider.getApplicationSupportPath(); + return path.join(directory, 'shared_preferences.json'); + } - /// Writes the test file to disk and loads the contents to the - /// sharedPreferences cache. - void _writeTestFile() { - fs.file(sharedPreferences.getLocalDataFilePath) + _writeTestFile(String value) async { + fileSystem.file(await _getFilePath()) ..createSync(recursive: true) - ..writeAsStringSync(''' - { - "$kTestKey": "$kTestValue" - } - '''); - // Loads the file contents into the shared preferences store's cache. - sharedPreferences.getCachedPreferences; + ..writeAsStringSync(value); + } + + Future _readTestFile() async { + return fileSystem.file(await _getFilePath()).readAsStringSync(); } - String _readTestFile() { - return fs.file(sharedPreferences.getLocalDataFilePath).readAsStringSync(); + SharedPreferencesWindows _getPreferences() { + var prefs = SharedPreferencesWindows(); + prefs.fs = fileSystem; + prefs.pathProvider = pathProvider; + return prefs; } - group('shared preferences', () { - test('getAll', () async { - _writeTestFile(); - - final Map allData = await sharedPreferences.getAll(); - expect(allData, hasLength(1)); - expect(allData[kTestKey], kTestValue); - }); - - test('remove', () async { - _writeTestFile(); - expect(sharedPreferences.getCachedPreferences[kTestKey], isNotNull); - expect(await sharedPreferences.remove(kTestKey), isTrue); - expect(sharedPreferences.getCachedPreferences.containsKey(kTestKey), - isFalse); - expect(_readTestFile(), '{}'); - }); - - test('setValue', () async { - _writeTestFile(); - const String kNewKey = 'NewKey'; - const String kNewValue = 'NewValue'; - expect(sharedPreferences.getCachedPreferences[kNewKey], isNull); - expect(await sharedPreferences.setValue('String', kNewKey, kNewValue), - isTrue); - expect(sharedPreferences.getCachedPreferences[kNewKey], isNotNull); - expect(_readTestFile(), - '{"$kTestKey":"$kTestValue","$kNewKey":"$kNewValue"}'); - }); - - test('clear', () async { - _writeTestFile(); - expect(await sharedPreferences.clear(), isTrue); - expect(sharedPreferences.getCachedPreferences.isEmpty, isTrue); - expect(_readTestFile(), '{}'); - }); + test('getAll', () async { + await _writeTestFile('{"key1": "one", "key2": 2}'); + var prefs = _getPreferences(); + + var values = await prefs.getAll(); + expect(values, hasLength(2)); + expect(values['key1'], 'one'); + expect(values['key2'], 2); + }); + + test('remove', () async { + await _writeTestFile('{"key1":"one","key2":2}'); + var prefs = _getPreferences(); + + await prefs.remove('key2'); + + expect(await _readTestFile(), '{"key1":"one"}'); + }); + + test('setValue', () async { + await _writeTestFile('{}'); + var prefs = _getPreferences(); + + await prefs.setValue('', 'key1', 'one'); + await prefs.setValue('', 'key2', 2); + + expect(await _readTestFile(), '{"key1":"one","key2":2}'); + }); + + test('clear', () async { + await _writeTestFile('{"key1":"one","key2":2}'); + var prefs = _getPreferences(); + + await prefs.clear(); + expect(await _readTestFile(), '{}'); }); } -class MockWin32Wrapper extends Win32Wrapper { +/// Fake implementation of PathProviderWindows that returns hard-coded paths, +/// allowing tests to run on any platform. +/// +/// Note that this should only be used with an in-memory filesystem, as the +/// path it returns is a root path that does not actually exist on Windows. +class FakePathProviderWindows extends PathProviderPlatform + implements PathProviderWindows { @override - String getLocalDataPath() { - return fs.directory('\\data').path; - } + Future getApplicationSupportPath() async => r'C:\appsupport'; @override - String getModuleFileName() { - return 'test'; - } + Future getTemporaryPath() async => null; + + @override + Future getLibraryPath() async => null; + + @override + Future getApplicationDocumentsPath() async => null; + + @override + Future getDownloadsPath() async => null; + + @override + Future getPath(String folderID) async => null; } From 0ea3b4da6d33f614f13b0b503442911df50df795 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Wed, 16 Sep 2020 06:54:41 -0700 Subject: [PATCH 18/20] Remove a TODO; this solution is a reasonable one --- .../lib/shared_preferences_windows.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart index ec9bb0124b9c..dd9ab8a0c38f 100644 --- a/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart +++ b/packages/shared_preferences/shared_preferences_windows/lib/shared_preferences_windows.dart @@ -23,9 +23,6 @@ class SharedPreferencesWindows extends SharedPreferencesStorePlatform { FileSystem fs = LocalFileSystem(); /// The path_provider_windows instance used to find the support directory. - /// - /// DO NOT LAND: See what the testing solution is for path_provider to see if - /// exposing this is actually necessary. @visibleForTesting PathProviderWindows pathProvider = PathProviderWindows(); From 7f1a10da6fcb3787b3d4b21913c83150dee7337b Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 18 Sep 2020 09:57:55 -0700 Subject: [PATCH 19/20] Require path_provider_windows 0.0.2 --- .../shared_preferences_windows/pubspec.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml index a8de0eac99b9..ce4dbc603237 100644 --- a/packages/shared_preferences/shared_preferences_windows/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_windows/pubspec.yaml @@ -23,10 +23,7 @@ dependencies: meta: ^1.1.7 path: ^1.6.4 path_provider_platform_interface: ^1.0.3 - path_provider_windows: ^0.0.1 - # DO NOT LAND: Update the above to require the landed version of - # path_provider_windows once it's landed and published; this version doesn't - # use the desired path for application support. + path_provider_windows: ^0.0.2 dev_dependencies: flutter_test: From 9d2f1d4cafd331fd9f28678493123b09ee98b7cc Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Fri, 18 Sep 2020 10:44:27 -0700 Subject: [PATCH 20/20] Update fake path provider --- .../test/shared_preferences_windows_test.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart index aad386ae8373..b0827ca3b36b 100644 --- a/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart +++ b/packages/shared_preferences/shared_preferences_windows/test/shared_preferences_windows_test.dart @@ -87,6 +87,8 @@ void main() { /// path it returns is a root path that does not actually exist on Windows. class FakePathProviderWindows extends PathProviderPlatform implements PathProviderWindows { + VersionInfoQuerier versionInfoQuerier; + @override Future getApplicationSupportPath() async => r'C:\appsupport';