[shared_preferences] Migrate platform plugins to null-safety (#3523)

Migrates shared_preferences_linux and shared_preferences_web to null-safety.
diff --git a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md
index 9821b79..2be9c8c 100644
--- a/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md
+++ b/packages/shared_preferences/shared_preferences_linux/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.0.4-nullsafety
+
+* Migrate to null-safety.
+
 ## 0.0.3+1
 
 * Update Flutter SDK constraint.
diff --git a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart
index e43d4e3..3aedccd 100644
--- a/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart
+++ b/packages/shared_preferences/shared_preferences_linux/example/integration_test/shared_preferences_test.dart
@@ -1,12 +1,13 @@
 import 'dart:async';
+
 import 'package:flutter_test/flutter_test.dart';
-import 'package:shared_preferences/shared_preferences.dart';
 import 'package:integration_test/integration_test.dart';
+import 'package:shared_preferences_linux/shared_preferences_linux.dart';
 
 void main() {
   IntegrationTestWidgetsFlutterBinding.ensureInitialized();
 
-  group('$SharedPreferences', () {
+  group('SharedPreferencesLinux', () {
     const Map<String, dynamic> kTestValues = <String, dynamic>{
       'flutter.String': 'hello world',
       'flutter.bool': true,
@@ -23,10 +24,10 @@
       'flutter.List': <String>['baz', 'quox'],
     };
 
-    SharedPreferences preferences;
+    SharedPreferencesLinux preferences;
 
     setUp(() async {
-      preferences = await SharedPreferences.getInstance();
+      preferences = SharedPreferencesLinux.instance;
     });
 
     tearDown(() {
@@ -34,56 +35,62 @@
     });
 
     testWidgets('reading', (WidgetTester _) 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 all = await preferences.getAll();
+      expect(all['String'], isNull);
+      expect(all['bool'], isNull);
+      expect(all['int'], isNull);
+      expect(all['double'], isNull);
+      expect(all['List'], isNull);
     });
 
     testWidgets('writing', (WidgetTester _) async {
       await Future.wait(<Future<bool>>[
-        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 all = await preferences.getAll();
+      expect(all['String'], kTestValues2['flutter.String']);
+      expect(all['bool'], kTestValues2['flutter.bool']);
+      expect(all['int'], kTestValues2['flutter.int']);
+      expect(all['double'], kTestValues2['flutter.double']);
+      expect(all['List'], kTestValues2['flutter.List']);
     });
 
     testWidgets('removing', (WidgetTester _) 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 Future.wait([
+        preferences.setValue('String', key, kTestValues['flutter.String']),
+        preferences.setValue('Bool', key, kTestValues['flutter.bool']),
+        preferences.setValue('Int', key, kTestValues['flutter.int']),
+        preferences.setValue('Double', key, kTestValues['flutter.double']),
+        preferences.setValue('StringList', key, kTestValues['flutter.List'])
+      ]);
       await preferences.remove(key);
-      expect(preferences.get('testKey'), isNull);
+      final all = await preferences.getAll();
+      expect(all['testKey'], isNull);
     });
 
     testWidgets('clearing', (WidgetTester _) 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 Future.wait(<Future<bool>>[
+        preferences.setValue('String', 'String', kTestValues['flutter.String']),
+        preferences.setValue('Bool', 'bool', kTestValues['flutter.bool']),
+        preferences.setValue('Int', 'int', kTestValues['flutter.int']),
+        preferences.setValue('Double', 'double', kTestValues['flutter.double']),
+        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 all = await preferences.getAll();
+      expect(all['String'], null);
+      expect(all['bool'], null);
+      expect(all['int'], null);
+      expect(all['double'], null);
+      expect(all['List'], null);
     });
   });
 }
diff --git a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml
index fb79444..591aad4 100644
--- a/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml
+++ b/packages/shared_preferences/shared_preferences_linux/example/pubspec.yaml
@@ -4,15 +4,8 @@
 dependencies:
   flutter:
     sdk: flutter
-  shared_preferences: any
-  shared_preferences_linux: ^0.1.0
-
-dependency_overrides:
   shared_preferences_linux:
     path: ../
-  # Remove this override once the endorsement is published.
-  shared_preferences:
-    path: ../../shared_preferences/
 
 dev_dependencies:
   flutter_driver:
diff --git a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart
index c975ad1..5a69465 100644
--- a/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart
+++ b/packages/shared_preferences/shared_preferences_linux/lib/shared_preferences_linux.dart
@@ -20,16 +20,17 @@
   static SharedPreferencesLinux instance = SharedPreferencesLinux();
 
   /// Local copy of preferences
-  Map<String, Object> _cachedPreferences;
+  Map<String, Object>? _cachedPreferences;
 
   /// File system used to store to disk. Exposed for testing only.
   @visibleForTesting
   FileSystem fs = LocalFileSystem();
 
   /// Gets the file where the preferences are stored.
-  Future<File> _getLocalDataFile() async {
+  Future<File?> _getLocalDataFile() async {
     final pathProvider = PathProviderLinux();
     final directory = await pathProvider.getApplicationSupportPath();
+    if (directory == null) return null;
     return fs.file(path.join(directory, 'shared_preferences.json'));
   }
 
@@ -37,19 +38,19 @@
   /// maintained in memory.
   Future<Map<String, Object>> _readPreferences() async {
     if (_cachedPreferences != null) {
-      return _cachedPreferences;
+      return _cachedPreferences!;
     }
 
-    _cachedPreferences = {};
-    var localDataFile = await _getLocalDataFile();
-    if (localDataFile.existsSync()) {
+    Map<String, Object> preferences = {};
+    final File? localDataFile = await _getLocalDataFile();
+    if (localDataFile != null && localDataFile.existsSync()) {
       String stringMap = localDataFile.readAsStringSync();
       if (stringMap.isNotEmpty) {
-        _cachedPreferences = json.decode(stringMap) as Map<String, Object>;
+        preferences = json.decode(stringMap).cast<String, Object>();
       }
     }
-
-    return _cachedPreferences;
+    _cachedPreferences = preferences;
+    return preferences;
   }
 
   /// Writes the cached preferences to disk. Returns [true] if the operation
@@ -57,6 +58,10 @@
   Future<bool> _writePreferences(Map<String, Object> preferences) async {
     try {
       var localDataFile = await _getLocalDataFile();
+      if (localDataFile == null) {
+        print("Unable to determine where to write preferences.");
+        return false;
+      }
       if (!localDataFile.existsSync()) {
         localDataFile.createSync(recursive: true);
       }
diff --git a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml
index 50709aa..df4b5db 100644
--- a/packages/shared_preferences/shared_preferences_linux/pubspec.yaml
+++ b/packages/shared_preferences/shared_preferences_linux/pubspec.yaml
@@ -1,6 +1,6 @@
 name: shared_preferences_linux
 description: Linux implementation of the shared_preferences plugin
-version: 0.0.3+1
+version: 0.0.4-nullsafety
 homepage: https://github.com/flutter/plugins/tree/master/packages/shared_preferences/shared_preferences_linux
 
 flutter:
@@ -11,17 +11,17 @@
         pluginClass: none
 
 environment:
-  sdk: ">=2.1.0 <3.0.0"
+  sdk: ">=2.12.0-0 <3.0.0"
   flutter: ">=1.12.8"
 
 dependencies:
-  file: ">=5.1.0 <7.0.0"
   flutter:
     sdk: flutter
+  file: ^6.0.0-nullsafety.4
   meta: ^1.0.4
-  path: ^1.6.4
-  path_provider_linux: ^0.0.1
-  shared_preferences_platform_interface: ^1.0.0
+  path: ^1.8.0-nullsafety.3
+  path_provider_linux: ^0.2.0-nullsafety
+  shared_preferences_platform_interface: ^2.0.0-nullsafety
 
 dev_dependencies:
   flutter_test:
diff --git a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart
index 8c659f2..cf0bc80 100644
--- a/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart
+++ b/packages/shared_preferences/shared_preferences_linux/test/shared_preferences_linux_test.dart
@@ -7,9 +7,9 @@
 import 'package:path_provider_linux/path_provider_linux.dart';
 import 'package:shared_preferences_linux/shared_preferences_linux.dart';
 
-MemoryFileSystem fs;
-
 void main() {
+  late MemoryFileSystem fs;
+
   setUp(() {
     fs = MemoryFileSystem.test();
   });
@@ -19,7 +19,7 @@
   Future<String> _getFilePath() async {
     final pathProvider = PathProviderLinux();
     final directory = await pathProvider.getApplicationSupportPath();
-    return path.join(directory, 'shared_preferences.json');
+    return path.join(directory!, 'shared_preferences.json');
   }
 
   _writeTestFile(String value) async {
diff --git a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md
index 2ba8778..0194ef8 100644
--- a/packages/shared_preferences/shared_preferences_web/CHANGELOG.md
+++ b/packages/shared_preferences/shared_preferences_web/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.2.0-nullsafety
+
+* Migrate to null-safety.
+
 ## 0.1.2+8
 
 * Update Flutter SDK constraint.
diff --git a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart
index 8a0f137..346877e 100644
--- a/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart
+++ b/packages/shared_preferences/shared_preferences_web/lib/shared_preferences_web.dart
@@ -14,7 +14,7 @@
 /// This class implements the `package:shared_preferences` functionality for the web.
 class SharedPreferencesPlugin extends SharedPreferencesStorePlatform {
   /// Registers this class as the default instance of [SharedPreferencesStorePlatform].
-  static void registerWith(Registrar registrar) {
+  static void registerWith(Registrar? registrar) {
     SharedPreferencesStorePlatform.instance = SharedPreferencesPlugin();
   }
 
@@ -31,9 +31,9 @@
 
   @override
   Future<Map<String, Object>> getAll() async {
-    final Map<String, Object> allData = <String, Object>{};
+    final Map<String, Object> allData = {};
     for (String key in _storedFlutterKeys) {
-      allData[key] = _decodeValue(html.window.localStorage[key]);
+      allData[key] = _decodeValue(html.window.localStorage[key]!);
     }
     return allData;
   }
@@ -46,7 +46,7 @@
   }
 
   @override
-  Future<bool> setValue(String valueType, String key, Object value) async {
+  Future<bool> setValue(String valueType, String key, Object? value) async {
     _checkPrefix(key);
     html.window.localStorage[key] = _encodeValue(value);
     return true;
@@ -62,17 +62,12 @@
     }
   }
 
-  List<String> get _storedFlutterKeys {
-    final List<String> keys = <String>[];
-    for (String key in html.window.localStorage.keys) {
-      if (key.startsWith('flutter.')) {
-        keys.add(key);
-      }
-    }
-    return keys;
+  Iterable<String> get _storedFlutterKeys {
+    return html.window.localStorage.keys
+        .where((key) => key.startsWith('flutter.'));
   }
 
-  String _encodeValue(Object value) {
+  String _encodeValue(Object? value) {
     return json.encode(value);
   }
 
diff --git a/packages/shared_preferences/shared_preferences_web/pubspec.yaml b/packages/shared_preferences/shared_preferences_web/pubspec.yaml
index d657b23..60892bc 100644
--- a/packages/shared_preferences/shared_preferences_web/pubspec.yaml
+++ b/packages/shared_preferences/shared_preferences_web/pubspec.yaml
@@ -4,7 +4,7 @@
 # 0.1.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.1.2+8
+version: 0.2.0-nullsafety
 
 flutter:
   plugin:
@@ -14,7 +14,7 @@
         fileName: shared_preferences_web.dart
 
 dependencies:
-  shared_preferences_platform_interface: ^1.0.0
+  shared_preferences_platform_interface: ^2.0.0-nullsafety
   flutter:
     sdk: flutter
   flutter_web_plugins:
@@ -27,5 +27,5 @@
   pedantic: ^1.8.0
 
 environment:
-  sdk: ">=2.1.0 <3.0.0"
+  sdk: ">=2.12.0-0 <3.0.0"
   flutter: ">=1.12.13+hotfix.4"
diff --git a/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart b/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart
index 951f04c..c0cf92c 100644
--- a/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart
+++ b/packages/shared_preferences/shared_preferences_web/test/shared_preferences_web_test.dart
@@ -2,12 +2,12 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-@TestOn('chrome') // Uses web-only Flutter SDK
-
+@TestOn('chrome')
 import 'dart:convert' show json;
 import 'dart:html' as html;
 
 import 'package:flutter_test/flutter_test.dart';
+import 'package:shared_preferences_platform_interface/method_channel_shared_preferences.dart';
 import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart';
 import 'package:shared_preferences_web/shared_preferences_web.dart';
 
@@ -26,6 +26,8 @@
     });
 
     test('registers itself', () {
+      SharedPreferencesStorePlatform.instance =
+          MethodChannelSharedPreferencesStore();
       expect(SharedPreferencesStorePlatform.instance,
           isNot(isA<SharedPreferencesPlugin>()));
       SharedPreferencesPlugin.registerWith(null);