[flutter_tools] Forward app.webLaunchUrl event from Flutter to DAP clients (#116275)
* [flutter_tools] Forward app.webLaunchUrl event from Flutter to DAP clients Fixes https://github.com/Dart-Code/Dart-Code/issues/4292. * Update packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart Co-authored-by: Christopher Fujino <fujino@google.com> * Another static const instead of final Co-authored-by: Christopher Fujino <fujino@google.com>
This commit is contained in:
parent
fcc8ea1177
commit
a29796e339
@ -51,7 +51,7 @@ class FlutterDebugAdapter extends FlutterBaseDebugAdapter {
|
|||||||
bool get supportsRestartRequest => true;
|
bool get supportsRestartRequest => true;
|
||||||
|
|
||||||
/// A list of reverse-requests from `flutter run --machine` that should be forwarded to the client.
|
/// A list of reverse-requests from `flutter run --machine` that should be forwarded to the client.
|
||||||
final Set<String> _requestsToForwardToClient = <String>{
|
static const Set<String> _requestsToForwardToClient = <String>{
|
||||||
// The 'app.exposeUrl' request is sent by Flutter to request the client
|
// The 'app.exposeUrl' request is sent by Flutter to request the client
|
||||||
// exposes a URL to the user and return the public version of that URL.
|
// exposes a URL to the user and return the public version of that URL.
|
||||||
//
|
//
|
||||||
@ -65,6 +65,14 @@ class FlutterDebugAdapter extends FlutterBaseDebugAdapter {
|
|||||||
'app.exposeUrl',
|
'app.exposeUrl',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// A list of events from `flutter run --machine` that should be forwarded to the client.
|
||||||
|
static const Set<String> _eventsToForwardToClient = <String>{
|
||||||
|
// The 'app.webLaunchUrl' event is sent to the client to tell it about a URL
|
||||||
|
// that should be launched (including a flag for whether it has been
|
||||||
|
// launched by the tool or needs launching by the editor).
|
||||||
|
'app.webLaunchUrl',
|
||||||
|
};
|
||||||
|
|
||||||
/// Completers for reverse requests from Flutter that may need to be handled by the client.
|
/// Completers for reverse requests from Flutter that may need to be handled by the client.
|
||||||
final Map<Object, Completer<Object?>> _reverseRequestCompleters = <Object, Completer<Object?>>{};
|
final Map<Object, Completer<Object?>> _reverseRequestCompleters = <Object, Completer<Object?>>{};
|
||||||
|
|
||||||
@ -454,6 +462,17 @@ class FlutterDebugAdapter extends FlutterBaseDebugAdapter {
|
|||||||
_handleAppStarted();
|
_handleAppStarted();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_eventsToForwardToClient.contains(event)) {
|
||||||
|
// Forward the event to the client.
|
||||||
|
sendEvent(
|
||||||
|
RawEventBody(<String, Object?>{
|
||||||
|
'event': event,
|
||||||
|
'params': params,
|
||||||
|
}),
|
||||||
|
eventType: 'flutter.forwardedEvent',
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Handles incoming reverse requests from `flutter run --machine`.
|
/// Handles incoming reverse requests from `flutter run --machine`.
|
||||||
|
@ -121,7 +121,7 @@ void main() {
|
|||||||
await adapter.terminateRequest(MockRequest(), TerminateArguments(restart: false), terminateCompleter.complete);
|
await adapter.terminateRequest(MockRequest(), TerminateArguments(restart: false), terminateCompleter.complete);
|
||||||
await terminateCompleter.future;
|
await terminateCompleter.future;
|
||||||
|
|
||||||
expect(adapter.flutterRequests, contains('app.stop'));
|
expect(adapter.dapToFlutterRequests, contains('app.stop'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('does not call "app.stop" on terminateRequest if app was not started', () async {
|
test('does not call "app.stop" on terminateRequest if app was not started', () async {
|
||||||
@ -145,7 +145,7 @@ void main() {
|
|||||||
await adapter.terminateRequest(MockRequest(), TerminateArguments(restart: false), terminateCompleter.complete);
|
await adapter.terminateRequest(MockRequest(), TerminateArguments(restart: false), terminateCompleter.complete);
|
||||||
await terminateCompleter.future;
|
await terminateCompleter.future;
|
||||||
|
|
||||||
expect(adapter.flutterRequests, isNot(contains('app.stop')));
|
expect(adapter.dapToFlutterRequests, isNot(contains('app.stop')));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -210,7 +210,39 @@ void main() {
|
|||||||
await adapter.terminateRequest(MockRequest(), TerminateArguments(restart: false), terminateCompleter.complete);
|
await adapter.terminateRequest(MockRequest(), TerminateArguments(restart: false), terminateCompleter.complete);
|
||||||
await terminateCompleter.future;
|
await terminateCompleter.future;
|
||||||
|
|
||||||
expect(adapter.flutterRequests, contains('app.detach'));
|
expect(adapter.dapToFlutterRequests, contains('app.detach'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('forwards events', () {
|
||||||
|
test('app.webLaunchUrl', () async {
|
||||||
|
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
|
||||||
|
fileSystem: MemoryFileSystem.test(style: fsStyle),
|
||||||
|
platform: platform,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Simulate Flutter asking for a URL to be launched.
|
||||||
|
adapter.simulateStdoutMessage(<String, Object?>{
|
||||||
|
'event': 'app.webLaunchUrl',
|
||||||
|
'params': <String, Object?>{
|
||||||
|
'url': 'http://localhost:123/',
|
||||||
|
'launched': false,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Allow the handler to be processed.
|
||||||
|
await pumpEventQueue(times: 5000);
|
||||||
|
|
||||||
|
// Find the forwarded event.
|
||||||
|
final Map<String, Object?> message = adapter.dapToClientMessages.singleWhere((Map<String, Object?> data) => data['event'] == 'flutter.forwardedEvent');
|
||||||
|
// Ensure the body of the event matches the original event sent by Flutter.
|
||||||
|
expect(message['body'], <String, Object?>{
|
||||||
|
'event': 'app.webLaunchUrl',
|
||||||
|
'params': <String, Object?>{
|
||||||
|
'url': 'http://localhost:123/',
|
||||||
|
'launched': false,
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -238,7 +270,7 @@ void main() {
|
|||||||
// Allow the handler to be processed.
|
// Allow the handler to be processed.
|
||||||
await pumpEventQueue(times: 5000);
|
await pumpEventQueue(times: 5000);
|
||||||
|
|
||||||
final Map<String, Object?> message = adapter.flutterMessages.singleWhere((Map<String, Object?> data) => data['id'] == requestId);
|
final Map<String, Object?> message = adapter.dapToFlutterMessages.singleWhere((Map<String, Object?> data) => data['id'] == requestId);
|
||||||
expect(message['result'], 'http://mapped-host:123/');
|
expect(message['result'], 'http://mapped-host:123/');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -53,11 +53,15 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
|
|||||||
late List<String> processArgs;
|
late List<String> processArgs;
|
||||||
late Map<String, String>? env;
|
late Map<String, String>? env;
|
||||||
|
|
||||||
/// A list of all messages sent to the `flutter run` processes `stdin`.
|
/// A list of all messages sent from the adapter back to the client.
|
||||||
final List<Map<String, Object?>> flutterMessages = <Map<String, Object?>>[];
|
final List<Map<String, Object?>> dapToClientMessages = <Map<String, Object?>>[];
|
||||||
|
|
||||||
/// The `method`s of all requests send to the `flutter run` processes `stdin`.
|
/// A list of all messages sent from the adapter to the `flutter run` processes `stdin`.
|
||||||
List<String> get flutterRequests => flutterMessages
|
final List<Map<String, Object?>> dapToFlutterMessages = <Map<String, Object?>>[];
|
||||||
|
|
||||||
|
/// The `method`s of all mesages sent to the `flutter run` processes `stdin`
|
||||||
|
/// by the debug adapter.
|
||||||
|
List<String> get dapToFlutterRequests => dapToFlutterMessages
|
||||||
.map((Map<String, Object?> message) => message['method'] as String?)
|
.map((Map<String, Object?> message) => message['method'] as String?)
|
||||||
.whereNotNull()
|
.whereNotNull()
|
||||||
.toList();
|
.toList();
|
||||||
@ -92,6 +96,8 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
|
|||||||
|
|
||||||
/// Handles messages sent from the debug adapter back to the client.
|
/// Handles messages sent from the debug adapter back to the client.
|
||||||
void _handleDapToClientMessage(ProtocolMessage message) {
|
void _handleDapToClientMessage(ProtocolMessage message) {
|
||||||
|
dapToClientMessages.add(message.toJson());
|
||||||
|
|
||||||
// Pretend to be the client, delegating any reverse-requests to the relevant
|
// Pretend to be the client, delegating any reverse-requests to the relevant
|
||||||
// handler that is provided by the test.
|
// handler that is provided by the test.
|
||||||
if (message is Event && message.event == 'flutter.forwardedRequest') {
|
if (message is Event && message.event == 'flutter.forwardedRequest') {
|
||||||
@ -133,7 +139,7 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void sendFlutterMessage(Map<String, Object?> message) {
|
void sendFlutterMessage(Map<String, Object?> message) {
|
||||||
flutterMessages.add(message);
|
dapToFlutterMessages.add(message);
|
||||||
// Don't call super because it will try to write to the process that we
|
// Don't call super because it will try to write to the process that we
|
||||||
// didn't actually spawn.
|
// didn't actually spawn.
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user