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

Add deprecations to PlatformMessage stuff #42580

Merged
merged 4 commits into from
Jun 15, 2023
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
14 changes: 12 additions & 2 deletions lib/ui/channel_buffers.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@
// KEEP THIS SYNCHRONIZED WITH ../web_ui/lib/channel_buffers.dart
part of dart.ui;

/// Deprecated. Migrate to [ChannelCallback] instead.
///
/// Signature for [ChannelBuffers.drain]'s `callback` argument.
///
/// The first argument is the data sent by the plugin.
///
/// The second argument is a closure that, when called, will send messages
/// back to the plugin.
// TODO(ianh): deprecate this once the framework is migrated to [ChannelCallback].
@Deprecated(
'Migrate to ChannelCallback instead. '
'This feature was deprecated after v3.11.0-20.0.pre.',
)
typedef DrainChannelCallback = Future<void> Function(ByteData? data, PlatformMessageResponseCallback callback);

/// Signature for [ChannelBuffers.setListener]'s `callback` argument.
Expand Down Expand Up @@ -377,14 +382,19 @@ class ChannelBuffers {
}
}

/// Deprecated. Migrate to [setListener] instead.
///
/// Remove and process all stored messages for a given channel.
///
/// This should be called once a channel is prepared to handle messages
/// (i.e. when a message handler is set up in the framework).
///
/// The messages are processed by calling the given `callback`. Each message
/// is processed in its own microtask.
// TODO(ianh): deprecate once framework uses [setListener].
@Deprecated(
'Migrate to setListener instead. '
'This feature was deprecated after v3.11.0-20.0.pre.',
)
Future<void> drain(String name, DrainChannelCallback callback) async {
final _Channel? channel = _channels[name];
while (channel != null && !channel._queue.isEmpty) {
Expand Down
19 changes: 16 additions & 3 deletions lib/ui/platform_dispatcher.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,13 @@ typedef SemanticsActionEventCallback = void Function(SemanticsActionEvent action
/// [PlatformDispatcher.onPlatformMessage].
typedef PlatformMessageResponseCallback = void Function(ByteData? data);

/// Deprecated. Migrate to [ChannelBuffers.setListener] instead.
///
/// Signature for [PlatformDispatcher.onPlatformMessage].
// TODO(ianh): deprecate once framework uses [ChannelBuffers.setListener].
@Deprecated(
'Migrate to ChannelBuffers.setListener instead. '
'This feature was deprecated after v3.11.0-20.0.pre.',
)
typedef PlatformMessageCallback = void Function(String name, ByteData? data, PlatformMessageResponseCallback? callback);

// Signature for _setNeedsReportTimings.
Expand Down Expand Up @@ -651,6 +656,8 @@ class PlatformDispatcher {
@Native<Void Function(Int64)>(symbol: 'PlatformConfigurationNativeApi::RegisterBackgroundIsolate')
external static void __registerBackgroundIsolate(int rootIsolateId);

/// Deprecated. Migrate to [ChannelBuffers.setListener] instead.
///
/// Called whenever this platform dispatcher receives a message from a
/// platform-specific plugin.
///
Expand All @@ -664,11 +671,17 @@ 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.
@Deprecated(
'Migrate to ChannelBuffers.setListener instead. '
'This feature was deprecated after v3.11.0-20.0.pre.',
)
PlatformMessageCallback? get onPlatformMessage => _onPlatformMessage;
PlatformMessageCallback? _onPlatformMessage;
Zone _onPlatformMessageZone = Zone.root;
@Deprecated(
'Migrate to ChannelBuffers.setListener instead. '
'This feature was deprecated after v3.11.0-20.0.pre.',
)
set onPlatformMessage(PlatformMessageCallback? callback) {
_onPlatformMessage = callback;
_onPlatformMessageZone = Zone.current;
Expand Down
11 changes: 10 additions & 1 deletion lib/ui/window.dart
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,8 @@ class SingletonFlutterWindow extends FlutterView {
platformDispatcher.sendPlatformMessage(name, data, callback);
}

/// Deprecated. Migrate to [ChannelBuffers.setListener] instead.
///
/// Called whenever this window receives a message from a platform-specific
/// plugin.
///
Expand All @@ -802,8 +804,15 @@ class SingletonFlutterWindow extends FlutterView {
///
/// The framework invokes this callback in the same zone in which the
/// callback was set.
// TODO(ianh): deprecate once framework uses [ChannelBuffers.setListener].
@Deprecated(
'Migrate to ChannelBuffers.setListener instead. '
'This feature was deprecated after v3.11.0-20.0.pre.',
)
PlatformMessageCallback? get onPlatformMessage => platformDispatcher.onPlatformMessage;
@Deprecated(
'Migrate to ChannelBuffers.setListener instead. '
'This feature was deprecated after v3.11.0-20.0.pre.',
)
set onPlatformMessage(PlatformMessageCallback? callback) {
platformDispatcher.onPlatformMessage = callback;
}
Expand Down
18 changes: 18 additions & 0 deletions testing/dart/channel_buffers_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ void main() {
called = true;
}
buffers.push(channel, data, callback);
// Ignoring the deprecated member use because we're specifically testing
// deprecated API.
// ignore: deprecated_member_use
await buffers.drain(channel, (ByteData? drainedData, ui.PlatformMessageResponseCallback drainedCallback) async {
expect(drainedData, equals(data));
assert(!called);
Expand All @@ -52,6 +55,9 @@ void main() {

// Ignoring the returned future because the completion of the drain is
// communicated using the `completer`.
// Ignoring the deprecated member use because we're specifically testing
// deprecated API.
// ignore: deprecated_member_use
buffers.drain(channel, (ByteData? drainedData, ui.PlatformMessageResponseCallback drainedCallback) async {
log.add('callback');
completer.complete();
Expand All @@ -77,6 +83,9 @@ void main() {
_resize(buffers, channel, 0);
buffers.push(channel, data, callback);
bool didCall = false;
// Ignoring the deprecated member use because we're specifically testing
// deprecated API.
// ignore: deprecated_member_use
await buffers.drain(channel, (ByteData? drainedData, ui.PlatformMessageResponseCallback drainedCallback) async {
didCall = true;
});
Expand All @@ -87,6 +96,9 @@ void main() {
const String channel = 'foo';
final ui.ChannelBuffers buffers = ui.ChannelBuffers();
bool didCall = false;
// Ignoring the deprecated member use because we're specifically testing
// deprecated API.
// ignore: deprecated_member_use
await buffers.drain(channel, (ByteData? drainedData, ui.PlatformMessageResponseCallback drainedCallback) async {
didCall = true;
});
Expand All @@ -107,6 +119,9 @@ void main() {
buffers.push(channel, three, callback);
buffers.push(channel, four, callback);
int counter = 0;
// Ignoring the deprecated member use because we're specifically testing
// deprecated API.
// ignore: deprecated_member_use
await buffers.drain(channel, (ByteData? drainedData, ui.PlatformMessageResponseCallback drainedCallback) async {
switch (counter) {
case 0:
Expand All @@ -132,6 +147,9 @@ void main() {
buffers.push(channel, two, callback);
_resize(buffers, channel, 1);
int counter = 0;
// Ignoring the deprecated member use because we're specifically testing
// deprecated API.
// ignore: deprecated_member_use
await buffers.drain(channel, (ByteData? drainedData, ui.PlatformMessageResponseCallback drainedCallback) async {
switch (counter) {
case 0:
Expand Down
40 changes: 11 additions & 29 deletions testing/dart/observatory/vmservice_methods_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,15 @@ void main() {
fail('This test must not be run with --disable-vm-service.');
}

final Completer<PlatformResponse> completer = Completer<PlatformResponse>();
ui.PlatformDispatcher.instance.onPlatformMessage = (String name, ByteData? data, ui.PlatformMessageResponseCallback? callback) {
final ByteBuffer buffer = data!.buffer;
final Uint8List list = buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
completer.complete(PlatformResponse(name: name, contents: utf8.decode(list)));
};
final Completer<String> completer = Completer<String>();
ui.channelBuffers.setListener(
'flutter/system',
(ByteData? data, ui.PlatformMessageResponseCallback callback) {
final ByteBuffer buffer = data!.buffer;
final Uint8List list = buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
completer.complete(utf8.decode(list));
},
);

vmService = await vmServiceConnectUri(
'ws://localhost:${info.serverUri!.port}${info.serverUri!.path}ws',
Expand All @@ -94,13 +97,11 @@ void main() {
expect(fontChangeResponse.type, 'Success');
expect(
await completer.future,
const PlatformResponse(
name: 'flutter/system',
contents: '{"type":"fontsChange"}',
),
'{"type":"fontsChange"}',
);
} finally {
await vmService?.dispose();
ui.channelBuffers.clearListener('flutter/system');
}
});
}
Expand All @@ -121,22 +122,3 @@ Future<String?> getIsolateId(vms.VmService vmService) async {
}
return null;
}

class PlatformResponse {
const PlatformResponse({
required this.name,
required this.contents,
});

final String name;
final String contents;

@override
bool operator ==(Object other) =>
other is PlatformResponse &&
other.name == name &&
other.contents == contents;

@override
int get hashCode => Object.hash(name, contents);
}
19 changes: 9 additions & 10 deletions testing/dart/text_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -195,20 +195,19 @@ void testTextRange() {

void testLoadFontFromList() {
test('loadFontFromList will send platform message after font is loaded', () async {
final PlatformMessageCallback? oldHandler = PlatformDispatcher.instance.onPlatformMessage;
late String actualName;
late String message;
PlatformDispatcher.instance.onPlatformMessage = (String name, ByteData? data, PlatformMessageResponseCallback? callback) {
assert(data != null);
actualName = name;
final Uint8List list = data!.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
message = utf8.decode(list);
};
channelBuffers.setListener(
'flutter/system',
(ByteData? data, PlatformMessageResponseCallback? callback) {
assert(data != null);
final Uint8List list = data!.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes);
message = utf8.decode(list);
},
);
final Uint8List fontData = Uint8List(0);
await loadFontFromList(fontData, fontFamily: 'fake');
PlatformDispatcher.instance.onPlatformMessage = oldHandler;
expect(actualName, 'flutter/system');
expect(message, '{"type":"fontsChange"}');
channelBuffers.clearListener('flutter/system');
});
}

Expand Down
26 changes: 7 additions & 19 deletions testing/scenario_app/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@ void main() {
// FlutterView to the _view property.
assert(PlatformDispatcher.instance.implicitView != null);
PlatformDispatcher.instance
..onPlatformMessage = _handlePlatformMessage
..onBeginFrame = _onBeginFrame
..onDrawFrame = _onDrawFrame
..onMetricsChanged = _onMetricsChanged
..onPointerDataPacket = _onPointerDataPacket
..scheduleFrame();
channelBuffers.setListener('driver', _handleDriverMessage);
channelBuffers.setListener('write_timeline', _handleWriteTimelineMessage);

final FlutterView view = PlatformDispatcher.instance.implicitView!;
// Asserting that this is greater than zero since this app runs on different
Expand All @@ -41,7 +42,8 @@ void main() {
/// The FlutterView into which the [Scenario]s will be rendered.
FlutterView get _view => PlatformDispatcher.instance.implicitView!;

void _handleDriverMessage(Map<String, dynamic> call) {
void _handleDriverMessage(ByteData? data, PlatformMessageResponseCallback? callback) {
final Map<String, dynamic> call = json.decode(utf8.decode(data!.buffer.asUint8List())) as Map<String, dynamic>;
final String? methodName = call['method'] as String?;
switch (methodName) {
case 'set_scenario':
Expand All @@ -52,23 +54,9 @@ void _handleDriverMessage(Map<String, dynamic> call) {
}
}

Future<void> _handlePlatformMessage(
String name, ByteData? data, PlatformMessageResponseCallback? callback) async {
if (data != null) {
print('$name = ${utf8.decode(data.buffer.asUint8List())}');
} else {
print(name);
}

switch (name) {
case 'driver':
_handleDriverMessage(json.decode(utf8.decode(data!.buffer.asUint8List())) as Map<String, dynamic>);
case 'write_timeline':
final String timelineData = await _getTimelineData();
callback!(Uint8List.fromList(utf8.encode(timelineData)).buffer.asByteData());
default:
currentScenario?.onPlatformMessage(name, data, callback);
}
Future<void> _handleWriteTimelineMessage(ByteData? data, PlatformMessageResponseCallback? callback) async {
final String timelineData = await _getTimelineData();
callback!(Uint8List.fromList(utf8.encode(timelineData)).buffer.asByteData());
}

Future<String> _getTimelineData() async {
Expand Down
21 changes: 0 additions & 21 deletions testing/scenario_app/lib/src/platform_echo_mixin.dart

This file was deleted.

14 changes: 8 additions & 6 deletions testing/scenario_app/lib/src/platform_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ class MultiPlatformViewBackgroundForegroundScenario extends Scenario
required this.secondId,
}) {
_nextFrame = _firstFrame;
channelBuffers.setListener('flutter/lifecycle', _onPlatformMessage);
}

/// The platform view identifier to use for the first platform view.
Expand Down Expand Up @@ -504,15 +505,10 @@ class MultiPlatformViewBackgroundForegroundScenario extends Scenario

String _lastLifecycleState = '';

@override
void onPlatformMessage(
String name,
void _onPlatformMessage(
ByteData? data,
PlatformMessageResponseCallback? callback,
) {
if (name != 'flutter/lifecycle') {
return;
}
final String message = utf8.decode(data!.buffer.asUint8List());
if (_lastLifecycleState == 'AppLifecycleState.inactive' &&
message == 'AppLifecycleState.resumed') {
Expand All @@ -522,6 +518,12 @@ class MultiPlatformViewBackgroundForegroundScenario extends Scenario

_lastLifecycleState = message;
}

@override
void unmount() {
channelBuffers.clearListener('flutter/lifecycle');
super.unmount();
}
}

/// Platform view with clip rect.
Expand Down
Loading