Simplify the flutter_web_plugins plugin registration API. (#70337) (#70722)
In principle this is backwards compatible; I just merged all the classes into one and deprecated everything that became redundant as a result.
diff --git a/packages/flutter_tools/lib/src/build_system/targets/web.dart b/packages/flutter_tools/lib/src/build_system/targets/web.dart
index ee56688..46aadd3 100644
--- a/packages/flutter_tools/lib/src/build_system/targets/web.dart
+++ b/packages/flutter_tools/lib/src/build_system/targets/web.dart
@@ -135,7 +135,7 @@
import '$mainImport' as entrypoint;
Future<void> main() async {
- registerPlugins(webPluginRegistry);
+ registerPlugins(webPluginRegistrar);
await ui.webOnlyInitializePlatform();
entrypoint.main();
}
diff --git a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
index f0c98f7..7a016ff 100644
--- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
+++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart
@@ -686,7 +686,7 @@
'typedef _NullaryFunction = dynamic Function();',
'Future<void> main() async {',
if (hasWebPlugins)
- ' registerPlugins(webPluginRegistry);',
+ ' registerPlugins(webPluginRegistrar);',
' await ui.webOnlyInitializePlatform();',
' if (entrypoint.main is _UnaryFunction) {',
' return (entrypoint.main as _UnaryFunction)(<String>[]);',
diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart
index 3883862..0539e0c 100644
--- a/packages/flutter_tools/lib/src/plugins.dart
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -779,9 +779,6 @@
// Generated file. Do not edit.
//
-// ignore: unused_import
-import 'dart:ui';
-
{{#plugins}}
import 'package:{{name}}/{{file}}';
{{/plugins}}
@@ -789,11 +786,11 @@
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
// ignore: public_member_api_docs
-void registerPlugins(PluginRegistry registry) {
+void registerPlugins(Registrar registrar) {
{{#plugins}}
- {{class}}.registerWith(registry.registrarFor({{class}}));
+ {{class}}.registerWith(registrar);
{{/plugins}}
- registry.registerMessageHandler();
+ registrar.registerMessageHandler();
}
''';
diff --git a/packages/flutter_tools/templates/plugin/lib/projectName_web.dart.tmpl b/packages/flutter_tools/templates/plugin/lib/projectName_web.dart.tmpl
index 37dc71c..2113520 100644
--- a/packages/flutter_tools/templates/plugin/lib/projectName_web.dart.tmpl
+++ b/packages/flutter_tools/templates/plugin/lib/projectName_web.dart.tmpl
@@ -14,7 +14,7 @@
final MethodChannel channel = MethodChannel(
'{{projectName}}',
const StandardMethodCodec(),
- registrar.messenger,
+ registrar,
);
final pluginInstance = {{pluginDartClass}}Web();
diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart
index dac00f9..3547d2d 100644
--- a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart
+++ b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart
@@ -83,7 +83,7 @@
// Plugins
expect(generated, contains("import 'package:foo/generated_plugin_registrant.dart';"));
- expect(generated, contains('registerPlugins(webPluginRegistry);'));
+ expect(generated, contains('registerPlugins(webPluginRegistrar);'));
// Main
expect(generated, contains('entrypoint.main();'));
@@ -185,7 +185,7 @@
// Plugins
expect(generated, contains("import 'package:foo/generated_plugin_registrant.dart';"));
- expect(generated, contains('registerPlugins(webPluginRegistry);'));
+ expect(generated, contains('registerPlugins(webPluginRegistrar);'));
// Main
expect(generated, contains('entrypoint.main();'));
@@ -208,7 +208,7 @@
// Plugins
expect(generated, isNot(contains("import 'package:foo/generated_plugin_registrant.dart';")));
- expect(generated, isNot(contains('registerPlugins(webPluginRegistry);')));
+ expect(generated, isNot(contains('registerPlugins(webPluginRegistrar);')));
// Main
expect(generated, contains('entrypoint.main();'));
}));
@@ -253,7 +253,7 @@
// Plugins
expect(generated, isNot(contains("import 'package:foo/generated_plugin_registrant.dart';")));
- expect(generated, isNot(contains('registerPlugins(webPluginRegistry);')));
+ expect(generated, isNot(contains('registerPlugins(webPluginRegistrar);')));
// Main
expect(generated, contains('entrypoint.main();'));
diff --git a/packages/flutter_web_plugins/lib/flutter_web_plugins.dart b/packages/flutter_web_plugins/lib/flutter_web_plugins.dart
index 53a19bd..97a079d 100644
--- a/packages/flutter_web_plugins/lib/flutter_web_plugins.dart
+++ b/packages/flutter_web_plugins/lib/flutter_web_plugins.dart
@@ -15,6 +15,8 @@
/// describing how the `url_launcher` package was created using [flutter_web_plugins].
library flutter_web_plugins;
+export 'src/navigation/js_url_strategy.dart';
export 'src/navigation/url_strategy.dart';
+export 'src/navigation/utils.dart';
export 'src/plugin_event_channel.dart';
export 'src/plugin_registry.dart';
diff --git a/packages/flutter_web_plugins/lib/src/navigation/utils.dart b/packages/flutter_web_plugins/lib/src/navigation/utils.dart
index a1250cd..7cf7081 100644
--- a/packages/flutter_web_plugins/lib/src/navigation/utils.dart
+++ b/packages/flutter_web_plugins/lib/src/navigation/utils.dart
@@ -4,7 +4,6 @@
import 'dart:html';
-// TODO(mdebbar): Use the `URI` class instead?
final AnchorElement _urlParsingNode = AnchorElement();
/// Extracts the pathname part of a full [url].
diff --git a/packages/flutter_web_plugins/lib/src/plugin_registry.dart b/packages/flutter_web_plugins/lib/src/plugin_registry.dart
index ada8aae..c7e20b6 100644
--- a/packages/flutter_web_plugins/lib/src/plugin_registry.dart
+++ b/packages/flutter_web_plugins/lib/src/plugin_registry.dart
@@ -8,34 +8,54 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
-// TODO(hterkelsen): Why is this _MessageHandler duplicated here?
-typedef _MessageHandler = Future<ByteData?>? Function(ByteData?);
-
-/// This class registers web platform plugins.
+/// A registrar for Flutter plugins implemented in Dart.
///
-/// An instance of this class is available as [webPluginRegistry].
-class PluginRegistry {
- /// Creates a plugin registry.
+/// Plugins for the web platform are implemented in Dart and are
+/// registered with this class by code generated by the `flutter` tool
+/// when compiling the application.
+///
+/// This class implements [BinaryMessenger] to route messages from the
+/// framework to registered plugins.
+///
+/// Use this [BinaryMessenger] when creating platform channels in order for
+/// them to receive messages from the platform side. For example:
+///
+/// ```dart
+/// class MyPlugin {
+/// static void registerWith(Registrar registrar) {
+/// final MethodChannel channel = MethodChannel(
+/// 'com.my_plugin/my_plugin',
+/// const StandardMethodCodec(),
+/// registrar, // the registrar is used as the BinaryMessenger
+/// );
+/// final MyPlugin instance = MyPlugin();
+/// channel.setMethodCallHandler(instance.handleMethodCall);
+/// }
+/// // ...
+/// }
+/// ```
+class Registrar extends BinaryMessenger {
+ /// Creates a [Registrar].
///
- /// The argument selects the [BinaryMessenger] to use. An
- /// appropriate value would be [pluginBinaryMessenger].
- PluginRegistry(this._binaryMessenger);
+ /// The argument is ignored. To create a test [Registrar] with custom behavior,
+ /// subclass the [Registrar] class and override methods as appropriate.
+ Registrar([
+ @Deprecated(
+ 'This argument is ignored. '
+ 'This feature was deprecated after v1.24.0-7.0.pre.'
+ )
+ BinaryMessenger? binaryMessenger,
+ ]);
- final BinaryMessenger _binaryMessenger;
-
- /// Creates a registrar for the given plugin implementation class.
- Registrar registrarFor(Type key) => Registrar(_binaryMessenger);
-
- /// Registers this plugin handler with the engine, so that unrecognized
- /// platform messages are forwarded to the registry, where they can be
- /// correctly dispatched to one of the registered plugins.
+ /// Registers the registrar's message handler
+ /// ([handlePlatformMessage]) with the engine, so that plugin
+ /// messages are correctly dispatched to the relevant registered
+ /// plugin.
///
- /// Code generated by the `flutter` tool automatically calls this method
- /// for the global [webPluginRegistry] at startup.
- ///
- /// Only one [PluginRegistry] can be registered at a time. Calling this
- /// method a second time silently unregisters the first [PluginRegistry]
- /// and replaces it with the new one.
+ /// Only one handler can be registered at a time. Calling this
+ /// method a second time silently unregisters any
+ /// previously-registered handler and replaces it with the handler
+ /// from this object.
///
/// This method uses a function called `webOnlySetPluginHandler` in
/// the [dart:ui] library. That function is only available when
@@ -43,61 +63,50 @@
void registerMessageHandler() {
// The function below is only defined in the Web dart:ui.
// ignore: undefined_function
- ui.webOnlySetPluginHandler(_binaryMessenger.handlePlatformMessage);
+ ui.webOnlySetPluginHandler(handleFrameworkMessage);
}
-}
-
-/// A registrar for a particular plugin.
-///
-/// Gives access to a [BinaryMessenger] which has been configured to receive
-/// platform messages from the framework side.
-class Registrar {
- /// Creates a registrar with the given [BinaryMessenger].
- Registrar(this.messenger);
-
- /// A [BinaryMessenger] configured to receive platform messages from the
- /// framework side.
- ///
- /// Use this [BinaryMessenger] when creating platform channels in order for
- /// them to receive messages from the platform side. For example:
- ///
- /// ```dart
- /// class MyPlugin {
- /// static void registerWith(Registrar registrar) {
- /// final MethodChannel channel = MethodChannel(
- /// 'com.my_plugin/my_plugin',
- /// const StandardMethodCodec(),
- /// registrar.messenger,
- /// );
- /// final MyPlugin instance = MyPlugin();
- /// channel.setMethodCallHandler(instance.handleMethodCall);
- /// }
- /// // ...
- /// }
- /// ```
- final BinaryMessenger messenger;
-}
-
-/// The default plugin registry for the web.
-///
-/// Uses [pluginBinaryMessenger] as the [BinaryMessenger].
-final PluginRegistry webPluginRegistry = PluginRegistry(pluginBinaryMessenger);
-
-/// A [BinaryMessenger] which does the inverse of the default framework
-/// messenger.
-///
-/// Instead of sending messages from the framework to the engine, this
-/// receives messages from the framework and dispatches them to registered
-/// plugins.
-class _PlatformBinaryMessenger extends BinaryMessenger {
- final Map<String, _MessageHandler> _handlers = <String, _MessageHandler>{};
/// Receives a platform message from the framework.
+ ///
+ /// This method has been replaced with the more clearly-named [handleFrameworkMessage].
+ @Deprecated(
+ 'Use handleFrameworkMessage instead. '
+ 'This feature was deprecated after v1.24.0-7.0.pre.'
+ )
@override
Future<void> handlePlatformMessage(
String channel,
ByteData? data,
ui.PlatformMessageResponseCallback? callback,
+ ) => handleFrameworkMessage(channel, data, callback);
+
+ /// Message handler for web plugins.
+ ///
+ /// This method is called when handling messages from the framework.
+ ///
+ /// If a handler has been registered for the given `channel`, it is
+ /// invoked, and the value it returns is passed to `callback` (if that
+ /// is non-null). Then, the method's future is completed.
+ ///
+ /// If no handler has been registered for that channel, then the
+ /// callback (if any) is invoked with null, then the method's future
+ /// is completed.
+ ///
+ /// Messages are not buffered (unlike platform messages headed to
+ /// the framework, which are managed by [ChannelBuffers]).
+ ///
+ /// This method is registered as the message handler by code
+ /// autogenerated by the `flutter` tool when the application is
+ /// compiled, if any web plugins are used. The code in question is
+ /// the following:
+ ///
+ /// ```dart
+ /// ui.webOnlySetPluginHandler(webPluginRegistrar.handleFrameworkMessage);
+ /// ```
+ Future<void> handleFrameworkMessage(
+ String channel,
+ ByteData? data,
+ ui.PlatformMessageResponseCallback? callback,
) async {
ByteData? response;
try {
@@ -119,6 +128,15 @@
}
}
+ /// Returns `this`.
+ @Deprecated(
+ 'This property is redundant. It returns the object on which it is called. '
+ 'This feature was deprecated after v1.24.0-7.0.pre.'
+ )
+ BinaryMessenger get messenger => this;
+
+ final Map<String, MessageHandler> _handlers = <String, MessageHandler>{};
+
/// Sends a platform message from the platform side back to the framework.
@override
Future<ByteData?> send(String channel, ByteData? message) {
@@ -167,8 +185,45 @@
}
}
-/// The default [BinaryMessenger] for Flutter web plugins.
-///
-/// This is the value used for [webPluginRegistry]'s [PluginRegistry]
-/// constructor argument.
-final BinaryMessenger pluginBinaryMessenger = _PlatformBinaryMessenger();
+/// This class was previously separate from [Registrar] but was merged into it
+/// as part of a simplification of the web plugins API.
+@Deprecated(
+ 'Use Registrar instead. '
+ 'This feature was deprecated after v1.24.0-7.0.pre.'
+)
+class PluginRegistry extends Registrar {
+ /// Creates a [Registrar].
+ ///
+ /// The argument is ignored.
+ PluginRegistry([
+ @Deprecated(
+ 'This argument is ignored. '
+ 'This feature was deprecated after v1.24.0-7.0.pre.'
+ )
+ BinaryMessenger? binaryMessenger,
+ ]) : super(); // ignore: avoid_unused_constructor_parameters
+
+ /// Returns `this`. The argument is ignored.
+ @Deprecated(
+ 'This method is redundant. It returns the object on which it is called. '
+ 'This feature was deprecated after v1.24.0-7.0.pre.'
+ )
+ Registrar registrarFor(Type key) => this;
+}
+
+/// The default plugin registrar for the web.
+final Registrar webPluginRegistrar = PluginRegistry();
+
+/// A deprecated alias for [webPluginRegistrar].
+@Deprecated(
+ 'Use webPluginRegistrar instead. '
+ 'This feature was deprecated after v1.24.0-7.0.pre.'
+)
+PluginRegistry get webPluginRegistry => webPluginRegistrar as PluginRegistry;
+
+/// A deprecated alias for [webPluginRegistrar].
+@Deprecated(
+ 'Use webPluginRegistrar instead. '
+ 'This feature was deprecated after v1.24.0-7.0.pre.'
+)
+BinaryMessenger get pluginBinaryMessenger => webPluginRegistrar;