| // Copyright 2014 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 'dart:ui' as ui; | |
| import 'package:flutter/foundation.dart'; | |
| import 'package:flutter/services.dart'; | |
| /// A registrar for Flutter plugins implemented in Dart. | |
| /// | |
| /// 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 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, | |
| ]); | |
| /// Registers the registrar's message handler | |
| /// ([handlePlatformMessage]) with the engine, so that plugin | |
| /// messages are correctly dispatched to the relevant registered | |
| /// plugin. | |
| /// | |
| /// 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 | |
| /// compiling for the web. | |
| void registerMessageHandler() { | |
| // The `ui.webOnlySetPluginHandler` function below is only defined in the Web dart:ui. | |
| // ignore: undefined_function, avoid_dynamic_calls | |
| ui.webOnlySetPluginHandler(handleFrameworkMessage); | |
| } | |
| /// 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 { | |
| final MessageHandler? handler = _handlers[channel]; | |
| if (handler != null) { | |
| response = await handler(data); | |
| } | |
| } catch (exception, stack) { | |
| FlutterError.reportError(FlutterErrorDetails( | |
| exception: exception, | |
| stack: stack, | |
| library: 'flutter web plugins', | |
| context: ErrorDescription('during a framework-to-plugin message'), | |
| )); | |
| } finally { | |
| if (callback != null) { | |
| callback(response); | |
| } | |
| } | |
| } | |
| /// 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) { | |
| final Completer<ByteData?> completer = Completer<ByteData?>(); | |
| ui.channelBuffers.push(channel, message, (ByteData? reply) { | |
| try { | |
| completer.complete(reply); | |
| } catch (exception, stack) { | |
| FlutterError.reportError(FlutterErrorDetails( | |
| exception: exception, | |
| stack: stack, | |
| library: 'flutter web plugins', | |
| context: ErrorDescription('during a plugin-to-framework message'), | |
| )); | |
| } | |
| }); | |
| return completer.future; | |
| } | |
| @override | |
| void setMessageHandler(String channel, MessageHandler? handler) { | |
| if (handler == null) { | |
| _handlers.remove(channel); | |
| } else { | |
| _handlers[channel] = handler; | |
| } | |
| } | |
| } | |
| /// 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.26.0-18.0.pre.' | |
| ) | |
| class PluginRegistry extends Registrar { | |
| /// Creates a [Registrar]. | |
| /// | |
| /// The argument is ignored. | |
| @Deprecated( | |
| 'Use Registrar instead. ' | |
| 'This feature was deprecated after v1.26.0-18.0.pre.' | |
| ) | |
| PluginRegistry([ | |
| @Deprecated( | |
| 'This argument is ignored. ' | |
| 'This feature was deprecated after v1.26.0-18.0.pre.' | |
| ) | |
| BinaryMessenger? binaryMessenger, | |
| ]) : super(); | |
| /// 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.26.0-18.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; |