mirror of
https://github.com/flutter/flutter
synced 2024-08-24 18:36:03 +00:00
[flutter_tool] [dap] Forward Flutter progress events to DAP client (#142524)
Builds can be slow and the legacy debug adapter would handle Flutter's `app.progress` events to update the toast notification during builds. This was lost in the new adapters - we should only a single "Launching.." notification for the whole progress. This change listens to `app.progress` events and forwards those with `finished=false` to the client if the launch progress is still active. Fixes https://github.com/Dart-Code/Dart-Code/issues/4938 https://github.com/flutter/flutter/assets/1078012/8c60cf08-e034-4a72-b31e-9c61dca388bf
This commit is contained in:
parent
7082ae1517
commit
86613d198e
|
@ -420,6 +420,19 @@ class FlutterDebugAdapter extends FlutterBaseDebugAdapter with VmServiceInfoFile
|
|||
);
|
||||
}
|
||||
|
||||
/// Handles any app.progress event from Flutter.
|
||||
void _handleAppProgress(Map<String, Object?> params) {
|
||||
// If this is a new progress starting (and we're still launching), update
|
||||
// the progress notification.
|
||||
//
|
||||
// We ignore finished status because we have a limited API - the next
|
||||
// item will replace it (or the launch progress will be completed by
|
||||
// _handleAppStarted).
|
||||
if (params case {'message': final String message, 'finished': false}) {
|
||||
launchProgress?.update(message: message);
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles the app.started event from Flutter.
|
||||
Future<void> _handleAppStarted() async {
|
||||
launchProgress?.end();
|
||||
|
@ -481,6 +494,8 @@ class FlutterDebugAdapter extends FlutterBaseDebugAdapter with VmServiceInfoFile
|
|||
_handleDebugPort(params);
|
||||
case 'app.start':
|
||||
_handleAppStart(params);
|
||||
case 'app.progress':
|
||||
_handleAppProgress(params);
|
||||
case 'app.started':
|
||||
_handleAppStarted();
|
||||
}
|
||||
|
|
|
@ -210,6 +210,45 @@ void main() {
|
|||
expect(adapter.dapToFlutterRequests, isNot(contains('app.restart')));
|
||||
});
|
||||
|
||||
test('includes build progress updates', () async {
|
||||
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
|
||||
fileSystem: MemoryFileSystem.test(style: fsStyle),
|
||||
platform: platform,
|
||||
);
|
||||
final Completer<void> responseCompleter = Completer<void>();
|
||||
|
||||
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
|
||||
cwd: '.',
|
||||
program: 'foo.dart',
|
||||
);
|
||||
|
||||
// Begin listening for progress events up until `progressEnd` (but don't await yet).
|
||||
final Future<List<List<Object?>>> progressEventsFuture =
|
||||
adapter.dapToClientProgressEvents
|
||||
.takeWhile((Map<String, Object?> message) => message['event'] != 'progressEnd')
|
||||
.map((Map<String, Object?> message) => <Object?>[message['event'], (message['body']! as Map<String, Object?>)['message']])
|
||||
.toList();
|
||||
|
||||
// Initialize with progress support.
|
||||
await adapter.initializeRequest(
|
||||
MockRequest(),
|
||||
InitializeRequestArguments(adapterID: 'test', supportsProgressReporting: true, ),
|
||||
(_) {},
|
||||
);
|
||||
await adapter.configurationDoneRequest(MockRequest(), null, () {});
|
||||
await adapter.launchRequest(MockRequest(), args, responseCompleter.complete);
|
||||
await responseCompleter.future;
|
||||
|
||||
// Ensure we got the expected events prior to the progressEnd.
|
||||
final List<List<Object?>> progressEvents = await progressEventsFuture;
|
||||
expect(progressEvents, containsAllInOrder(<List<String?>>[
|
||||
<String?>['progressStart', 'Launching…'],
|
||||
<String?>['progressUpdate', 'Step 1…'],
|
||||
<String?>['progressUpdate', 'Step 2…'],
|
||||
// progressEnd isn't included because we used takeWhile to stop when it arrived above.
|
||||
]));
|
||||
});
|
||||
|
||||
test('includes Dart Debug extension progress update', () async {
|
||||
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
|
||||
fileSystem: MemoryFileSystem.test(style: fsStyle),
|
||||
|
@ -242,7 +281,7 @@ void main() {
|
|||
await adapter.launchRequest(MockRequest(), args, responseCompleter.complete);
|
||||
await responseCompleter.future;
|
||||
|
||||
// Ensure we got the expected events prior to the
|
||||
// Ensure we got the expected events prior to the progressEnd.
|
||||
final List<List<Object?>> progressEvents = await progressEventsFuture;
|
||||
expect(progressEvents, containsAllInOrder(<List<String>>[
|
||||
<String>['progressStart', 'Launching…'],
|
||||
|
|
|
@ -104,9 +104,22 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
|
|||
|
||||
await preAppStart?.call(this);
|
||||
|
||||
void sendLaunchProgress({required bool finished, String? message}) {
|
||||
assert(finished == (message == null));
|
||||
simulateStdoutMessage(<String, Object?>{
|
||||
'event': 'app.progress',
|
||||
'params': <String, Object?>{
|
||||
'id': 'launch',
|
||||
'message': message,
|
||||
'finished': finished,
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Simulate the app starting by triggering handling of events that Flutter
|
||||
// would usually write to stdout.
|
||||
if (simulateAppStarted) {
|
||||
sendLaunchProgress(message: 'Step 1…', finished: false);
|
||||
simulateStdoutMessage(<String, Object?>{
|
||||
'event': 'app.start',
|
||||
'params': <String, Object?>{
|
||||
|
@ -116,6 +129,8 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
|
|||
'mode': 'debug',
|
||||
}
|
||||
});
|
||||
sendLaunchProgress(message: 'Step 2…', finished: false);
|
||||
sendLaunchProgress(finished: true);
|
||||
simulateStdoutMessage(<String, Object?>{
|
||||
'event': 'app.started',
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue