From f666f93dbb5cd6d1ecdcf1b290da4c68162308c2 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 2 Jun 2021 17:34:02 -0700 Subject: [PATCH] [flutter_tools] always use device.stopApp (#83803) --- .../lib/src/resident_runner.dart | 47 +------ .../general.shard/resident_runner_test.dart | 132 +----------------- 2 files changed, 7 insertions(+), 172 deletions(-) diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index a88d586a1c1..5a686640342 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -344,49 +344,10 @@ class FlutterDevice { Future exitApps({ @visibleForTesting Duration timeoutDelay = const Duration(seconds: 10), }) async { - if (!device.supportsFlutterExit || vmService == null) { - return device.stopApp(package, userIdentifier: userIdentifier); - } - final List views = await vmService.getFlutterViews(); - 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); - }); + // TODO(jonahwilliams): https://github.com/flutter/flutter/issues/83127 + // When updating `flutter attach` to support running without a device, + // this will need to be changed to fall back to io exit. + return device.stopApp(package, userIdentifier: userIdentifier); } Future setupDevFS( diff --git a/packages/flutter_tools/test/general.shard/resident_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_runner_test.dart index 4ba422c4276..f00ba27633a 100644 --- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart @@ -1655,71 +1655,6 @@ void main() { expect(await result, 0); })); - testUsingContext('FlutterDevice will not exit a paused isolate', () => testbed.run(() async { - fakeVmServiceHost = FakeVmServiceHost(requests: [ - FakeVmServiceRequest( - method: '_flutter.listViews', - jsonResponse: { - 'views': [ - fakeFlutterView.toJson(), - ], - }, - ), - FakeVmServiceRequest( - method: 'getIsolate', - args: { - '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: [ - FakeVmServiceRequest( - method: '_flutter.listViews', - jsonResponse: { - 'views': [ - fakeFlutterView.toJson(), - ], - }, - ), - FakeVmServiceRequest( - method: 'getIsolate', - args: { - 'isolateId': fakeUnpausedIsolate.id, - }, - jsonResponse: fakeUnpausedIsolate.toJson(), - ), - FakeVmServiceRequest( - method: 'ext.flutter.exit', - args: { - '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 { final TestFlutterDevice flutterDevice = TestFlutterDevice( mockDevice, @@ -1730,70 +1665,8 @@ void main() { expect(mockDevice.appStopped, true); })); - testUsingContext('FlutterDevice will call stopApp if the exit request times out', () => testbed.run(() async { - fakeVmServiceHost = FakeVmServiceHost(requests: [ - FakeVmServiceRequest( - method: '_flutter.listViews', - jsonResponse: { - 'views': [ - fakeFlutterView.toJson(), - ], - }, - ), - FakeVmServiceRequest( - method: 'getIsolate', - args: { - 'isolateId': fakeUnpausedIsolate.id, - }, - jsonResponse: fakeUnpausedIsolate.toJson(), - ), - FakeVmServiceRequest( - method: 'ext.flutter.exit', - args: { - '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: [ - FakeVmServiceRequest( - method: kListViewsMethod, - jsonResponse: { - 'views': [ - fakeFlutterView.toJson(), - ], - }, - ), - FakeVmServiceRequest( - method: 'getIsolate', - args: { - 'isolateId': fakeUnpausedIsolate.id - }, - jsonResponse: fakeUnpausedIsolate.toJson(), - ), - FakeVmServiceRequest( - method: 'ext.flutter.exit', - args: { - 'isolateId': fakeUnpausedIsolate.id, - }, - close: true, - ) - ]); + testUsingContext('FlutterDevice will exit an un-paused isolate using stopApp', () => testbed.run(() async { + fakeVmServiceHost = FakeVmServiceHost(requests: []); final TestFlutterDevice flutterDevice = TestFlutterDevice( mockDevice, ); @@ -1802,6 +1675,7 @@ void main() { final Future exitFuture = flutterDevice.exitApps(); await expectLater(exitFuture, completes); + expect(mockDevice.appStopped, true); expect(fakeVmServiceHost.hasRemainingExpectations, false); }));