| // 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; |