Unverified Commit 93c32c4f authored by adazh's avatar adazh Committed by GitHub

Moved the default BinaryMessenger instance to ServicesBinding (#38464)

* Moved the default BinaryMessenger instance to ServicesBinding

This reverts commit 821602ae.

* Added assertion in defaultBinaryMessenger. Also fixed the devicelab tests.
parent ddb10dd9
...@@ -11,6 +11,6 @@ void main() { ...@@ -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 defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) {}); await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) {});
}); });
} }
...@@ -36,9 +36,9 @@ Future<String> respondToHostRequestForSplashLog(String _) { ...@@ -36,9 +36,9 @@ Future<String> respondToHostRequestForSplashLog(String _) {
void createTestChannelBetweenAndroidAndFlutter() { void createTestChannelBetweenAndroidAndFlutter() {
// Channel used for Android to send Flutter changes to the splash display. // Channel used for Android to send Flutter changes to the splash display.
final BasicMessageChannel<String> testChannel = BasicMessageChannel<String>( const BasicMessageChannel<String> testChannel = BasicMessageChannel<String>(
'testChannel', 'testChannel',
const StringCodec() StringCodec()
); );
// Every splash display change message that we receive from Android is either // Every splash display change message that we receive from Android is either
......
...@@ -25,6 +25,8 @@ const BasicMessageChannel<String> _kReloadChannel = ...@@ -25,6 +25,8 @@ const BasicMessageChannel<String> _kReloadChannel =
BasicMessageChannel<String>(_kReloadChannelName, StringCodec()); BasicMessageChannel<String>(_kReloadChannelName, StringCodec());
void main() { void main() {
// Ensures bindings are initialized before doing anything.
WidgetsFlutterBinding.ensureInitialized();
// Start listening immediately for messages from the iOS side. ObjC calls // Start listening immediately for messages from the iOS side. ObjC calls
// will be made to let us know when we should be changing the app state. // will be made to let us know when we should be changing the app state.
_kReloadChannel.setMessageHandler(run); _kReloadChannel.setMessageHandler(run);
......
...@@ -20,6 +20,8 @@ Future<void> main() async { ...@@ -20,6 +20,8 @@ Future<void> main() async {
final int port = httpServer.port; final int port = httpServer.port;
print('Listening on port $port.'); print('Listening on port $port.');
// Initializes bindings before using any platform channels.
WidgetsFlutterBinding.ensureInitialized();
final ByteData byteData = await rootBundle.load('images/coast.jpg'); final ByteData byteData = await rootBundle.load('images/coast.jpg');
final Uint8List bytes = byteData.buffer final Uint8List bytes = byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes); .asUint8List(byteData.offsetInBytes, byteData.lengthInBytes);
......
...@@ -216,7 +216,7 @@ class PlatformAssetBundle extends CachingAssetBundle { ...@@ -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 defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData()); await defaultBinaryMessenger.send('flutter/assets', encoded.buffer.asByteData()); // ignore: deprecated_member_use_from_same_package
if (asset == null) if (asset == null)
throw FlutterError('Unable to load asset: $key'); throw FlutterError('Unable to load asset: $key');
return asset; return asset;
......
...@@ -7,6 +7,7 @@ import 'dart:typed_data'; ...@@ -7,6 +7,7 @@ import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'binding.dart';
/// A function which takes a platform message and asynchronously returns an encoded response. /// A function which takes a platform message and asynchronously returns an encoded response.
typedef MessageHandler = Future<ByteData> Function(ByteData message); typedef MessageHandler = Future<ByteData> Function(ByteData message);
...@@ -56,99 +57,32 @@ abstract class BinaryMessenger { ...@@ -56,99 +57,32 @@ abstract class BinaryMessenger {
void setMockMessageHandler(String channel, Future<ByteData> handler(ByteData message)); 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]. /// The default instance of [BinaryMessenger].
/// ///
/// This API has been deprecated in favor of [ServicesBinding.defaultBinaryMessenger].
/// Please use [ServicesBinding.defaultBinaryMessenger] as the default
/// instance of [BinaryMessenger].
///
/// This is used to send messages from the application to the platform, and /// 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 /// keeps track of which handlers have been registered on each channel so
/// it may dispatch incoming messages to the registered handler. /// it may dispatch incoming messages to the registered handler.
const BinaryMessenger defaultBinaryMessenger = _DefaultBinaryMessenger._(); @Deprecated('Use ServicesBinding.instance.defaultBinaryMessenger instead.')
BinaryMessenger get defaultBinaryMessenger {
assert(() {
if (ServicesBinding.instance == null) {
throw FlutterError(
'ServicesBinding.defaultBinaryMessenger was accessed before the '
'binding was initialized.\n'
'If you\'re running an application and need to access the binary '
'messenger before `runApp()` has been called (for example, during '
'plugin initialization), then you need to explicitly call the '
'`WidgetsFlutterBinding.ensureInitialized()` first.\n'
'If you\'re running a test, you can call the '
'`TestWidgetsFlutterBinding.ensureInitialized()` as the first line in '
'your test\'s `main()` method to initialize the binding.'
);
}
return true;
}());
return ServicesBinding.instance.defaultBinaryMessenger;
}
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:async'; import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
...@@ -20,6 +22,7 @@ mixin ServicesBinding on BindingBase { ...@@ -20,6 +22,7 @@ mixin ServicesBinding on BindingBase {
void initInstances() { void initInstances() {
super.initInstances(); super.initInstances();
_instance = this; _instance = this;
_defaultBinaryMessenger = createBinaryMessenger();
window window
..onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage; ..onPlatformMessage = defaultBinaryMessenger.handlePlatformMessage;
initLicenses(); initLicenses();
...@@ -29,6 +32,21 @@ mixin ServicesBinding on BindingBase { ...@@ -29,6 +32,21 @@ mixin ServicesBinding on BindingBase {
static ServicesBinding get instance => _instance; static ServicesBinding get instance => _instance;
static ServicesBinding _instance; static ServicesBinding _instance;
/// 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.
BinaryMessenger get defaultBinaryMessenger => _defaultBinaryMessenger;
BinaryMessenger _defaultBinaryMessenger;
/// Creates a default [BinaryMessenger] instance that can be used for sending
/// platform messages.
@protected
BinaryMessenger createBinaryMessenger() {
return const _DefaultBinaryMessenger._();
}
/// Adds relevant licenses to the [LicenseRegistry]. /// Adds relevant licenses to the [LicenseRegistry].
/// ///
/// By default, the [ServicesBinding]'s implementation of [initLicenses] adds /// By default, the [ServicesBinding]'s implementation of [initLicenses] adds
...@@ -117,3 +135,92 @@ mixin ServicesBinding on BindingBase { ...@@ -117,3 +135,92 @@ mixin ServicesBinding on BindingBase {
rootBundle.evict(asset); rootBundle.evict(asset);
} }
} }
/// 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;
}
}
...@@ -8,6 +8,7 @@ import 'dart:typed_data'; ...@@ -8,6 +8,7 @@ import 'dart:typed_data';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'binary_messenger.dart'; import 'binary_messenger.dart';
import 'binding.dart';
import 'message_codec.dart'; import 'message_codec.dart';
import 'message_codecs.dart'; import 'message_codecs.dart';
...@@ -31,11 +32,12 @@ import 'message_codecs.dart'; ...@@ -31,11 +32,12 @@ import 'message_codecs.dart';
class BasicMessageChannel<T> { class BasicMessageChannel<T> {
/// Creates a [BasicMessageChannel] with the specified [name], [codec] and [binaryMessenger]. /// Creates a [BasicMessageChannel] with the specified [name], [codec] and [binaryMessenger].
/// ///
/// None of [name], [codec], or [binaryMessenger] may be null. /// The [name] and [codec] arguments cannot be null. The default [ServicesBinding.defaultBinaryMessenger]
const BasicMessageChannel(this.name, this.codec, { this.binaryMessenger = defaultBinaryMessenger }) /// instance is used if [binaryMessenger] is null.
: assert(name != null), const BasicMessageChannel(this.name, this.codec, { BinaryMessenger binaryMessenger })
assert(codec != null), : assert(name != null),
assert(binaryMessenger != null); assert(codec != null),
_binaryMessenger = binaryMessenger;
/// The logical channel on which communication happens, not null. /// The logical channel on which communication happens, not null.
final String name; final String name;
...@@ -44,7 +46,8 @@ class BasicMessageChannel<T> { ...@@ -44,7 +46,8 @@ class BasicMessageChannel<T> {
final MessageCodec<T> codec; final MessageCodec<T> codec;
/// The messenger which sends the bytes for this channel, not null. /// The messenger which sends the bytes for this channel, not null.
final BinaryMessenger binaryMessenger; BinaryMessenger get binaryMessenger => _binaryMessenger ?? defaultBinaryMessenger; // ignore: deprecated_member_use_from_same_package
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.
/// ///
...@@ -118,11 +121,12 @@ class MethodChannel { ...@@ -118,11 +121,12 @@ class MethodChannel {
/// The [codec] used will be [StandardMethodCodec], unless otherwise /// The [codec] used will be [StandardMethodCodec], unless otherwise
/// specified. /// specified.
/// ///
/// None of [name], [binaryMessenger], or [codec] may be null. /// The [name] and [codec] arguments cannot be null. The default [ServicesBinding.defaultBinaryMessenger]
const MethodChannel(this.name, [this.codec = const StandardMethodCodec(), this.binaryMessenger = defaultBinaryMessenger ]) /// instance is used if [binaryMessenger] is null.
: assert(name != null), const MethodChannel(this.name, [this.codec = const StandardMethodCodec(), BinaryMessenger binaryMessenger ])
assert(binaryMessenger != null), : assert(name != null),
assert(codec != null); assert(codec != null),
_binaryMessenger = binaryMessenger;
/// The logical channel on which communication happens, not null. /// The logical channel on which communication happens, not null.
final String name; final String name;
...@@ -133,7 +137,8 @@ class MethodChannel { ...@@ -133,7 +137,8 @@ class MethodChannel {
/// The messenger used by this channel to send platform messages. /// The messenger used by this channel to send platform messages.
/// ///
/// The messenger may not be null. /// The messenger may not be null.
final BinaryMessenger binaryMessenger; BinaryMessenger get binaryMessenger => _binaryMessenger ?? defaultBinaryMessenger; // ignore: deprecated_member_use_from_same_package
final BinaryMessenger _binaryMessenger;
/// Invokes a [method] on this channel with the specified [arguments]. /// Invokes a [method] on this channel with the specified [arguments].
/// ///
...@@ -462,8 +467,12 @@ class EventChannel { ...@@ -462,8 +467,12 @@ class EventChannel {
/// 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. /// Neither [name] nor [codec] may be null. The default [ServicesBinding.defaultBinaryMessenger]
const EventChannel(this.name, [this.codec = const StandardMethodCodec()]); /// instance is used if [binaryMessenger] is null.
const EventChannel(this.name, [this.codec = const StandardMethodCodec(), BinaryMessenger binaryMessenger])
: assert(name != null),
assert(codec != null),
_binaryMessenger = binaryMessenger;
/// The logical channel on which communication happens, not null. /// The logical channel on which communication happens, not null.
final String name; final String name;
...@@ -471,6 +480,10 @@ class EventChannel { ...@@ -471,6 +480,10 @@ class EventChannel {
/// 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, not null.
BinaryMessenger get binaryMessenger => _binaryMessenger ?? defaultBinaryMessenger; // ignore: deprecated_member_use_from_same_package
final BinaryMessenger _binaryMessenger;
/// Sets up a broadcast stream for receiving events on this channel. /// Sets up a broadcast stream for receiving events on this channel.
/// ///
/// Returns a broadcast [Stream] which emits events to listeners as follows: /// Returns a broadcast [Stream] which emits events to listeners as follows:
...@@ -488,7 +501,7 @@ class EventChannel { ...@@ -488,7 +501,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 {
defaultBinaryMessenger.setMessageHandler(name, (ByteData reply) async { binaryMessenger.setMessageHandler(name, (ByteData reply) async {
if (reply == null) { if (reply == null) {
controller.close(); controller.close();
} else { } else {
...@@ -511,7 +524,7 @@ class EventChannel { ...@@ -511,7 +524,7 @@ class EventChannel {
)); ));
} }
}, onCancel: () async { }, onCancel: () async {
defaultBinaryMessenger.setMessageHandler(name, null); binaryMessenger.setMessageHandler(name, null);
try { try {
await methodChannel.invokeMethod<void>('cancel', arguments); await methodChannel.invokeMethod<void>('cancel', arguments);
} catch (exception, stack) { } catch (exception, stack) {
......
...@@ -7,7 +7,6 @@ import 'dart:typed_data'; ...@@ -7,7 +7,6 @@ import 'dart:typed_data';
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'binary_messenger.dart'; import 'binary_messenger.dart';
import 'binding.dart' show ServicesBinding;
import 'platform_channel.dart'; import 'platform_channel.dart';
/// Sends binary messages to and receives binary messages from platform plugins. /// Sends binary messages to and receives binary messages from platform plugins.
...@@ -31,6 +30,9 @@ import 'platform_channel.dart'; ...@@ -31,6 +30,9 @@ import 'platform_channel.dart';
class BinaryMessages { class BinaryMessages {
BinaryMessages._(); BinaryMessages._();
/// The messenger which sends the platform messages, not null.
static final BinaryMessenger _binaryMessenger = defaultBinaryMessenger;
/// 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
...@@ -43,7 +45,7 @@ class BinaryMessages { ...@@ -43,7 +45,7 @@ class BinaryMessages {
ByteData data, ByteData data,
ui.PlatformMessageResponseCallback callback, ui.PlatformMessageResponseCallback callback,
) { ) {
return defaultBinaryMessenger.handlePlatformMessage(channel, data, callback); return _binaryMessenger.handlePlatformMessage(channel, data, callback);
} }
/// Send a binary message to the platform plugins on the given channel. /// Send a binary message to the platform plugins on the given channel.
...@@ -52,7 +54,7 @@ class BinaryMessages { ...@@ -52,7 +54,7 @@ class BinaryMessages {
/// binary form. /// binary form.
@Deprecated('Use defaultBinaryMessenger.send instead.') @Deprecated('Use defaultBinaryMessenger.send instead.')
static Future<ByteData> send(String channel, ByteData message) { static Future<ByteData> send(String channel, ByteData message) {
return defaultBinaryMessenger.send(channel, message); return _binaryMessenger.send(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
...@@ -65,7 +67,7 @@ class BinaryMessages { ...@@ -65,7 +67,7 @@ class BinaryMessages {
/// 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.') @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)) {
defaultBinaryMessenger.setMessageHandler(channel, handler); _binaryMessenger.setMessageHandler(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
...@@ -81,6 +83,6 @@ class BinaryMessages { ...@@ -81,6 +83,6 @@ class BinaryMessages {
/// sent to platform plugins. /// sent to platform plugins.
@Deprecated('Use defaultBinaryMessenger.setMockMessageHandler instead.') @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)) {
defaultBinaryMessenger.setMockMessageHandler(channel, handler); _binaryMessenger.setMockMessageHandler(channel, handler);
} }
} }
...@@ -251,6 +251,10 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB ...@@ -251,6 +251,10 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
void initInstances() { void initInstances() {
super.initInstances(); super.initInstances();
_instance = this; _instance = this;
// Initialization of [_buildOwner] has to be done after
// [super.initInstances] is called, as it requires [ServicesBinding] to
// properly setup the [defaultBinaryMessenger] instance.
_buildOwner = BuildOwner();
buildOwner.onBuildScheduled = _handleBuildScheduled; buildOwner.onBuildScheduled = _handleBuildScheduled;
window.onLocaleChanged = handleLocaleChanged; window.onLocaleChanged = handleLocaleChanged;
window.onAccessibilityFeaturesChanged = handleAccessibilityFeaturesChanged; window.onAccessibilityFeaturesChanged = handleAccessibilityFeaturesChanged;
...@@ -371,7 +375,10 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB ...@@ -371,7 +375,10 @@ mixin WidgetsBinding on BindingBase, SchedulerBinding, GestureBinding, RendererB
/// The [BuildOwner] in charge of executing the build pipeline for the /// The [BuildOwner] in charge of executing the build pipeline for the
/// widget tree rooted at this binding. /// widget tree rooted at this binding.
BuildOwner get buildOwner => _buildOwner; BuildOwner get buildOwner => _buildOwner;
final BuildOwner _buildOwner = BuildOwner(); // Initialization of [_buildOwner] has to be done within the [initInstances]
// method, as it requires [ServicesBinding] to properly setup the
// [defaultBinaryMessenger] instance.
BuildOwner _buildOwner;
/// The object in charge of the focus tree. /// The object in charge of the focus tree.
/// ///
......
...@@ -125,6 +125,7 @@ class PathPointsMatcher extends Matcher { ...@@ -125,6 +125,7 @@ class PathPointsMatcher extends Matcher {
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard(); final MockClipboard mockClipboard = MockClipboard();
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall); SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
......
...@@ -433,7 +433,7 @@ void main() { ...@@ -433,7 +433,7 @@ void main() {
bool completed; bool completed;
completed = false; completed = false;
defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData message) async { ServicesBinding.instance.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
...@@ -452,7 +452,7 @@ void main() { ...@@ -452,7 +452,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);
defaultBinaryMessenger.setMockMessageHandler('flutter/assets', null); ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', null);
}); });
test('Service extensions - exit', () async { test('Service extensions - exit', () async {
......
...@@ -72,7 +72,7 @@ void main() { ...@@ -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 defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { }); await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
await tester.pumpAndSettle(); await tester.pumpAndSettle();
expect(selectedResults, <void>[null]); expect(selectedResults, <void>[null]);
......
...@@ -129,6 +129,7 @@ double getOpacity(WidgetTester tester, Finder finder) { ...@@ -129,6 +129,7 @@ double getOpacity(WidgetTester tester, Finder finder) {
} }
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard(); final MockClipboard mockClipboard = MockClipboard();
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall); SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
...@@ -3391,7 +3392,7 @@ void main() { ...@@ -3391,7 +3392,7 @@ void main() {
}); });
void sendFakeKeyEvent(Map<String, dynamic> data) { void sendFakeKeyEvent(Map<String, dynamic> data) {
defaultBinaryMessenger.handlePlatformMessage( ServicesBinding.instance.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() { ...@@ -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 defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', message, (_) { }); await ServicesBinding.instance.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() { ...@@ -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 defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', pausedMessage, (_) { }); await ServicesBinding.instance.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() { ...@@ -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 defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', resumedMessage, (_) { }); await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/lifecycle', resumedMessage, (_) { });
await tester.pump(const Duration(milliseconds: 10)); await tester.pump(const Duration(milliseconds: 10));
......
...@@ -6,10 +6,13 @@ import 'dart:ui' show TextDirection; ...@@ -6,10 +6,13 @@ import 'dart:ui' show TextDirection;
import 'package:flutter/semantics.dart'; import 'package:flutter/semantics.dart';
import 'package:flutter/services.dart' show SystemChannels; import 'package:flutter/services.dart' show SystemChannels;
import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding;
import '../flutter_test_alternative.dart'; import '../flutter_test_alternative.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
test('Semantic announcement', () async { test('Semantic announcement', () async {
final List<Map<dynamic, dynamic>> log = <Map<dynamic, dynamic>>[]; final List<Map<dynamic, dynamic>> log = <Map<dynamic, dynamic>>[];
......
...@@ -71,7 +71,7 @@ class FakeAndroidPlatformViewsController { ...@@ -71,7 +71,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));
defaultBinaryMessenger.handlePlatformMessage(SystemChannels.platform_views.name, data, (ByteData data) {}); ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(SystemChannels.platform_views.name, data, (ByteData data) {});
} }
Future<dynamic> _onMethodCall(MethodCall call) { Future<dynamic> _onMethodCall(MethodCall call) {
......
...@@ -6,6 +6,8 @@ import 'package:flutter/services.dart'; ...@@ -6,6 +6,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
test('Haptic feedback control test', () async { test('Haptic feedback control test', () async {
final List<MethodCall> log = <MethodCall>[]; final List<MethodCall> log = <MethodCall>[];
......
...@@ -6,14 +6,18 @@ import 'dart:async'; ...@@ -6,14 +6,18 @@ import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding;
import '../flutter_test_alternative.dart'; import '../flutter_test_alternative.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('BasicMessageChannel', () { group('BasicMessageChannel', () {
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 {
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
'ch', 'ch',
(ByteData message) async => string.encodeMessage(string.decodeMessage(message) + ' world'), (ByteData message) async => string.encodeMessage(string.decodeMessage(message) + ' world'),
); );
...@@ -23,7 +27,7 @@ void main() { ...@@ -23,7 +27,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 defaultBinaryMessenger.handlePlatformMessage( await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
'ch', 'ch',
const StringCodec().encodeMessage('hello'), const StringCodec().encodeMessage('hello'),
(ByteData replyBinary) { (ByteData replyBinary) {
...@@ -39,7 +43,7 @@ void main() { ...@@ -39,7 +43,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 {
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.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 +58,7 @@ void main() { ...@@ -54,7 +58,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 {
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.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 +74,7 @@ void main() { ...@@ -70,7 +74,7 @@ void main() {
}); });
test('can invoke list method and get null result', () async { test('can invoke list method and get null result', () async {
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.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 +90,7 @@ void main() { ...@@ -86,7 +90,7 @@ void main() {
test('can invoke map method and get result', () async { test('can invoke map method and get result', () async {
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.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 +106,7 @@ void main() { ...@@ -102,7 +106,7 @@ void main() {
}); });
test('can invoke map method and get null result', () async { test('can invoke map method and get null result', () async {
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.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 +121,7 @@ void main() { ...@@ -117,7 +121,7 @@ void main() {
}); });
test('can invoke method and get error', () async { test('can invoke method and get error', () async {
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
'ch7', 'ch7',
(ByteData message) async { (ByteData message) async {
return jsonMessage.encodeMessage(<dynamic>[ return jsonMessage.encodeMessage(<dynamic>[
...@@ -139,7 +143,7 @@ void main() { ...@@ -139,7 +143,7 @@ void main() {
} }
}); });
test('can invoke unimplemented method', () async { test('can invoke unimplemented method', () async {
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler(
'ch7', 'ch7',
(ByteData message) async => null, (ByteData message) async => null,
); );
...@@ -157,7 +161,7 @@ void main() { ...@@ -157,7 +161,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 defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) { await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
envelope = result; envelope = result;
}); });
expect(envelope, isNull); expect(envelope, isNull);
...@@ -168,7 +172,7 @@ void main() { ...@@ -168,7 +172,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 defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) { await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
envelope = result; envelope = result;
}); });
expect(envelope, isNull); expect(envelope, isNull);
...@@ -177,7 +181,7 @@ void main() { ...@@ -177,7 +181,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 defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) { await ServicesBinding.instance.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 +192,7 @@ void main() { ...@@ -188,7 +192,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 defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) { await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
envelope = result; envelope = result;
}); });
try { try {
...@@ -207,7 +211,7 @@ void main() { ...@@ -207,7 +211,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 defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) { await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('ch7', call, (ByteData result) {
envelope = result; envelope = result;
}); });
try { try {
...@@ -226,7 +230,7 @@ void main() { ...@@ -226,7 +230,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) {
defaultBinaryMessenger.handlePlatformMessage( ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
'ch', 'ch',
event, event,
(ByteData reply) { }, (ByteData reply) { },
...@@ -234,7 +238,7 @@ void main() { ...@@ -234,7 +238,7 @@ void main() {
} }
test('can receive event stream', () async { test('can receive event stream', () async {
bool canceled = false; bool canceled = false;
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.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 +262,7 @@ void main() { ...@@ -258,7 +262,7 @@ void main() {
expect(canceled, isTrue); expect(canceled, isTrue);
}); });
test('can receive error event', () async { test('can receive error event', () async {
defaultBinaryMessenger.setMockMessageHandler( ServicesBinding.instance.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);
......
...@@ -16,18 +16,18 @@ void main() { ...@@ -16,18 +16,18 @@ void main() {
final List<ByteData> log = <ByteData>[]; final List<ByteData> log = <ByteData>[];
defaultBinaryMessenger.setMockMessageHandler('test1', (ByteData message) async { ServicesBinding.instance.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 defaultBinaryMessenger.send('test1', message); await ServicesBinding.instance.defaultBinaryMessenger.send('test1', message);
expect(log, equals(<ByteData>[message])); expect(log, equals(<ByteData>[message]));
log.clear(); log.clear();
defaultBinaryMessenger.setMockMessageHandler('test1', null); ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('test1', null);
await defaultBinaryMessenger.send('test1', message); await ServicesBinding.instance.defaultBinaryMessenger.send('test1', message);
expect(log, isEmpty); expect(log, isEmpty);
}); });
} }
...@@ -4,11 +4,13 @@ ...@@ -4,11 +4,13 @@
import 'package:flutter/painting.dart'; import 'package:flutter/painting.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding;
import '../flutter_test_alternative.dart'; import '../flutter_test_alternative.dart';
import 'fake_platform_views.dart'; import 'fake_platform_views.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('Android', () { group('Android', () {
FakeAndroidPlatformViewsController viewsController; FakeAndroidPlatformViewsController viewsController;
......
...@@ -61,7 +61,7 @@ void main() { ...@@ -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>[];
defaultBinaryMessenger.setMockMessageHandler('flutter/platform', (ByteData message) { ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('flutter/platform', (ByteData message) {
log.add(message); log.add(message);
return null; return null;
}); });
......
...@@ -6,6 +6,8 @@ import 'package:flutter/services.dart'; ...@@ -6,6 +6,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
test('System navigator control test', () async { test('System navigator control test', () async {
final List<MethodCall> log = <MethodCall>[]; final List<MethodCall> log = <MethodCall>[];
......
...@@ -6,6 +6,8 @@ import 'package:flutter/services.dart'; ...@@ -6,6 +6,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
test('System sound control test', () async { test('System sound control test', () async {
final List<MethodCall> log = <MethodCall>[]; final List<MethodCall> log = <MethodCall>[];
......
...@@ -3,9 +3,12 @@ ...@@ -3,9 +3,12 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart' show TestWidgetsFlutterBinding;
import '../flutter_test_alternative.dart'; import '../flutter_test_alternative.dart';
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('TextInputConfiguration', () { group('TextInputConfiguration', () {
test('sets expected defaults', () { test('sets expected defaults', () {
const TextInputConfiguration configuration = TextInputConfiguration(); const TextInputConfiguration configuration = TextInputConfiguration();
...@@ -103,7 +106,7 @@ void main() { ...@@ -103,7 +106,7 @@ void main() {
'method': 'TextInputClient.onConnectionClosed', 'method': 'TextInputClient.onConnectionClosed',
} }
); );
defaultBinaryMessenger.handlePlatformMessage( ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
'flutter/textinput', 'flutter/textinput',
messageBytes, messageBytes,
(ByteData _) {}, (ByteData _) {},
......
...@@ -46,12 +46,13 @@ void main() { ...@@ -46,12 +46,13 @@ 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 defaultBinaryMessenger.handlePlatformMessage('flutter/system', message, (_) { }); await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/system', message, (_) { });
expect(observer.sawMemoryPressure, true); expect(observer.sawMemoryPressure, true);
WidgetsBinding.instance.removeObserver(observer); WidgetsBinding.instance.removeObserver(observer);
}); });
testWidgets('handleLifecycleStateChanged callback', (WidgetTester tester) async { testWidgets('handleLifecycleStateChanged callback', (WidgetTester tester) async {
final BinaryMessenger defaultBinaryMessenger = ServicesBinding.instance.defaultBinaryMessenger;
final AppLifecycleStateObserver observer = AppLifecycleStateObserver(); final AppLifecycleStateObserver observer = AppLifecycleStateObserver();
WidgetsBinding.instance.addObserver(observer); WidgetsBinding.instance.addObserver(observer);
...@@ -79,13 +80,14 @@ void main() { ...@@ -79,13 +80,14 @@ 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 defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { }); await ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage('flutter/navigation', message, (_) { });
expect(observer.pushedRoute, testRouteName); expect(observer.pushedRoute, testRouteName);
WidgetsBinding.instance.removeObserver(observer); WidgetsBinding.instance.removeObserver(observer);
}); });
testWidgets('Application lifecycle affects frame scheduling', (WidgetTester tester) async { testWidgets('Application lifecycle affects frame scheduling', (WidgetTester tester) async {
final BinaryMessenger defaultBinaryMessenger = ServicesBinding.instance.defaultBinaryMessenger;
ByteData message; ByteData message;
expect(tester.binding.hasScheduledFrame, isFalse); expect(tester.binding.hasScheduledFrame, isFalse);
......
...@@ -10,7 +10,7 @@ import 'package:flutter/widgets.dart'; ...@@ -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) {
defaultBinaryMessenger.handlePlatformMessage( ServicesBinding.instance.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'; ...@@ -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) {
defaultBinaryMessenger.handlePlatformMessage( ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name, SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data), SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {}, (ByteData data) {},
......
...@@ -122,6 +122,7 @@ double getOpacity(WidgetTester tester, Finder finder) { ...@@ -122,6 +122,7 @@ double getOpacity(WidgetTester tester, Finder finder) {
} }
void main() { void main() {
TestWidgetsFlutterBinding.ensureInitialized();
final MockClipboard mockClipboard = MockClipboard(); final MockClipboard mockClipboard = MockClipboard();
SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall); SystemChannels.platform.setMockMethodCallHandler(mockClipboard.handleMethodCall);
...@@ -1247,7 +1248,7 @@ void main() { ...@@ -1247,7 +1248,7 @@ void main() {
}); });
void sendFakeKeyEvent(Map<String, dynamic> data) { void sendFakeKeyEvent(Map<String, dynamic> data) {
defaultBinaryMessenger.handlePlatformMessage( ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name, SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data), SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) { }, (ByteData data) { },
......
...@@ -11,7 +11,7 @@ import 'package:flutter/widgets.dart'; ...@@ -11,7 +11,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) {
defaultBinaryMessenger.handlePlatformMessage( ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
SystemChannels.keyEvent.name, SystemChannels.keyEvent.name,
SystemChannels.keyEvent.codec.encodeMessage(data), SystemChannels.keyEvent.codec.encodeMessage(data),
(ByteData data) {}, (ByteData data) {},
......
...@@ -207,10 +207,10 @@ abstract class TestWidgetsFlutterBinding extends BindingBase ...@@ -207,10 +207,10 @@ abstract class TestWidgetsFlutterBinding extends BindingBase
@override @override
void initInstances() { void initInstances() {
super.initInstances();
timeDilation = 1.0; // just in case the developer has artificially changed it for development timeDilation = 1.0; // just in case the developer has artificially changed it for development
HttpOverrides.global = _MockHttpOverrides(); HttpOverrides.global = _MockHttpOverrides();
_testTextInput = TestTextInput(onCleared: _resetFocusedEditable)..register(); _testTextInput = TestTextInput(onCleared: _resetFocusedEditable)..register();
super.initInstances();
} }
@override @override
...@@ -812,7 +812,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding { ...@@ -812,7 +812,7 @@ class AutomatedTestWidgetsFlutterBinding extends TestWidgetsFlutterBinding {
/// platform messages. /// platform messages.
SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {}); SystemChannels.navigation.setMockMethodCallHandler((MethodCall methodCall) async {});
defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData message) { ServicesBinding.instance.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (ByteData message) {
String key = utf8.decode(message.buffer.asUint8List()); String key = utf8.decode(message.buffer.asUint8List());
File asset = File(path.join(assetFolderPath, key)); File asset = File(path.join(assetFolderPath, key));
......
...@@ -36,6 +36,9 @@ class TestTextInput { ...@@ -36,6 +36,9 @@ class TestTextInput {
/// first be requested, e.g. using [WidgetTester.showKeyboard]. /// first be requested, e.g. using [WidgetTester.showKeyboard].
final VoidCallback onCleared; final VoidCallback onCleared;
/// The messenger which sends the bytes for this channel, not null.
BinaryMessenger get _binaryMessenger => ServicesBinding.instance.defaultBinaryMessenger;
/// Installs this object as a mock handler for [SystemChannels.textInput]. /// Installs this object as a mock handler for [SystemChannels.textInput].
void register() { void register() {
SystemChannels.textInput.setMockMethodCallHandler(_handleTextInputCall); SystemChannels.textInput.setMockMethodCallHandler(_handleTextInputCall);
...@@ -108,7 +111,7 @@ class TestTextInput { ...@@ -108,7 +111,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.');
defaultBinaryMessenger.handlePlatformMessage( _binaryMessenger.handlePlatformMessage(
SystemChannels.textInput.name, SystemChannels.textInput.name,
SystemChannels.textInput.codec.encodeMethodCall( SystemChannels.textInput.codec.encodeMethodCall(
MethodCall( MethodCall(
...@@ -140,7 +143,7 @@ class TestTextInput { ...@@ -140,7 +143,7 @@ class TestTextInput {
final Completer<void> completer = Completer<void>(); final Completer<void> completer = Completer<void>();
defaultBinaryMessenger.handlePlatformMessage( _binaryMessenger.handlePlatformMessage(
SystemChannels.textInput.name, SystemChannels.textInput.name,
SystemChannels.textInput.codec.encodeMethodCall( SystemChannels.textInput.codec.encodeMethodCall(
MethodCall( MethodCall(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment