mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Add binaryMessenger constructor argument to platform channels (#30406)
* Deprecates `BinaryMessages` in favor of a default instance of `BinaryMessenger`, called `defaultBinaryMessenger` * Platform channels use the `defaultBinaryMessenger` for their binaryMessenger default argument.
This commit is contained in:
parent
faec4ca361
commit
13e9bfcc94
@ -11,6 +11,6 @@ void main() {
|
|||||||
Ticker((Duration duration) { })..start();
|
Ticker((Duration duration) { })..start();
|
||||||
|
|
||||||
final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) {});
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) {});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
library services;
|
library services;
|
||||||
|
|
||||||
export 'src/services/asset_bundle.dart';
|
export 'src/services/asset_bundle.dart';
|
||||||
|
export 'src/services/binary_messenger.dart';
|
||||||
export 'src/services/binding.dart';
|
export 'src/services/binding.dart';
|
||||||
export 'src/services/clipboard.dart';
|
export 'src/services/clipboard.dart';
|
||||||
export 'src/services/font_loader.dart';
|
export 'src/services/font_loader.dart';
|
||||||
|
@ -9,7 +9,7 @@ import 'dart:typed_data';
|
|||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
import 'platform_messages.dart';
|
import 'binary_messenger.dart';
|
||||||
|
|
||||||
/// A collection of resources used by the application.
|
/// A collection of resources used by the application.
|
||||||
///
|
///
|
||||||
@ -216,7 +216,7 @@ class PlatformAssetBundle extends CachingAssetBundle {
|
|||||||
Future<ByteData> load(String key) async {
|
Future<ByteData> load(String key) async {
|
||||||
final Uint8List encoded = utf8.encoder.convert(Uri(path: Uri.encodeFull(key)).path);
|
final Uint8List encoded = utf8.encoder.convert(Uri(path: Uri.encodeFull(key)).path);
|
||||||
final ByteData asset =
|
final ByteData asset =
|
||||||
await BinaryMessages.send('flutter/assets', encoded.buffer.asByteData());
|
await defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData());
|
||||||
if (asset == null)
|
if (asset == null)
|
||||||
throw FlutterError('Unable to load asset: $key');
|
throw FlutterError('Unable to load asset: $key');
|
||||||
return asset;
|
return asset;
|
||||||
|
154
packages/flutter/lib/src/services/binary_messenger.dart
Normal file
154
packages/flutter/lib/src/services/binary_messenger.dart
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
// Copyright 2017 The Chromium 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:typed_data';
|
||||||
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
/// A function which takes a platform message and asynchronously returns an encoded response.
|
||||||
|
typedef MessageHandler = Future<ByteData> Function(ByteData message);
|
||||||
|
|
||||||
|
/// A messenger which sends binary data across the Flutter platform barrier.
|
||||||
|
///
|
||||||
|
/// This class also registers handlers for incoming messages.
|
||||||
|
abstract class BinaryMessenger {
|
||||||
|
/// A const constructor to allow subclasses to be const.
|
||||||
|
const BinaryMessenger();
|
||||||
|
|
||||||
|
/// Calls the handler registered for the given channel.
|
||||||
|
///
|
||||||
|
/// Typically called by [ServicesBinding] to handle platform messages received
|
||||||
|
/// from [Window.onPlatformMessage].
|
||||||
|
///
|
||||||
|
/// To register a handler for a given message channel, see [setMessageHandler].
|
||||||
|
Future<void> handlePlatformMessage(String channel, ByteData data, ui.PlatformMessageResponseCallback callback);
|
||||||
|
|
||||||
|
/// Send a binary message to the platform plugins on the given channel.
|
||||||
|
///
|
||||||
|
/// Returns a [Future] which completes to the received response, undecoded,
|
||||||
|
/// in binary form.
|
||||||
|
Future<ByteData> send(String channel, ByteData message);
|
||||||
|
|
||||||
|
/// Set a callback for receiving messages from the platform plugins on the
|
||||||
|
/// given channel, without decoding them.
|
||||||
|
///
|
||||||
|
/// The given callback will replace the currently registered callback for that
|
||||||
|
/// channel, if any. To remove the handler, pass null as the [handler]
|
||||||
|
/// argument.
|
||||||
|
///
|
||||||
|
/// The handler's return value, if non-null, is sent as a response, unencoded.
|
||||||
|
void setMessageHandler(String channel, Future<ByteData> handler(ByteData message));
|
||||||
|
|
||||||
|
/// Set a mock callback for intercepting messages from the [send] method on
|
||||||
|
/// this class, on the given channel, without decoding them.
|
||||||
|
///
|
||||||
|
/// The given callback will replace the currently registered mock callback for
|
||||||
|
/// that channel, if any. To remove the mock handler, pass null as the
|
||||||
|
/// [handler] argument.
|
||||||
|
///
|
||||||
|
/// The handler's return value, if non-null, is used as a response, unencoded.
|
||||||
|
///
|
||||||
|
/// This is intended for testing. Messages intercepted in this manner are not
|
||||||
|
/// sent to platform plugins.
|
||||||
|
void setMockMessageHandler(String channel, Future<ByteData> handler(ByteData message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The default implementation of [BinaryMessenger].
|
||||||
|
///
|
||||||
|
/// This messenger sends messages from the app-side to the platform-side and
|
||||||
|
/// dispatches incoming messages from the platform-side to the appropriate
|
||||||
|
/// handler.
|
||||||
|
class _DefaultBinaryMessenger extends BinaryMessenger {
|
||||||
|
const _DefaultBinaryMessenger._();
|
||||||
|
|
||||||
|
// Handlers for incoming messages from platform plugins.
|
||||||
|
// This is static so that this class can have a const constructor.
|
||||||
|
static final Map<String, MessageHandler> _handlers =
|
||||||
|
<String, MessageHandler>{};
|
||||||
|
|
||||||
|
// Mock handlers that intercept and respond to outgoing messages.
|
||||||
|
// This is static so that this class can have a const constructor.
|
||||||
|
static final Map<String, MessageHandler> _mockHandlers =
|
||||||
|
<String, MessageHandler>{};
|
||||||
|
|
||||||
|
Future<ByteData> _sendPlatformMessage(String channel, ByteData message) {
|
||||||
|
final Completer<ByteData> completer = Completer<ByteData>();
|
||||||
|
// ui.window is accessed directly instead of using ServicesBinding.instance.window
|
||||||
|
// because this method might be invoked before any binding is initialized.
|
||||||
|
// This issue was reported in #27541. It is not ideal to statically access
|
||||||
|
// ui.window because the Window may be dependency injected elsewhere with
|
||||||
|
// a different instance. However, static access at this location seems to be
|
||||||
|
// the least bad option.
|
||||||
|
ui.window.sendPlatformMessage(channel, message, (ByteData reply) {
|
||||||
|
try {
|
||||||
|
completer.complete(reply);
|
||||||
|
} catch (exception, stack) {
|
||||||
|
FlutterError.reportError(FlutterErrorDetails(
|
||||||
|
exception: exception,
|
||||||
|
stack: stack,
|
||||||
|
library: 'services library',
|
||||||
|
context: ErrorDescription('during a platform message response callback'),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return completer.future;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> handlePlatformMessage(
|
||||||
|
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: 'services library',
|
||||||
|
context: ErrorDescription('during a platform message callback'),
|
||||||
|
));
|
||||||
|
} finally {
|
||||||
|
callback(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<ByteData> send(String channel, ByteData message) {
|
||||||
|
final MessageHandler handler = _mockHandlers[channel];
|
||||||
|
if (handler != null)
|
||||||
|
return handler(message);
|
||||||
|
return _sendPlatformMessage(channel, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void setMessageHandler(String channel, MessageHandler handler) {
|
||||||
|
if (handler == null)
|
||||||
|
_handlers.remove(channel);
|
||||||
|
else
|
||||||
|
_handlers[channel] = handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void setMockMessageHandler(String channel, MessageHandler handler) {
|
||||||
|
if (handler == null)
|
||||||
|
_mockHandlers.remove(channel);
|
||||||
|
else
|
||||||
|
_mockHandlers[channel] = handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The default instance of [BinaryMessenger].
|
||||||
|
///
|
||||||
|
/// This is used to send messages from the application to the platform, and
|
||||||
|
/// keeps track of which handlers have been registered on each channel so
|
||||||
|
/// it may dispatch incoming messages to the registered handler.
|
||||||
|
const BinaryMessenger defaultBinaryMessenger = _DefaultBinaryMessenger._();
|
@ -7,9 +7,9 @@ import 'dart:async';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
import 'asset_bundle.dart';
|
import 'asset_bundle.dart';
|
||||||
import 'platform_messages.dart';
|
import 'binary_messenger.dart';
|
||||||
|
|
||||||
/// Listens for platform messages and directs them to [BinaryMessages].
|
/// Listens for platform messages and directs them to the [defaultBinaryMessenger].
|
||||||
///
|
///
|
||||||
/// The [ServicesBinding] also registers a [LicenseEntryCollector] that exposes
|
/// The [ServicesBinding] also registers a [LicenseEntryCollector] that exposes
|
||||||
/// the licenses found in the `LICENSE` file stored at the root of the asset
|
/// the licenses found in the `LICENSE` file stored at the root of the asset
|
||||||
@ -21,7 +21,7 @@ mixin ServicesBinding on BindingBase {
|
|||||||
super.initInstances();
|
super.initInstances();
|
||||||
_instance = this;
|
_instance = this;
|
||||||
window
|
window
|
||||||
..onPlatformMessage = BinaryMessages.handlePlatformMessage;
|
..onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage;
|
||||||
initLicenses();
|
initLicenses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,9 +7,9 @@ import 'dart:typed_data';
|
|||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
import 'binary_messenger.dart';
|
||||||
import 'message_codec.dart';
|
import 'message_codec.dart';
|
||||||
import 'message_codecs.dart';
|
import 'message_codecs.dart';
|
||||||
import 'platform_messages.dart';
|
|
||||||
|
|
||||||
/// A named channel for communicating with platform plugins using asynchronous
|
/// A named channel for communicating with platform plugins using asynchronous
|
||||||
/// message passing.
|
/// message passing.
|
||||||
@ -29,10 +29,13 @@ import 'platform_messages.dart';
|
|||||||
///
|
///
|
||||||
/// See: <https://flutter.dev/platform-channels/>
|
/// See: <https://flutter.dev/platform-channels/>
|
||||||
class BasicMessageChannel<T> {
|
class BasicMessageChannel<T> {
|
||||||
/// Creates a [BasicMessageChannel] with the specified [name] and [codec].
|
/// Creates a [BasicMessageChannel] with the specified [name], [codec] and [binaryMessenger].
|
||||||
///
|
///
|
||||||
/// Neither [name] nor [codec] may be null.
|
/// None of [name], [codec], or [binaryMessenger] may be null.
|
||||||
const BasicMessageChannel(this.name, this.codec);
|
const BasicMessageChannel(this.name, this.codec, { this.binaryMessenger = defaultBinaryMessenger })
|
||||||
|
: assert(name != null),
|
||||||
|
assert(codec != null),
|
||||||
|
assert(binaryMessenger != null);
|
||||||
|
|
||||||
/// The logical channel on which communication happens, not null.
|
/// The logical channel on which communication happens, not null.
|
||||||
final String name;
|
final String name;
|
||||||
@ -40,12 +43,15 @@ class BasicMessageChannel<T> {
|
|||||||
/// The message codec used by this channel, not null.
|
/// The message codec used by this channel, not null.
|
||||||
final MessageCodec<T> codec;
|
final MessageCodec<T> codec;
|
||||||
|
|
||||||
|
/// The messenger which sends the bytes for this channel, not null.
|
||||||
|
final BinaryMessenger binaryMessenger;
|
||||||
|
|
||||||
/// Sends the specified [message] to the platform plugins on this channel.
|
/// Sends the specified [message] to the platform plugins on this channel.
|
||||||
///
|
///
|
||||||
/// Returns a [Future] which completes to the received response, which may
|
/// Returns a [Future] which completes to the received response, which may
|
||||||
/// be null.
|
/// be null.
|
||||||
Future<T> send(T message) async {
|
Future<T> send(T message) async {
|
||||||
return codec.decodeMessage(await BinaryMessages.send(name, codec.encodeMessage(message)));
|
return codec.decodeMessage(await binaryMessenger.send(name, codec.encodeMessage(message)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets a callback for receiving messages from the platform plugins on this
|
/// Sets a callback for receiving messages from the platform plugins on this
|
||||||
@ -59,9 +65,9 @@ class BasicMessageChannel<T> {
|
|||||||
/// message reply. It may be null.
|
/// message reply. It may be null.
|
||||||
void setMessageHandler(Future<T> handler(T message)) {
|
void setMessageHandler(Future<T> handler(T message)) {
|
||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
BinaryMessages.setMessageHandler(name, null);
|
binaryMessenger.setMessageHandler(name, null);
|
||||||
} else {
|
} else {
|
||||||
BinaryMessages.setMessageHandler(name, (ByteData message) async {
|
binaryMessenger.setMessageHandler(name, (ByteData message) async {
|
||||||
return codec.encodeMessage(await handler(codec.decodeMessage(message)));
|
return codec.encodeMessage(await handler(codec.decodeMessage(message)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -80,9 +86,9 @@ class BasicMessageChannel<T> {
|
|||||||
/// sent to platform plugins.
|
/// sent to platform plugins.
|
||||||
void setMockMessageHandler(Future<T> handler(T message)) {
|
void setMockMessageHandler(Future<T> handler(T message)) {
|
||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
BinaryMessages.setMockMessageHandler(name, null);
|
binaryMessenger.setMockMessageHandler(name, null);
|
||||||
} else {
|
} else {
|
||||||
BinaryMessages.setMockMessageHandler(name, (ByteData message) async {
|
binaryMessenger.setMockMessageHandler(name, (ByteData message) async {
|
||||||
return codec.encodeMessage(await handler(codec.decodeMessage(message)));
|
return codec.encodeMessage(await handler(codec.decodeMessage(message)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -112,8 +118,11 @@ class MethodChannel {
|
|||||||
/// The [codec] used will be [StandardMethodCodec], unless otherwise
|
/// The [codec] used will be [StandardMethodCodec], unless otherwise
|
||||||
/// specified.
|
/// specified.
|
||||||
///
|
///
|
||||||
/// Neither [name] nor [codec] may be null.
|
/// None of [name], [binaryMessenger], or [codec] may be null.
|
||||||
const MethodChannel(this.name, [this.codec = const StandardMethodCodec()]);
|
const MethodChannel(this.name, [this.codec = const StandardMethodCodec(), this.binaryMessenger = defaultBinaryMessenger ])
|
||||||
|
: assert(name != null),
|
||||||
|
assert(binaryMessenger != null),
|
||||||
|
assert(codec != null);
|
||||||
|
|
||||||
/// The logical channel on which communication happens, not null.
|
/// The logical channel on which communication happens, not null.
|
||||||
final String name;
|
final String name;
|
||||||
@ -121,6 +130,11 @@ class MethodChannel {
|
|||||||
/// The message codec used by this channel, not null.
|
/// The message codec used by this channel, not null.
|
||||||
final MethodCodec codec;
|
final MethodCodec codec;
|
||||||
|
|
||||||
|
/// The messenger used by this channel to send platform messages.
|
||||||
|
///
|
||||||
|
/// The messenger may not be null.
|
||||||
|
final BinaryMessenger binaryMessenger;
|
||||||
|
|
||||||
/// Invokes a [method] on this channel with the specified [arguments].
|
/// Invokes a [method] on this channel with the specified [arguments].
|
||||||
///
|
///
|
||||||
/// The static type of [arguments] is `dynamic`, but only values supported by
|
/// The static type of [arguments] is `dynamic`, but only values supported by
|
||||||
@ -287,12 +301,12 @@ class MethodChannel {
|
|||||||
/// [StandardMethodCodec].
|
/// [StandardMethodCodec].
|
||||||
/// * [JSONMessageCodec] which defines the payload values supported by
|
/// * [JSONMessageCodec] which defines the payload values supported by
|
||||||
/// [JSONMethodCodec].
|
/// [JSONMethodCodec].
|
||||||
/// * <https://docs.flutter.io/javadoc/io/flutter/plugin/common/MethodCall.html>
|
/// * <https://api.flutter.dev/javadoc/io/flutter/plugin/common/MethodCall.html>
|
||||||
/// for how to access method call arguments on Android.
|
/// for how to access method call arguments on Android.
|
||||||
@optionalTypeArgs
|
@optionalTypeArgs
|
||||||
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
|
Future<T> invokeMethod<T>(String method, [ dynamic arguments ]) async {
|
||||||
assert(method != null);
|
assert(method != null);
|
||||||
final ByteData result = await BinaryMessages.send(
|
final ByteData result = await binaryMessenger.send(
|
||||||
name,
|
name,
|
||||||
codec.encodeMethodCall(MethodCall(method, arguments)),
|
codec.encodeMethodCall(MethodCall(method, arguments)),
|
||||||
);
|
);
|
||||||
@ -346,7 +360,7 @@ class MethodChannel {
|
|||||||
/// similarly to what happens if no method call handler has been set.
|
/// similarly to what happens if no method call handler has been set.
|
||||||
/// Any other exception results in an error envelope being sent.
|
/// Any other exception results in an error envelope being sent.
|
||||||
void setMethodCallHandler(Future<dynamic> handler(MethodCall call)) {
|
void setMethodCallHandler(Future<dynamic> handler(MethodCall call)) {
|
||||||
BinaryMessages.setMessageHandler(
|
binaryMessenger.setMessageHandler(
|
||||||
name,
|
name,
|
||||||
handler == null ? null : (ByteData message) => _handleAsMethodCall(message, handler),
|
handler == null ? null : (ByteData message) => _handleAsMethodCall(message, handler),
|
||||||
);
|
);
|
||||||
@ -371,7 +385,7 @@ class MethodChannel {
|
|||||||
/// [MethodCodec.encodeSuccessEnvelope], to act as if platform plugin had
|
/// [MethodCodec.encodeSuccessEnvelope], to act as if platform plugin had
|
||||||
/// returned that value.
|
/// returned that value.
|
||||||
void setMockMethodCallHandler(Future<dynamic> handler(MethodCall call)) {
|
void setMockMethodCallHandler(Future<dynamic> handler(MethodCall call)) {
|
||||||
BinaryMessages.setMockMessageHandler(
|
binaryMessenger.setMockMessageHandler(
|
||||||
name,
|
name,
|
||||||
handler == null ? null : (ByteData message) => _handleAsMethodCall(message, handler),
|
handler == null ? null : (ByteData message) => _handleAsMethodCall(message, handler),
|
||||||
);
|
);
|
||||||
@ -474,7 +488,7 @@ class EventChannel {
|
|||||||
final MethodChannel methodChannel = MethodChannel(name, codec);
|
final MethodChannel methodChannel = MethodChannel(name, codec);
|
||||||
StreamController<dynamic> controller;
|
StreamController<dynamic> controller;
|
||||||
controller = StreamController<dynamic>.broadcast(onListen: () async {
|
controller = StreamController<dynamic>.broadcast(onListen: () async {
|
||||||
BinaryMessages.setMessageHandler(name, (ByteData reply) async {
|
defaultBinaryMessenger.setMessageHandler(name, (ByteData reply) async {
|
||||||
if (reply == null) {
|
if (reply == null) {
|
||||||
controller.close();
|
controller.close();
|
||||||
} else {
|
} else {
|
||||||
@ -497,7 +511,7 @@ class EventChannel {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}, onCancel: () async {
|
}, onCancel: () async {
|
||||||
BinaryMessages.setMessageHandler(name, null);
|
defaultBinaryMessenger.setMessageHandler(name, null);
|
||||||
try {
|
try {
|
||||||
await methodChannel.invokeMethod<void>('cancel', arguments);
|
await methodChannel.invokeMethod<void>('cancel', arguments);
|
||||||
} catch (exception, stack) {
|
} catch (exception, stack) {
|
||||||
|
@ -6,17 +6,18 @@ import 'dart:async';
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
import 'dart:ui' as ui;
|
import 'dart:ui' as ui;
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'binary_messenger.dart';
|
||||||
|
|
||||||
import 'binding.dart' show ServicesBinding;
|
import 'binding.dart' show ServicesBinding;
|
||||||
import 'platform_channel.dart';
|
import 'platform_channel.dart';
|
||||||
|
|
||||||
typedef _MessageHandler = Future<ByteData> Function(ByteData message);
|
|
||||||
|
|
||||||
/// Sends binary messages to and receives binary messages from platform plugins.
|
/// Sends binary messages to and receives binary messages from platform plugins.
|
||||||
///
|
///
|
||||||
|
/// This class has been deprecated in favor of [defaultBinaryMessenger]. New
|
||||||
|
/// code should not use [BinaryMessages].
|
||||||
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
|
/// * [BinaryMessenger], the interface which has replaced this class.
|
||||||
/// * [BasicMessageChannel], which provides basic messaging services similar to
|
/// * [BasicMessageChannel], which provides basic messaging services similar to
|
||||||
/// `BinaryMessages`, but with pluggable message codecs in support of sending
|
/// `BinaryMessages`, but with pluggable message codecs in support of sending
|
||||||
/// strings or semi-structured messages.
|
/// strings or semi-structured messages.
|
||||||
@ -24,77 +25,34 @@ typedef _MessageHandler = Future<ByteData> Function(ByteData message);
|
|||||||
/// method calls.
|
/// method calls.
|
||||||
/// * [EventChannel], which provides platform communication using event streams.
|
/// * [EventChannel], which provides platform communication using event streams.
|
||||||
/// * <https://flutter.dev/platform-channels/>
|
/// * <https://flutter.dev/platform-channels/>
|
||||||
|
@Deprecated('This class, which was just a collection of static methods, has been '
|
||||||
|
'deprecated in favor of BinaryMessenger, and its default '
|
||||||
|
'implementation, defaultBinaryMessenger.')
|
||||||
class BinaryMessages {
|
class BinaryMessages {
|
||||||
BinaryMessages._();
|
BinaryMessages._();
|
||||||
|
|
||||||
// Handlers for incoming messages from platform plugins.
|
|
||||||
static final Map<String, _MessageHandler> _handlers =
|
|
||||||
<String, _MessageHandler>{};
|
|
||||||
|
|
||||||
// Mock handlers that intercept and respond to outgoing messages.
|
|
||||||
static final Map<String, _MessageHandler> _mockHandlers =
|
|
||||||
<String, _MessageHandler>{};
|
|
||||||
|
|
||||||
static Future<ByteData> _sendPlatformMessage(String channel, ByteData message) {
|
|
||||||
final Completer<ByteData> completer = Completer<ByteData>();
|
|
||||||
// ui.window is accessed directly instead of using ServicesBinding.instance.window
|
|
||||||
// because this method might be invoked before any binding is initialized.
|
|
||||||
// This issue was reported in #27541. It is not ideal to statically access
|
|
||||||
// ui.window because the Window may be dependency injected elsewhere with
|
|
||||||
// a different instance. However, static access at this location seems to be
|
|
||||||
// the least bad option.
|
|
||||||
ui.window.sendPlatformMessage(channel, message, (ByteData reply) {
|
|
||||||
try {
|
|
||||||
completer.complete(reply);
|
|
||||||
} catch (exception, stack) {
|
|
||||||
FlutterError.reportError(FlutterErrorDetails(
|
|
||||||
exception: exception,
|
|
||||||
stack: stack,
|
|
||||||
library: 'services library',
|
|
||||||
context: ErrorDescription('during a platform message response callback'),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return completer.future;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calls the handler registered for the given channel.
|
/// Calls the handler registered for the given channel.
|
||||||
///
|
///
|
||||||
/// Typically called by [ServicesBinding] to handle platform messages received
|
/// Typically called by [ServicesBinding] to handle platform messages received
|
||||||
/// from [Window.onPlatformMessage].
|
/// from [Window.onPlatformMessage].
|
||||||
///
|
///
|
||||||
/// To register a handler for a given message channel, see [setMessageHandler].
|
/// To register a handler for a given message channel, see [setMessageHandler].
|
||||||
|
@Deprecated('Use defaultBinaryMessenger.handlePlatformMessage instead.')
|
||||||
static Future<void> handlePlatformMessage(
|
static Future<void> handlePlatformMessage(
|
||||||
String channel,
|
String channel,
|
||||||
ByteData data,
|
ByteData data,
|
||||||
ui.PlatformMessageResponseCallback callback,
|
ui.PlatformMessageResponseCallback callback,
|
||||||
) async {
|
) {
|
||||||
ByteData response;
|
return defaultBinaryMessenger.handlePlatformMessage(channel, data, callback);
|
||||||
try {
|
|
||||||
final _MessageHandler handler = _handlers[channel];
|
|
||||||
if (handler != null)
|
|
||||||
response = await handler(data);
|
|
||||||
} catch (exception, stack) {
|
|
||||||
FlutterError.reportError(FlutterErrorDetails(
|
|
||||||
exception: exception,
|
|
||||||
stack: stack,
|
|
||||||
library: 'services library',
|
|
||||||
context: ErrorDescription('during a platform message callback'),
|
|
||||||
));
|
|
||||||
} finally {
|
|
||||||
callback(response);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Send a binary message to the platform plugins on the given channel.
|
/// Send a binary message to the platform plugins on the given channel.
|
||||||
///
|
///
|
||||||
/// Returns a [Future] which completes to the received response, undecoded, in
|
/// Returns a [Future] which completes to the received response, undecoded, in
|
||||||
/// binary form.
|
/// binary form.
|
||||||
|
@Deprecated('Use defaultBinaryMessenger.send instead.')
|
||||||
static Future<ByteData> send(String channel, ByteData message) {
|
static Future<ByteData> send(String channel, ByteData message) {
|
||||||
final _MessageHandler handler = _mockHandlers[channel];
|
return defaultBinaryMessenger.send(channel, message);
|
||||||
if (handler != null)
|
|
||||||
return handler(message);
|
|
||||||
return _sendPlatformMessage(channel, message);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a callback for receiving messages from the platform plugins on the
|
/// Set a callback for receiving messages from the platform plugins on the
|
||||||
@ -105,11 +63,9 @@ class BinaryMessages {
|
|||||||
/// argument.
|
/// argument.
|
||||||
///
|
///
|
||||||
/// The handler's return value, if non-null, is sent as a response, unencoded.
|
/// The handler's return value, if non-null, is sent as a response, unencoded.
|
||||||
|
@Deprecated('Use defaultBinaryMessenger.setMessageHandler instead.')
|
||||||
static void setMessageHandler(String channel, Future<ByteData> handler(ByteData message)) {
|
static void setMessageHandler(String channel, Future<ByteData> handler(ByteData message)) {
|
||||||
if (handler == null)
|
defaultBinaryMessenger.setMessageHandler(channel, handler);
|
||||||
_handlers.remove(channel);
|
|
||||||
else
|
|
||||||
_handlers[channel] = handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set a mock callback for intercepting messages from the `send*` methods on
|
/// Set a mock callback for intercepting messages from the `send*` methods on
|
||||||
@ -123,10 +79,8 @@ class BinaryMessages {
|
|||||||
///
|
///
|
||||||
/// This is intended for testing. Messages intercepted in this manner are not
|
/// This is intended for testing. Messages intercepted in this manner are not
|
||||||
/// sent to platform plugins.
|
/// sent to platform plugins.
|
||||||
|
@Deprecated('Use defaultBinaryMessenger.setMockMessageHandler instead.')
|
||||||
static void setMockMessageHandler(String channel, Future<ByteData> handler(ByteData message)) {
|
static void setMockMessageHandler(String channel, Future<ByteData> handler(ByteData message)) {
|
||||||
if (handler == null)
|
defaultBinaryMessenger.setMockMessageHandler(channel, handler);
|
||||||
_mockHandlers.remove(channel);
|
|
||||||
else
|
|
||||||
_mockHandlers[channel] = handler;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,7 +417,7 @@ void main() {
|
|||||||
bool completed;
|
bool completed;
|
||||||
|
|
||||||
completed = false;
|
completed = false;
|
||||||
BinaryMessages.setMockMessageHandler('flutter/assets', (ByteData message) async {
|
defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData message) async {
|
||||||
expect(utf8.decode(message.buffer.asUint8List()), 'test');
|
expect(utf8.decode(message.buffer.asUint8List()), 'test');
|
||||||
completed = true;
|
completed = true;
|
||||||
return ByteData(5); // 0x0000000000
|
return ByteData(5); // 0x0000000000
|
||||||
@ -436,7 +436,7 @@ void main() {
|
|||||||
data = await rootBundle.loadStructuredData<bool>('test', (String value) async { expect(value, '\x00\x00\x00\x00\x00'); return false; });
|
data = await rootBundle.loadStructuredData<bool>('test', (String value) async { expect(value, '\x00\x00\x00\x00\x00'); return false; });
|
||||||
expect(data, isFalse);
|
expect(data, isFalse);
|
||||||
expect(completed, isTrue);
|
expect(completed, isTrue);
|
||||||
BinaryMessages.setMockMessageHandler('flutter/assets', null);
|
defaultBinaryMessenger.setMockMessageHandler('flutter/assets', null);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Service extensions - exit', () async {
|
test('Service extensions - exit', () async {
|
||||||
|
@ -72,7 +72,7 @@ void main() {
|
|||||||
|
|
||||||
// Simulate system back button
|
// Simulate system back button
|
||||||
final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
|
final ByteData message = const JSONMethodCodec().encodeMethodCall(const MethodCall('popRoute'));
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/navigation', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(selectedResults, <void>[null]);
|
expect(selectedResults, <void>[null]);
|
||||||
|
@ -2957,7 +2957,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
void sendFakeKeyEvent(Map<String, dynamic> data) {
|
void sendFakeKeyEvent(Map<String, dynamic> data) {
|
||||||
BinaryMessages.handlePlatformMessage(
|
defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData data) { },
|
(ByteData data) { },
|
||||||
|
@ -129,7 +129,7 @@ void main() {
|
|||||||
expect(tickCount, equals(0));
|
expect(tickCount, equals(0));
|
||||||
|
|
||||||
final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
final ByteData message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(ticker.isTicking, isFalse);
|
expect(ticker.isTicking, isFalse);
|
||||||
expect(ticker.isActive, isTrue);
|
expect(ticker.isActive, isTrue);
|
||||||
|
|
||||||
@ -138,7 +138,7 @@ void main() {
|
|||||||
|
|
||||||
testWidgets('Ticker can be created before application unpauses', (WidgetTester tester) async {
|
testWidgets('Ticker can be created before application unpauses', (WidgetTester tester) async {
|
||||||
final ByteData pausedMessage = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
final ByteData pausedMessage = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', pausedMessage, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', pausedMessage, (_) { });
|
||||||
|
|
||||||
int tickCount = 0;
|
int tickCount = 0;
|
||||||
void handleTick(Duration duration) {
|
void handleTick(Duration duration) {
|
||||||
@ -157,7 +157,7 @@ void main() {
|
|||||||
expect(ticker.isTicking, isFalse);
|
expect(ticker.isTicking, isFalse);
|
||||||
|
|
||||||
final ByteData resumedMessage = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
final ByteData resumedMessage = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', resumedMessage, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', resumedMessage, (_) { });
|
||||||
|
|
||||||
await tester.pump(const Duration(milliseconds: 10));
|
await tester.pump(const Duration(milliseconds: 10));
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class FakeAndroidPlatformViewsController {
|
|||||||
void invokeViewFocused(int viewId) {
|
void invokeViewFocused(int viewId) {
|
||||||
final MethodCodec codec = SystemChannels.platform_views.codec;
|
final MethodCodec codec = SystemChannels.platform_views.codec;
|
||||||
final ByteData data = codec.encodeMethodCall(MethodCall('viewFocused', viewId));
|
final ByteData data = codec.encodeMethodCall(MethodCall('viewFocused', viewId));
|
||||||
BinaryMessages.handlePlatformMessage(SystemChannels.platform_views.name, data, (ByteData data) {});
|
defaultBinaryMessenger.handlePlatformMessage(SystemChannels.platform_views.name, data, (ByteData data) {});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> _onMethodCall(MethodCall call) {
|
Future<dynamic> _onMethodCall(MethodCall call) {
|
||||||
|
@ -13,7 +13,7 @@ void main() {
|
|||||||
const MessageCodec<String> string = StringCodec();
|
const MessageCodec<String> string = StringCodec();
|
||||||
const BasicMessageChannel<String> channel = BasicMessageChannel<String>('ch', string);
|
const BasicMessageChannel<String> channel = BasicMessageChannel<String>('ch', string);
|
||||||
test('can send string message and get reply', () async {
|
test('can send string message and get reply', () async {
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch',
|
'ch',
|
||||||
(ByteData message) async => string.encodeMessage(string.decodeMessage(message) + ' world'),
|
(ByteData message) async => string.encodeMessage(string.decodeMessage(message) + ' world'),
|
||||||
);
|
);
|
||||||
@ -23,7 +23,7 @@ void main() {
|
|||||||
test('can receive string message and send reply', () async {
|
test('can receive string message and send reply', () async {
|
||||||
channel.setMessageHandler((String message) async => message + ' world');
|
channel.setMessageHandler((String message) async => message + ' world');
|
||||||
String reply;
|
String reply;
|
||||||
await BinaryMessages.handlePlatformMessage(
|
await defaultBinaryMessenger.handlePlatformMessage(
|
||||||
'ch',
|
'ch',
|
||||||
const StringCodec().encodeMessage('hello'),
|
const StringCodec().encodeMessage('hello'),
|
||||||
(ByteData replyBinary) {
|
(ByteData replyBinary) {
|
||||||
@ -39,7 +39,7 @@ void main() {
|
|||||||
const MethodCodec jsonMethod = JSONMethodCodec();
|
const MethodCodec jsonMethod = JSONMethodCodec();
|
||||||
const MethodChannel channel = MethodChannel('ch7', jsonMethod);
|
const MethodChannel channel = MethodChannel('ch7', jsonMethod);
|
||||||
test('can invoke method and get result', () async {
|
test('can invoke method and get result', () async {
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData message) async {
|
(ByteData message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
||||||
@ -54,7 +54,7 @@ void main() {
|
|||||||
expect(result, equals('hello world'));
|
expect(result, equals('hello world'));
|
||||||
});
|
});
|
||||||
test('can invoke list method and get result', () async {
|
test('can invoke list method and get result', () async {
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData message) async {
|
(ByteData message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
||||||
@ -70,7 +70,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke list method and get null result', () async {
|
test('can invoke list method and get null result', () async {
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData message) async {
|
(ByteData message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
||||||
@ -86,7 +86,7 @@ void main() {
|
|||||||
|
|
||||||
|
|
||||||
test('can invoke map method and get result', () async {
|
test('can invoke map method and get result', () async {
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData message) async {
|
(ByteData message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
||||||
@ -102,7 +102,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke map method and get null result', () async {
|
test('can invoke map method and get null result', () async {
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData message) async {
|
(ByteData message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
||||||
@ -117,7 +117,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('can invoke method and get error', () async {
|
test('can invoke method and get error', () async {
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData message) async {
|
(ByteData message) async {
|
||||||
return jsonMessage.encodeMessage(<dynamic>[
|
return jsonMessage.encodeMessage(<dynamic>[
|
||||||
@ -139,7 +139,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
test('can invoke unimplemented method', () async {
|
test('can invoke unimplemented method', () async {
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch7',
|
'ch7',
|
||||||
(ByteData message) async => null,
|
(ByteData message) async => null,
|
||||||
);
|
);
|
||||||
@ -157,7 +157,7 @@ void main() {
|
|||||||
channel.setMethodCallHandler(null);
|
channel.setMethodCallHandler(null);
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData envelope;
|
ByteData envelope;
|
||||||
await BinaryMessages.handlePlatformMessage('ch7', call, (ByteData result) {
|
await defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
expect(envelope, isNull);
|
expect(envelope, isNull);
|
||||||
@ -168,7 +168,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData envelope;
|
ByteData envelope;
|
||||||
await BinaryMessages.handlePlatformMessage('ch7', call, (ByteData result) {
|
await defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
expect(envelope, isNull);
|
expect(envelope, isNull);
|
||||||
@ -177,7 +177,7 @@ void main() {
|
|||||||
channel.setMethodCallHandler((MethodCall call) async => '${call.arguments}, world');
|
channel.setMethodCallHandler((MethodCall call) async => '${call.arguments}, world');
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData envelope;
|
ByteData envelope;
|
||||||
await BinaryMessages.handlePlatformMessage('ch7', call, (ByteData result) {
|
await defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
expect(jsonMethod.decodeEnvelope(envelope), equals('hello, world'));
|
expect(jsonMethod.decodeEnvelope(envelope), equals('hello, world'));
|
||||||
@ -188,7 +188,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData envelope;
|
ByteData envelope;
|
||||||
await BinaryMessages.handlePlatformMessage('ch7', call, (ByteData result) {
|
await defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@ -207,7 +207,7 @@ void main() {
|
|||||||
});
|
});
|
||||||
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
final ByteData call = jsonMethod.encodeMethodCall(const MethodCall('sayHello', 'hello'));
|
||||||
ByteData envelope;
|
ByteData envelope;
|
||||||
await BinaryMessages.handlePlatformMessage('ch7', call, (ByteData result) {
|
await defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
|
||||||
envelope = result;
|
envelope = result;
|
||||||
});
|
});
|
||||||
try {
|
try {
|
||||||
@ -226,7 +226,7 @@ void main() {
|
|||||||
const MethodCodec jsonMethod = JSONMethodCodec();
|
const MethodCodec jsonMethod = JSONMethodCodec();
|
||||||
const EventChannel channel = EventChannel('ch', jsonMethod);
|
const EventChannel channel = EventChannel('ch', jsonMethod);
|
||||||
void emitEvent(dynamic event) {
|
void emitEvent(dynamic event) {
|
||||||
BinaryMessages.handlePlatformMessage(
|
defaultBinaryMessenger.handlePlatformMessage(
|
||||||
'ch',
|
'ch',
|
||||||
event,
|
event,
|
||||||
(ByteData reply) { },
|
(ByteData reply) { },
|
||||||
@ -234,7 +234,7 @@ void main() {
|
|||||||
}
|
}
|
||||||
test('can receive event stream', () async {
|
test('can receive event stream', () async {
|
||||||
bool canceled = false;
|
bool canceled = false;
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch',
|
'ch',
|
||||||
(ByteData message) async {
|
(ByteData message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
||||||
@ -258,7 +258,7 @@ void main() {
|
|||||||
expect(canceled, isTrue);
|
expect(canceled, isTrue);
|
||||||
});
|
});
|
||||||
test('can receive error event', () async {
|
test('can receive error event', () async {
|
||||||
BinaryMessages.setMockMessageHandler(
|
defaultBinaryMessenger.setMockMessageHandler(
|
||||||
'ch',
|
'ch',
|
||||||
(ByteData message) async {
|
(ByteData message) async {
|
||||||
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
final Map<dynamic, dynamic> methodCall = jsonMessage.decodeMessage(message);
|
||||||
|
@ -9,23 +9,23 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
test('Mock binary message handler control test', () async {
|
test('Mock binary message handler control test', () async {
|
||||||
// Initialize all bindings because BinaryMessages.send() needs a window.
|
// Initialize all bindings because defaultBinaryMessenger.send() needs a window.
|
||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
final List<ByteData> log = <ByteData>[];
|
final List<ByteData> log = <ByteData>[];
|
||||||
|
|
||||||
BinaryMessages.setMockMessageHandler('test1', (ByteData message) async {
|
defaultBinaryMessenger.setMockMessageHandler('test1', (ByteData message) async {
|
||||||
log.add(message);
|
log.add(message);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
final ByteData message = ByteData(2)..setUint16(0, 0xABCD);
|
final ByteData message = ByteData(2)..setUint16(0, 0xABCD);
|
||||||
await BinaryMessages.send('test1', message);
|
await defaultBinaryMessenger.send('test1', message);
|
||||||
expect(log, equals(<ByteData>[message]));
|
expect(log, equals(<ByteData>[message]));
|
||||||
log.clear();
|
log.clear();
|
||||||
|
|
||||||
BinaryMessages.setMockMessageHandler('test1', null);
|
defaultBinaryMessenger.setMockMessageHandler('test1', null);
|
||||||
await BinaryMessages.send('test1', message);
|
await defaultBinaryMessenger.send('test1', message);
|
||||||
expect(log, isEmpty);
|
expect(log, isEmpty);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ void main() {
|
|||||||
test('setApplicationSwitcherDescription missing plugin', () async {
|
test('setApplicationSwitcherDescription missing plugin', () async {
|
||||||
final List<ByteData> log = <ByteData>[];
|
final List<ByteData> log = <ByteData>[];
|
||||||
|
|
||||||
BinaryMessages.setMockMessageHandler('flutter/platform', (ByteData message) {
|
defaultBinaryMessenger.setMockMessageHandler('flutter/platform', (ByteData message) {
|
||||||
log.add(message);
|
log.add(message);
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
@ -46,7 +46,7 @@ void main() {
|
|||||||
WidgetsBinding.instance.addObserver(observer);
|
WidgetsBinding.instance.addObserver(observer);
|
||||||
final ByteData message = const JSONMessageCodec().encodeMessage(
|
final ByteData message = const JSONMessageCodec().encodeMessage(
|
||||||
<String, dynamic>{'type': 'memoryPressure'});
|
<String, dynamic>{'type': 'memoryPressure'});
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/system', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/system', message, (_) { });
|
||||||
expect(observer.sawMemoryPressure, true);
|
expect(observer.sawMemoryPressure, true);
|
||||||
WidgetsBinding.instance.removeObserver(observer);
|
WidgetsBinding.instance.removeObserver(observer);
|
||||||
});
|
});
|
||||||
@ -56,19 +56,19 @@ void main() {
|
|||||||
WidgetsBinding.instance.addObserver(observer);
|
WidgetsBinding.instance.addObserver(observer);
|
||||||
|
|
||||||
ByteData message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
ByteData message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(observer.lifecycleState, AppLifecycleState.paused);
|
expect(observer.lifecycleState, AppLifecycleState.paused);
|
||||||
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
message = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(observer.lifecycleState, AppLifecycleState.resumed);
|
expect(observer.lifecycleState, AppLifecycleState.resumed);
|
||||||
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.inactive');
|
message = const StringCodec().encodeMessage('AppLifecycleState.inactive');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(observer.lifecycleState, AppLifecycleState.inactive);
|
expect(observer.lifecycleState, AppLifecycleState.inactive);
|
||||||
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.suspending');
|
message = const StringCodec().encodeMessage('AppLifecycleState.suspending');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(observer.lifecycleState, AppLifecycleState.suspending);
|
expect(observer.lifecycleState, AppLifecycleState.suspending);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ void main() {
|
|||||||
const String testRouteName = 'testRouteName';
|
const String testRouteName = 'testRouteName';
|
||||||
final ByteData message = const JSONMethodCodec().encodeMethodCall(
|
final ByteData message = const JSONMethodCodec().encodeMethodCall(
|
||||||
const MethodCall('pushRoute', testRouteName));
|
const MethodCall('pushRoute', testRouteName));
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/navigation', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
|
||||||
expect(observer.pushedRoute, testRouteName);
|
expect(observer.pushedRoute, testRouteName);
|
||||||
|
|
||||||
WidgetsBinding.instance.removeObserver(observer);
|
WidgetsBinding.instance.removeObserver(observer);
|
||||||
@ -90,31 +90,31 @@ void main() {
|
|||||||
expect(tester.binding.hasScheduledFrame, isFalse);
|
expect(tester.binding.hasScheduledFrame, isFalse);
|
||||||
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(tester.binding.hasScheduledFrame, isFalse);
|
expect(tester.binding.hasScheduledFrame, isFalse);
|
||||||
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
message = const StringCodec().encodeMessage('AppLifecycleState.resumed');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(tester.binding.hasScheduledFrame, isTrue);
|
expect(tester.binding.hasScheduledFrame, isTrue);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(tester.binding.hasScheduledFrame, isFalse);
|
expect(tester.binding.hasScheduledFrame, isFalse);
|
||||||
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.inactive');
|
message = const StringCodec().encodeMessage('AppLifecycleState.inactive');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(tester.binding.hasScheduledFrame, isFalse);
|
expect(tester.binding.hasScheduledFrame, isFalse);
|
||||||
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.suspending');
|
message = const StringCodec().encodeMessage('AppLifecycleState.suspending');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(tester.binding.hasScheduledFrame, isFalse);
|
expect(tester.binding.hasScheduledFrame, isFalse);
|
||||||
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.inactive');
|
message = const StringCodec().encodeMessage('AppLifecycleState.inactive');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(tester.binding.hasScheduledFrame, isTrue);
|
expect(tester.binding.hasScheduledFrame, isTrue);
|
||||||
await tester.pump();
|
await tester.pump();
|
||||||
expect(tester.binding.hasScheduledFrame, isFalse);
|
expect(tester.binding.hasScheduledFrame, isFalse);
|
||||||
|
|
||||||
message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
message = const StringCodec().encodeMessage('AppLifecycleState.paused');
|
||||||
await BinaryMessages.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
await defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { });
|
||||||
expect(tester.binding.hasScheduledFrame, isFalse);
|
expect(tester.binding.hasScheduledFrame, isFalse);
|
||||||
|
|
||||||
tester.binding.scheduleFrame();
|
tester.binding.scheduleFrame();
|
||||||
|
@ -10,7 +10,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void sendFakeKeyEvent(Map<String, dynamic> data) {
|
void sendFakeKeyEvent(Map<String, dynamic> data) {
|
||||||
BinaryMessages.handlePlatformMessage(
|
defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData data) {},
|
(ByteData data) {},
|
||||||
|
@ -9,7 +9,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void sendFakeKeyEvent(Map<String, dynamic> data) {
|
void sendFakeKeyEvent(Map<String, dynamic> data) {
|
||||||
BinaryMessages.handlePlatformMessage(
|
defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.keyEvent.name,
|
SystemChannels.keyEvent.name,
|
||||||
SystemChannels.keyEvent.codec.encodeMessage(data),
|
SystemChannels.keyEvent.codec.encodeMessage(data),
|
||||||
(ByteData data) {},
|
(ByteData data) {},
|
||||||
|
@ -757,7 +757,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
|
|||||||
_ensureInitialized(assetFolderPath);
|
_ensureInitialized(assetFolderPath);
|
||||||
|
|
||||||
if (_allowedAssetKeys.isNotEmpty) {
|
if (_allowedAssetKeys.isNotEmpty) {
|
||||||
BinaryMessages.setMockMessageHandler('flutter/assets', (ByteData message) {
|
defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData message) {
|
||||||
final String key = utf8.decode(message.buffer.asUint8List());
|
final String key = utf8.decode(message.buffer.asUint8List());
|
||||||
if (_allowedAssetKeys.contains(key)) {
|
if (_allowedAssetKeys.contains(key)) {
|
||||||
final File asset = File(path.join(assetFolderPath, key));
|
final File asset = File(path.join(assetFolderPath, key));
|
||||||
|
@ -105,7 +105,7 @@ class TestTextInput {
|
|||||||
// test this code does not run in a package:test test zone.
|
// test this code does not run in a package:test test zone.
|
||||||
if (_client == 0)
|
if (_client == 0)
|
||||||
throw TestFailure('Tried to use TestTextInput with no keyboard attached. You must use WidgetTester.showKeyboard() first.');
|
throw TestFailure('Tried to use TestTextInput with no keyboard attached. You must use WidgetTester.showKeyboard() first.');
|
||||||
BinaryMessages.handlePlatformMessage(
|
defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.textInput.name,
|
SystemChannels.textInput.name,
|
||||||
SystemChannels.textInput.codec.encodeMethodCall(
|
SystemChannels.textInput.codec.encodeMethodCall(
|
||||||
MethodCall(
|
MethodCall(
|
||||||
@ -137,7 +137,7 @@ class TestTextInput {
|
|||||||
|
|
||||||
final Completer<void> completer = Completer<void>();
|
final Completer<void> completer = Completer<void>();
|
||||||
|
|
||||||
BinaryMessages.handlePlatformMessage(
|
defaultBinaryMessenger.handlePlatformMessage(
|
||||||
SystemChannels.textInput.name,
|
SystemChannels.textInput.name,
|
||||||
SystemChannels.textInput.codec.encodeMethodCall(
|
SystemChannels.textInput.codec.encodeMethodCall(
|
||||||
MethodCall(
|
MethodCall(
|
||||||
|
Loading…
Reference in New Issue
Block a user