[shared_preferences] Platform interface for new shared preferences async (#6962)

Platform interface portion of https://github.com/flutter/packages/pull/5210

Adds new async api
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md
index 3966f65..b611dd3 100644
--- a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md
+++ b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md
@@ -1,5 +1,6 @@
-## NEXT
+## 2.4.0
 
+* Adds `SharedPreferencesAsyncPlatform` API.
 * Updates minimum supported SDK version to Flutter 3.16/Dart 3.2.
 
 ## 2.3.2
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/README.md b/packages/shared_preferences/shared_preferences_platform_interface/README.md
index 301ba68..6716fe9 100644
--- a/packages/shared_preferences/shared_preferences_platform_interface/README.md
+++ b/packages/shared_preferences/shared_preferences_platform_interface/README.md
@@ -9,9 +9,16 @@
 # Usage
 
 To implement a new platform-specific implementation of `shared_preferences`, extend
-[`SharedPreferencesPlatform`][2] with an implementation that performs the
-platform-specific behavior, and when you register your plugin, set the default
-`SharedPreferencesLoader` by calling the `SharedPreferencesPlatform.loader` setter.
+[`SharedPreferencesPlatform`][2] and [`SharedPreferencesAsyncPlatform`][3] with
+implementations that perform the platform-specific behaviors, and when you register
+your plugin, set the default `SharedPreferencesStorePlatform` and
+`SharedPreferencesAsyncPlatform` by calling the `SharedPreferencesPlatform.instance`
+and `SharedPreferencesAsyncPlatform.instance` setters.
+
+Please note that the plugin tooling only registers the native and/or Dart classes
+listed in your package's `pubspec.yaml`, so if you intend to implement more than
+one class, you will need to manually register the second class
+(as can be seen in the Android and iOS implementations).
 
 # Note on breaking changes
 
@@ -23,3 +30,4 @@
 
 [1]: ../shared_preferences
 [2]: lib/shared_preferences_platform_interface.dart
+[3]: lib/shared_preferences_async_platform_interface.dart
\ No newline at end of file
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/in_memory_shared_preferences_async.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/in_memory_shared_preferences_async.dart
new file mode 100644
index 0000000..5080241
--- /dev/null
+++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/in_memory_shared_preferences_async.dart
@@ -0,0 +1,158 @@
+// Copyright 2013 The Flutter 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 'shared_preferences_async_platform_interface.dart';
+import 'types.dart';
+
+/// Stores data in memory.
+///
+/// Data does not persist across application restarts. This is useful in unit tests.
+base class InMemorySharedPreferencesAsync
+    extends SharedPreferencesAsyncPlatform {
+  /// Instantiates an empty in-memory preferences store.
+  InMemorySharedPreferencesAsync.empty() : _data = <String, Object>{};
+
+  /// Instantiates an in-memory preferences store containing a copy of [data].
+  InMemorySharedPreferencesAsync.withData(Map<String, Object> data)
+      : _data = Map<String, Object>.from(data);
+
+  final Map<String, Object> _data;
+
+  @override
+  Future<bool> clear(
+    ClearPreferencesParameters parameters,
+    SharedPreferencesOptions options,
+  ) async {
+    final PreferencesFilters filter = parameters.filter;
+    if (filter.allowList != null) {
+      _data.removeWhere((String key, _) => filter.allowList!.contains(key));
+    } else {
+      _data.clear();
+    }
+    return true;
+  }
+
+  @override
+  Future<Map<String, Object>> getPreferences(
+    GetPreferencesParameters parameters,
+    SharedPreferencesOptions options,
+  ) async {
+    final PreferencesFilters filter = parameters.filter;
+    final Map<String, Object> preferences = Map<String, Object>.from(_data);
+    preferences.removeWhere((String key, _) =>
+        filter.allowList != null && !filter.allowList!.contains(key));
+    return preferences;
+  }
+
+  Future<bool> _setValue(
+    String key,
+    Object value,
+    SharedPreferencesOptions options,
+  ) async {
+    _data[key] = value;
+    return true;
+  }
+
+  @override
+  Future<bool> setString(
+    String key,
+    String value,
+    SharedPreferencesOptions options,
+  ) async {
+    return _setValue(key, value, options);
+  }
+
+  @override
+  Future<bool> setInt(
+    String key,
+    int value,
+    SharedPreferencesOptions options,
+  ) async {
+    return _setValue(key, value, options);
+  }
+
+  @override
+  Future<bool> setDouble(
+    String key,
+    double value,
+    SharedPreferencesOptions options,
+  ) async {
+    return _setValue(key, value, options);
+  }
+
+  @override
+  Future<bool> setBool(
+    String key,
+    bool value,
+    SharedPreferencesOptions options,
+  ) async {
+    return _setValue(key, value, options);
+  }
+
+  @override
+  Future<bool> setStringList(
+    String key,
+    List<String> value,
+    SharedPreferencesOptions options,
+  ) async {
+    return _setValue(key, value, options);
+  }
+
+  @override
+  Future<String?> getString(
+    String key,
+    SharedPreferencesOptions options,
+  ) async {
+    return _data[key] as String?;
+  }
+
+  @override
+  Future<bool?> getBool(
+    String key,
+    SharedPreferencesOptions options,
+  ) async {
+    return _data[key] as bool?;
+  }
+
+  @override
+  Future<double?> getDouble(
+    String key,
+    SharedPreferencesOptions options,
+  ) async {
+    return _data[key] as double?;
+  }
+
+  @override
+  Future<int?> getInt(
+    String key,
+    SharedPreferencesOptions options,
+  ) async {
+    return _data[key] as int?;
+  }
+
+  @override
+  Future<List<String>?> getStringList(
+    String key,
+    SharedPreferencesOptions options,
+  ) async {
+    final List<Object>? data = _data[key] as List<Object>?;
+    return data?.cast<String>();
+  }
+
+  @override
+  Future<Set<String>> getKeys(
+    GetPreferencesParameters parameters,
+    SharedPreferencesOptions options,
+  ) async {
+    final Set<String> keys = _data.keys.toSet();
+    if (parameters.filter.allowList != null) {
+      keys.retainWhere(
+          (String element) => parameters.filter.allowList!.contains(element));
+    }
+
+    return keys;
+  }
+}
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_async_platform_interface.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_async_platform_interface.dart
new file mode 100644
index 0000000..559483b
--- /dev/null
+++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_async_platform_interface.dart
@@ -0,0 +1,109 @@
+// Copyright 2013 The Flutter 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 'types.dart';
+
+/// The interface that implementations of shared_preferences_async must implement.
+abstract base class SharedPreferencesAsyncPlatform {
+  /// Constructs a SharedPreferencesAsyncPlatform.
+  SharedPreferencesAsyncPlatform();
+
+  /// The instance of [SharedPreferencesAsyncPlatform] to use.
+  static SharedPreferencesAsyncPlatform? instance;
+
+  /// Stores the String [value] associated with the [key].
+  Future<void> setString(
+    String key,
+    String value,
+    SharedPreferencesOptions options,
+  );
+
+  /// Stores the bool [value] associated with the [key].
+  Future<void> setBool(
+    String key,
+    bool value,
+    SharedPreferencesOptions options,
+  );
+
+  /// Stores the double [value] associated with the [key].
+  Future<void> setDouble(
+    String key,
+    double value,
+    SharedPreferencesOptions options,
+  );
+
+  /// Stores the int [value] associated with the [key].
+  Future<void> setInt(
+    String key,
+    int value,
+    SharedPreferencesOptions options,
+  );
+
+  /// Stores the List<String> [value] associated with the [key].
+  Future<void> setStringList(
+    String key,
+    List<String> value,
+    SharedPreferencesOptions options,
+  );
+
+  /// Retrieves the String [value] associated with the [key], if any.
+  ///
+  /// Throws a [TypeError] if the returned type is not a String.
+  Future<String?> getString(
+    String key,
+    SharedPreferencesOptions options,
+  );
+
+  /// Retrieves the bool [value] associated with the [key], if any.
+  ///
+  /// Throws a [TypeError] if the returned type is not a bool.
+  Future<bool?> getBool(
+    String key,
+    SharedPreferencesOptions options,
+  );
+
+  /// Retrieves the double [value] associated with the [key], if any.
+  ///
+  /// Throws a [TypeError] if the returned type is not a double.
+  Future<double?> getDouble(
+    String key,
+    SharedPreferencesOptions options,
+  );
+
+  /// Retrieves the int [value] associated with the [key], if any.
+  ///
+  /// Throws a [TypeError] if the returned type is not an int.
+  Future<int?> getInt(
+    String key,
+    SharedPreferencesOptions options,
+  );
+
+  /// Retrieves the List<String> [value] associated with the [key], if any.
+  ///
+  /// Throws a [TypeError] if the returned type is not a List<String>.
+  Future<List<String>?> getStringList(
+    String key,
+    SharedPreferencesOptions options,
+  );
+
+  /// Removes all keys and values in the store that match the given [parameters].
+  Future<void> clear(
+    ClearPreferencesParameters parameters,
+    SharedPreferencesOptions options,
+  );
+
+  /// Returns all key/value pairs persisting in this store that match the given [parameters].
+  Future<Map<String, Object>> getPreferences(
+    GetPreferencesParameters parameters,
+    SharedPreferencesOptions options,
+  );
+
+  /// Returns all keys persisting in this store that match the given [parameters].
+  Future<Set<String>> getKeys(
+    GetPreferencesParameters parameters,
+    SharedPreferencesOptions options,
+  );
+}
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/types.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/types.dart
index f52f071..979361c 100644
--- a/packages/shared_preferences/shared_preferences_platform_interface/lib/types.dart
+++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/types.dart
@@ -2,9 +2,62 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/// Filter options used to get and clear preferences.
+// shared_preferences_async types.
+
+import 'package:flutter/foundation.dart';
+
+/// Basic options for creating SharedPreferencesAsync classes.
+///
+/// This class exists to provide extension to platform specific options as
+/// there are currently no general options that are not platform specific.
+@immutable
+class SharedPreferencesOptions {
+  /// Constructor for SharedPreferencesOptions.
+  const SharedPreferencesOptions();
+}
+
+/// Filter options used to get and clear preferences on shared_preferences_async.
+@immutable
+class PreferencesFilters {
+  /// Creates a new instance with the given options.
+  const PreferencesFilters({
+    this.allowList,
+  });
+
+  /// A list of preference keys that will limit getting and clearing to only
+  /// items included in this list.
+  ///
+  /// An empty set will create a filter that allows no items to be set/get.
+  final Set<String>? allowList;
+}
+
+/// Parameters for use in [get] methods on shared_preferences_async.
+@immutable
+class GetPreferencesParameters {
+  /// Creates a new instance with the given options.
+  const GetPreferencesParameters({required this.filter});
+
+  /// Filter to limit which preferences are returned.
+  final PreferencesFilters filter;
+}
+
+/// Parameters for use in [clear] methods on shared_preferences_async.
+@immutable
+class ClearPreferencesParameters {
+  /// Creates a new instance with the given options.
+  const ClearPreferencesParameters({required this.filter});
+
+  /// Filter to limit which preferences are cleared.
+  final PreferencesFilters filter;
+}
+
+//////////////////////////////////
+// legacy_shared_preferences types.
+//////////////////////////////////
+
+/// Filter options used to get and clear preferences on legacy_shared_preferences.
 class PreferencesFilter {
-  /// Constructor.
+  /// Creates a new instance with the given options.
   PreferencesFilter({
     required this.prefix,
     this.allowList,
@@ -19,18 +72,18 @@
   Set<String>? allowList;
 }
 
-/// Parameters for use in [getAll] methods.
+/// Parameters for use in [getAll] methods on legacy_shared_preferences.
 class GetAllParameters {
-  /// Constructor.
+  /// Creates a new instance with the given options.
   GetAllParameters({required this.filter});
 
   /// Filter to limit which preferences are returned.
   PreferencesFilter filter;
 }
 
-/// Parameters for use in [clear] methods.
+/// Parameters for use in [clear] methods on legacy_shared_preferences.
 class ClearParameters {
-  /// Constructor.
+  /// Creates a new instance with the given options.
   ClearParameters({required this.filter});
 
   /// Filter to limit which preferences are cleared.
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml
index c8c9832..8d90956 100644
--- a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml
+++ b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml
@@ -2,7 +2,7 @@
 description: A common platform interface for the shared_preferences plugin.
 repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences_platform_interface
 issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
-version: 2.3.2
+version: 2.4.0
 
 environment:
   sdk: ^3.2.0
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart b/packages/shared_preferences/shared_preferences_platform_interface/test/deprecated_method_channel_shared_preferences_test.dart
similarity index 100%
rename from packages/shared_preferences/shared_preferences_platform_interface/test/method_channel_shared_preferences_test.dart
rename to packages/shared_preferences/shared_preferences_platform_interface/test/deprecated_method_channel_shared_preferences_test.dart