Skip to content

Commit 3494c08

Browse files
authored
[flutter_tools/dap] Inform DAP client whether restart is supported (flutter#121610)
[flutter_tools/dap] Inform DAP client whether restart is supported
1 parent 4ab053c commit 3494c08

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

packages/flutter_tools/lib/src/debug_adapters/flutter_adapter.dart

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,6 @@ class FlutterDebugAdapter extends FlutterBaseDebugAdapter {
4848
/// their handlers.
4949
final Map<int, Completer<Object?>> _flutterRequestCompleters = <int, Completer<Object?>>{};
5050

51-
/// Whether or not this adapter can handle the restartRequest.
52-
///
53-
/// For Flutter apps we can handle this with a Hot Restart rather than having
54-
/// the whole debug session stopped and restarted.
55-
@override
56-
bool get supportsRestartRequest => true;
57-
5851
/// A list of reverse-requests from `flutter run --machine` that should be forwarded to the client.
5952
static const Set<String> _requestsToForwardToClient = <String>{
6053
// The 'app.exposeUrl' request is sent by Flutter to request the client
@@ -399,6 +392,12 @@ class FlutterDebugAdapter extends FlutterBaseDebugAdapter {
399392
if (_appId == null) {
400393
throw DebugAdapterException('Unexpected null `appId` in app.start event');
401394
}
395+
396+
// Notify the client whether it can call 'restartRequest' when the user
397+
// clicks restart, instead of terminating and re-starting its own debug
398+
// session (which is much slower, but required for profile/release mode).
399+
final bool supportsRestart = (params['supportsRestart'] as bool?) ?? false;
400+
sendEvent(CapabilitiesEventBody(capabilities: Capabilities(supportsRestartRequest: supportsRestart)));
402401
}
403402

404403
/// Handles the app.started event from Flutter.

packages/flutter_tools/test/general.shard/dap/flutter_adapter_test.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,44 @@ void main() {
101101
expect(adapter.pidsToTerminate, isNot(contains(123)));
102102
});
103103

104+
105+
group('supportsRestartRequest', () {
106+
void testRestartSupport(bool supportsRestart) {
107+
test('notifies client for supportsRestart: $supportsRestart', () async {
108+
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
109+
fileSystem: MemoryFileSystem.test(style: fsStyle),
110+
platform: platform,
111+
supportsRestart: supportsRestart,
112+
);
113+
114+
final FlutterLaunchRequestArguments args = FlutterLaunchRequestArguments(
115+
cwd: '/project',
116+
program: 'foo.dart',
117+
);
118+
119+
// Listen for a Capabilities event that modifies 'supportsRestartRequest'.
120+
final Future<CapabilitiesEventBody> capabilitiesUpdate = adapter
121+
.dapToClientMessages
122+
.where((Map<String, Object?> message) => message['event'] == 'capabilities')
123+
.map((Map<String, Object?> message) => message['body'] as Map<String, Object?>?)
124+
.where((Map<String, Object?>? body) => body != null).cast<Map<String, Object?>>()
125+
.map(CapabilitiesEventBody.fromJson)
126+
.firstWhere((CapabilitiesEventBody body) => body.capabilities.supportsRestartRequest != null);
127+
128+
await adapter.configurationDoneRequest(MockRequest(), null, () {});
129+
final Completer<void> launchCompleter = Completer<void>();
130+
await adapter.launchRequest(MockRequest(), args, launchCompleter.complete);
131+
await launchCompleter.future;
132+
133+
// Ensure the Capabilities update has the expected value.
134+
expect((await capabilitiesUpdate).capabilities.supportsRestartRequest, supportsRestart);
135+
});
136+
}
137+
138+
testRestartSupport(true);
139+
testRestartSupport(false);
140+
});
141+
104142
test('calls "app.stop" on terminateRequest', () async {
105143
final MockFlutterDebugAdapter adapter = MockFlutterDebugAdapter(
106144
fileSystem: MemoryFileSystem.test(style: fsStyle),

packages/flutter_tools/test/general.shard/dap/mocks.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
1818
required FileSystem fileSystem,
1919
required Platform platform,
2020
bool simulateAppStarted = true,
21+
bool supportsRestart = true,
2122
FutureOr<void> Function(MockFlutterDebugAdapter adapter)? preAppStart,
2223
}) {
2324
final StreamController<List<int>> stdinController = StreamController<List<int>>();
@@ -31,6 +32,7 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
3132
fileSystem: fileSystem,
3233
platform: platform,
3334
simulateAppStarted: simulateAppStarted,
35+
supportsRestart: supportsRestart,
3436
preAppStart: preAppStart,
3537
);
3638
}
@@ -41,6 +43,7 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
4143
required super.fileSystem,
4244
required super.platform,
4345
this.simulateAppStarted = true,
46+
this.supportsRestart = true,
4447
this.preAppStart,
4548
}) {
4649
clientChannel.listen((ProtocolMessage message) {
@@ -51,6 +54,7 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
5154
int _seq = 1;
5255
final ByteStreamServerChannel clientChannel;
5356
final bool simulateAppStarted;
57+
final bool supportsRestart;
5458
final FutureOr<void> Function(MockFlutterDebugAdapter adapter)? preAppStart;
5559

5660
late String executable;
@@ -110,6 +114,7 @@ class MockFlutterDebugAdapter extends FlutterDebugAdapter {
110114
'event': 'app.start',
111115
'params': <String, Object?>{
112116
'appId': 'TEST',
117+
'supportsRestart': supportsRestart,
113118
}
114119
});
115120
}

0 commit comments

Comments
 (0)