Skip to content

Commit

Permalink
Add deprecations to PlatformMessage stuff (flutter#42580)
Browse files Browse the repository at this point in the history
Fixes old TODOs originally added in flutter#22181.
The framework appears to be fully migrated off these.
  • Loading branch information
goderbauer authored Jun 15, 2023
1 parent d4717bd commit cfbd7c7
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 105 deletions.
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

0 comments on commit cfbd7c7

Please sign in to comment.