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;