mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
[flutter_tools] always use device.stopApp (#83803)
This commit is contained in:
parent
4d289ca634
commit
f666f93dbb
@ -344,49 +344,10 @@ class FlutterDevice {
|
|||||||
Future<void> exitApps({
|
Future<void> exitApps({
|
||||||
@visibleForTesting Duration timeoutDelay = const Duration(seconds: 10),
|
@visibleForTesting Duration timeoutDelay = const Duration(seconds: 10),
|
||||||
}) async {
|
}) async {
|
||||||
if (!device.supportsFlutterExit || vmService == null) {
|
// TODO(jonahwilliams): https://github.com/flutter/flutter/issues/83127
|
||||||
return device.stopApp(package, userIdentifier: userIdentifier);
|
// When updating `flutter attach` to support running without a device,
|
||||||
}
|
// this will need to be changed to fall back to io exit.
|
||||||
final List<FlutterView> views = await vmService.getFlutterViews();
|
return device.stopApp(package, userIdentifier: userIdentifier);
|
||||||
if (views == null || views.isEmpty) {
|
|
||||||
return device.stopApp(package, userIdentifier: userIdentifier);
|
|
||||||
}
|
|
||||||
// If any of the flutter views are paused, we might not be able to
|
|
||||||
// cleanly exit since the service extension may not have been registered.
|
|
||||||
for (final FlutterView flutterView in views) {
|
|
||||||
final vm_service.Isolate isolate = await vmService
|
|
||||||
.getIsolateOrNull(flutterView.uiIsolate.id);
|
|
||||||
if (isolate == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (isPauseEvent(isolate.pauseEvent.kind)) {
|
|
||||||
return device.stopApp(package, userIdentifier: userIdentifier);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (final FlutterView view in views) {
|
|
||||||
if (view != null && view.uiIsolate != null) {
|
|
||||||
// If successful, there will be no response from flutterExit. If the exit
|
|
||||||
// method is not registered, this will complete with `false`.
|
|
||||||
unawaited(vmService.flutterExit(
|
|
||||||
isolateId: view.uiIsolate.id,
|
|
||||||
).then((bool exited) async {
|
|
||||||
// If exiting the app failed, fall back to stopApp
|
|
||||||
if (!exited) {
|
|
||||||
await device.stopApp(package, userIdentifier: userIdentifier);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return vmService.service.onDone
|
|
||||||
.catchError((dynamic error, StackTrace stackTrace) {
|
|
||||||
globals.logger.printError(
|
|
||||||
'unhandled error waiting for vm service exit:\n $error',
|
|
||||||
stackTrace: stackTrace,
|
|
||||||
);
|
|
||||||
})
|
|
||||||
.timeout(timeoutDelay, onTimeout: () {
|
|
||||||
return device.stopApp(package, userIdentifier: userIdentifier);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Uri> setupDevFS(
|
Future<Uri> setupDevFS(
|
||||||
|
@ -1655,71 +1655,6 @@ void main() {
|
|||||||
expect(await result, 0);
|
expect(await result, 0);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
testUsingContext('FlutterDevice will not exit a paused isolate', () => testbed.run(() async {
|
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: '_flutter.listViews',
|
|
||||||
jsonResponse: <String, Object>{
|
|
||||||
'views': <Object>[
|
|
||||||
fakeFlutterView.toJson(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: 'getIsolate',
|
|
||||||
args: <String, Object>{
|
|
||||||
'isolateId': fakeUnpausedIsolate.id,
|
|
||||||
},
|
|
||||||
jsonResponse: fakePausedIsolate.toJson(),
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
final TestFlutterDevice flutterDevice = TestFlutterDevice(
|
|
||||||
mockDevice,
|
|
||||||
);
|
|
||||||
flutterDevice.vmService = fakeVmServiceHost.vmService;
|
|
||||||
|
|
||||||
await flutterDevice.exitApps();
|
|
||||||
|
|
||||||
expect(mockDevice.appStopped, true);
|
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
testUsingContext('FlutterDevice will exit an isolate that did not register the exit extension method', () => testbed.run(() async {
|
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: '_flutter.listViews',
|
|
||||||
jsonResponse: <String, Object>{
|
|
||||||
'views': <Object>[
|
|
||||||
fakeFlutterView.toJson(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: 'getIsolate',
|
|
||||||
args: <String, Object>{
|
|
||||||
'isolateId': fakeUnpausedIsolate.id,
|
|
||||||
},
|
|
||||||
jsonResponse: fakeUnpausedIsolate.toJson(),
|
|
||||||
),
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: 'ext.flutter.exit',
|
|
||||||
args: <String, Object>{
|
|
||||||
'isolateId': fakeUnpausedIsolate.id,
|
|
||||||
},
|
|
||||||
errorCode: RPCErrorCodes.kMethodNotFound,
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
final TestFlutterDevice flutterDevice = TestFlutterDevice(
|
|
||||||
mockDevice,
|
|
||||||
);
|
|
||||||
flutterDevice.vmService = fakeVmServiceHost.vmService;
|
|
||||||
|
|
||||||
await flutterDevice.exitApps(timeoutDelay: Duration.zero);
|
|
||||||
|
|
||||||
expect(mockDevice.appStopped, true);
|
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
testUsingContext('FlutterDevice can exit from a release mode isolate with no VmService', () => testbed.run(() async {
|
testUsingContext('FlutterDevice can exit from a release mode isolate with no VmService', () => testbed.run(() async {
|
||||||
final TestFlutterDevice flutterDevice = TestFlutterDevice(
|
final TestFlutterDevice flutterDevice = TestFlutterDevice(
|
||||||
mockDevice,
|
mockDevice,
|
||||||
@ -1730,70 +1665,8 @@ void main() {
|
|||||||
expect(mockDevice.appStopped, true);
|
expect(mockDevice.appStopped, true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
testUsingContext('FlutterDevice will call stopApp if the exit request times out', () => testbed.run(() async {
|
testUsingContext('FlutterDevice will exit an un-paused isolate using stopApp', () => testbed.run(() async {
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: '_flutter.listViews',
|
|
||||||
jsonResponse: <String, Object>{
|
|
||||||
'views': <Object>[
|
|
||||||
fakeFlutterView.toJson(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: 'getIsolate',
|
|
||||||
args: <String, Object>{
|
|
||||||
'isolateId': fakeUnpausedIsolate.id,
|
|
||||||
},
|
|
||||||
jsonResponse: fakeUnpausedIsolate.toJson(),
|
|
||||||
),
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: 'ext.flutter.exit',
|
|
||||||
args: <String, Object>{
|
|
||||||
'isolateId': fakeUnpausedIsolate.id,
|
|
||||||
},
|
|
||||||
// Intentionally do not close isolate.
|
|
||||||
close: false,
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
final TestFlutterDevice flutterDevice = TestFlutterDevice(
|
|
||||||
mockDevice,
|
|
||||||
);
|
|
||||||
flutterDevice.vmService = fakeVmServiceHost.vmService;
|
|
||||||
|
|
||||||
await flutterDevice.exitApps(
|
|
||||||
timeoutDelay: Duration.zero,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(mockDevice.appStopped, true);
|
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
|
||||||
}));
|
|
||||||
|
|
||||||
testUsingContext('FlutterDevice will exit an un-paused isolate', () => testbed.run(() async {
|
|
||||||
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: kListViewsMethod,
|
|
||||||
jsonResponse: <String, Object>{
|
|
||||||
'views': <Object>[
|
|
||||||
fakeFlutterView.toJson(),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
),
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: 'getIsolate',
|
|
||||||
args: <String, Object>{
|
|
||||||
'isolateId': fakeUnpausedIsolate.id
|
|
||||||
},
|
|
||||||
jsonResponse: fakeUnpausedIsolate.toJson(),
|
|
||||||
),
|
|
||||||
FakeVmServiceRequest(
|
|
||||||
method: 'ext.flutter.exit',
|
|
||||||
args: <String, Object>{
|
|
||||||
'isolateId': fakeUnpausedIsolate.id,
|
|
||||||
},
|
|
||||||
close: true,
|
|
||||||
)
|
|
||||||
]);
|
|
||||||
final TestFlutterDevice flutterDevice = TestFlutterDevice(
|
final TestFlutterDevice flutterDevice = TestFlutterDevice(
|
||||||
mockDevice,
|
mockDevice,
|
||||||
);
|
);
|
||||||
@ -1802,6 +1675,7 @@ void main() {
|
|||||||
final Future<void> exitFuture = flutterDevice.exitApps();
|
final Future<void> exitFuture = flutterDevice.exitApps();
|
||||||
|
|
||||||
await expectLater(exitFuture, completes);
|
await expectLater(exitFuture, completes);
|
||||||
|
expect(mockDevice.appStopped, true);
|
||||||
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
expect(fakeVmServiceHost.hasRemainingExpectations, false);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user