Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Refactor platform message logic #22181

Merged
merged 1 commit into from
Nov 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
617 changes: 473 additions & 144 deletions lib/ui/channel_buffers.dart

Large diffs are not rendered by default.

37 changes: 30 additions & 7 deletions lib/ui/hooks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ void _invoke(void Function()? callback, Zone zone) {
}

/// Invokes [callback] inside the given [zone] passing it [arg].
///
/// The 1 in the name refers to the number of arguments expected by
/// the callback (and thus passed to this function, in addition to the
/// callback itself and the zone in which the callback is executed).
void _invoke1<A>(void Function(A a)? callback, Zone zone, A arg) {
if (callback == null) {
return;
Expand All @@ -173,14 +177,33 @@ void _invoke1<A>(void Function(A a)? callback, Zone zone, A arg) {
}
}

/// Invokes [callback] inside the given [zone] passing it [arg1] and [arg2].
///
/// The 2 in the name refers to the number of arguments expected by
/// the callback (and thus passed to this function, in addition to the
/// callback itself and the zone in which the callback is executed).
void _invoke2<A1, A2>(void Function(A1 a1, A2 a2)? callback, Zone zone, A1 arg1, A2 arg2) {
if (callback == null) {
return;
}

assert(zone != null); // ignore: unnecessary_null_comparison

if (identical(zone, Zone.current)) {
callback(arg1, arg2);
} else {
zone.runGuarded(() {
callback(arg1, arg2);
});
}
}

/// Invokes [callback] inside the given [zone] passing it [arg1], [arg2], and [arg3].
void _invoke3<A1, A2, A3>(
void Function(A1 a1, A2 a2, A3 a3)? callback,
Zone zone,
A1 arg1,
A2 arg2,
A3 arg3,
) {
///
/// The 3 in the name refers to the number of arguments expected by
/// the callback (and thus passed to this function, in addition to the
/// callback itself and the zone in which the callback is executed).
void _invoke3<A1, A2, A3>(void Function(A1 a1, A2 a2, A3 a3)? callback, Zone zone, A1 arg1, A2 arg2, A3 arg3) {
if (callback == null) {
return;
}
Expand Down
13 changes: 9 additions & 4 deletions lib/ui/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ typedef SemanticsActionCallback = void Function(int id, SemanticsAction action,
typedef PlatformMessageResponseCallback = void Function(ByteData? data);

/// Signature for [PlatformDispatcher.onPlatformMessage].
// TODO(ianh): deprecate once framework uses [ChannelBuffers.setListener].
typedef PlatformMessageCallback = void Function(String name, ByteData? data, PlatformMessageResponseCallback? callback);

// Signature for _setNeedsReportTimings.
Expand Down Expand Up @@ -409,6 +410,8 @@ class PlatformDispatcher {
///
/// The framework invokes this callback in the same zone in which the callback
/// was set.
// TODO(ianh): Deprecate onPlatformMessage once the framework is moved over
// to using channel buffers exclusively.
PlatformMessageCallback? get onPlatformMessage => _onPlatformMessage;
PlatformMessageCallback? _onPlatformMessage;
Zone _onPlatformMessageZone = Zone.root;
Expand Down Expand Up @@ -438,13 +441,15 @@ class PlatformDispatcher {
};
}

// Called from the engine, via hooks.dart
/// Send a message to the framework using the [ChannelBuffers].
///
/// This method constructs the appropriate callback to respond
/// with the given `responseId`. It should only be called for messages
/// from the platform.
void _dispatchPlatformMessage(String name, ByteData? data, int responseId) {
if (name == ChannelBuffers.kControlChannelName) {
try {
channelBuffers.handleMessage(data!);
} catch (ex) {
_printDebug('Message to "$name" caused exception $ex');
} finally {
_respondToPlatformMessage(responseId, null);
}
Expand All @@ -454,7 +459,7 @@ class PlatformDispatcher {
_onPlatformMessageZone,
name,
data,
(ByteData? responseData) {
(ByteData? responseData) {
_respondToPlatformMessage(responseId, responseData);
},
);
Expand Down
17 changes: 12 additions & 5 deletions lib/ui/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2273,11 +2273,18 @@ final ByteData _fontChangeMessage = utf8.encoder.convert(
).buffer.asByteData();

FutureOr<void> _sendFontChangeMessage() async {
PlatformDispatcher.instance.onPlatformMessage?.call(
'flutter/system',
_fontChangeMessage,
(_) {},
);
const String kSystemChannelName = 'flutter/system';
if (PlatformDispatcher.instance.onPlatformMessage != null) {
_invoke3<String, ByteData?, PlatformMessageResponseCallback>(
PlatformDispatcher.instance.onPlatformMessage,
PlatformDispatcher.instance._onPlatformMessageZone,
kSystemChannelName,
_fontChangeMessage,
(ByteData? responseData) { },
);
} else {
channelBuffers.push(kSystemChannelName, _fontChangeMessage, (ByteData? responseData) { });
}
}

// TODO(gspencergoog): remove this template block once the framework templates
Expand Down
1 change: 1 addition & 0 deletions lib/ui/window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,7 @@ class SingletonFlutterWindow extends FlutterWindow {
///
/// The framework invokes this callback in the same zone in which the
/// callback was set.
// TODO(ianh): deprecate once framework uses [ChannelBuffers.setListener].
PlatformMessageCallback? get onPlatformMessage => platformDispatcher.onPlatformMessage;
set onPlatformMessage(PlatformMessageCallback? callback) {
platformDispatcher.onPlatformMessage = callback;
Expand Down
4 changes: 0 additions & 4 deletions lib/web_ui/lib/src/engine/keyboard.dart
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,6 @@ class Keyboard {

final html.KeyboardEvent keyboardEvent = event;

if (EnginePlatformDispatcher.instance._onPlatformMessage == null) {
return;
}

if (_shouldPreventDefault(event)) {
event.preventDefault();
}
Expand Down
48 changes: 21 additions & 27 deletions lib/web_ui/lib/src/engine/navigation/history.dart
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,15 @@ class MultiEntriesBrowserHistory extends BrowserHistory {
currentPath);
}
_lastSeenSerialCount = _currentSerialCount;
if (EnginePlatformDispatcher.instance._onPlatformMessage != null) {
EnginePlatformDispatcher.instance.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRouteInformation', <dynamic, dynamic>{
'location': currentPath,
'state': event.state?['state'],
})),
(_) {},
);
}
EnginePlatformDispatcher.instance.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRouteInformation', <dynamic, dynamic>{
'location': currentPath,
'state': event.state?['state'],
})),
(_) {},
);
}

@override
Expand Down Expand Up @@ -272,13 +270,11 @@ class SingleEntryBrowserHistory extends BrowserHistory {
_setupFlutterEntry(urlStrategy!);

// 2. Send a 'popRoute' platform message so the app can handle it accordingly.
if (EnginePlatformDispatcher.instance._onPlatformMessage != null) {
EnginePlatformDispatcher.instance.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(_popRouteMethodCall),
(_) {},
);
}
EnginePlatformDispatcher.instance.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(_popRouteMethodCall),
(_) {},
);
} else if (_isFlutterEntry(event.state)) {
// We get into this scenario when the user changes the url manually. It
// causes a new entry to be pushed on top of our "flutter" one. When this
Expand All @@ -291,15 +287,13 @@ class SingleEntryBrowserHistory extends BrowserHistory {
_userProvidedRouteName = null;

// Send a 'pushRoute' platform message so the app handles it accordingly.
if (EnginePlatformDispatcher.instance._onPlatformMessage != null) {
EnginePlatformDispatcher.instance.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRoute', newRouteName),
),
(_) {},
);
}
EnginePlatformDispatcher.instance.invokeOnPlatformMessage(
'flutter/navigation',
const JSONMethodCodec().encodeMethodCall(
MethodCall('pushRoute', newRouteName),
),
(_) {},
);
} else {
// The user has pushed a new entry on top of our flutter entry. This could
// happen when the user modifies the hash part of the url directly, for
Expand Down
Loading