[flutter_tools] reland remove flutter view cache (#56387)
Fixes #56194
Remove caching of FlutterView and poll forever if the list of flutter views is empty. Added test for missing release mode logic.
diff --git a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
index 282e3de..a2370bd 100644
--- a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
+++ b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart
@@ -191,6 +191,11 @@
}
@override
+ Future<List<FlutterView>> listFlutterViews() async {
+ return <FlutterView>[];
+ }
+
+ @override
Future<void> debugDumpApp() async {
try {
await _vmService
diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart
index 4e89ffa..e940856 100644
--- a/packages/flutter_tools/lib/src/resident_runner.dart
+++ b/packages/flutter_tools/lib/src/resident_runner.dart
@@ -226,38 +226,13 @@
return completer.future;
}
- Future<void> refreshViews() async {
- if (vmService == null) {
- return;
- }
- final List<FlutterView> updatedViews = await vmService.getFlutterViews();
- _views
- ..clear()
- ..addAll(updatedViews);
- }
- final List<FlutterView> _views = <FlutterView>[];
-
- List<FlutterView> get views {
- if (vmService == null) {
- return <FlutterView>[];
- }
- if (viewFilter != null) {
- return <FlutterView>[
- for (final FlutterView flutterView in _views)
- if (flutterView.uiIsolate.name.contains(viewFilter))
- flutterView
- ];
- }
- return _views;
- }
-
Future<void> exitApps({
@visibleForTesting Duration timeoutDelay = const Duration(seconds: 10),
}) async {
- if (!device.supportsFlutterExit) {
+ if (!device.supportsFlutterExit || vmService == null) {
return device.stopApp(package);
}
- await refreshViews();
+ final List<FlutterView> views = await vmService.getFlutterViews();
if (views == null || views.isEmpty) {
return device.stopApp(package);
}
@@ -333,6 +308,7 @@
final Uri deviceAssetsDirectoryUri = devFS.baseUri.resolveUri(
globals.fs.path.toUri(getAssetBuildDirectory()));
assert(deviceAssetsDirectoryUri != null);
+ final List<FlutterView> views = await vmService.getFlutterViews();
await Future.wait<void>(views.map<Future<void>>(
(FlutterView view) => vmService.setAssetDirectory(
assetsDirectory: deviceAssetsDirectoryUri,
@@ -343,6 +319,7 @@
}
Future<void> debugDumpApp() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterDebugDumpApp(
isolateId: view.uiIsolate.id,
@@ -351,6 +328,7 @@
}
Future<void> debugDumpRenderTree() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterDebugDumpRenderTree(
isolateId: view.uiIsolate.id,
@@ -359,6 +337,7 @@
}
Future<void> debugDumpLayerTree() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterDebugDumpLayerTree(
isolateId: view.uiIsolate.id,
@@ -367,6 +346,7 @@
}
Future<void> debugDumpSemanticsTreeInTraversalOrder() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterDebugDumpSemanticsTreeInTraversalOrder(
isolateId: view.uiIsolate.id,
@@ -375,6 +355,7 @@
}
Future<void> debugDumpSemanticsTreeInInverseHitTestOrder() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterDebugDumpSemanticsTreeInInverseHitTestOrder(
isolateId: view.uiIsolate.id,
@@ -383,6 +364,7 @@
}
Future<void> toggleDebugPaintSizeEnabled() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterToggleDebugPaintSizeEnabled(
isolateId: view.uiIsolate.id,
@@ -391,6 +373,7 @@
}
Future<void> toggleDebugCheckElevationsEnabled() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterToggleDebugCheckElevationsEnabled(
isolateId: view.uiIsolate.id,
@@ -399,6 +382,7 @@
}
Future<void> debugTogglePerformanceOverlayOverride() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterTogglePerformanceOverlayOverride(
isolateId: view.uiIsolate.id,
@@ -407,6 +391,7 @@
}
Future<void> toggleWidgetInspector() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterToggleWidgetInspector(
isolateId: view.uiIsolate.id,
@@ -415,6 +400,7 @@
}
Future<void> toggleProfileWidgetBuilds() async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
for (final FlutterView view in views) {
await vmService.flutterToggleProfileWidgetBuilds(
isolateId: view.uiIsolate.id,
@@ -423,6 +409,7 @@
}
Future<String> togglePlatform({ String from }) async {
+ final List<FlutterView> views = await vmService.getFlutterViews();
final String to = nextPlatform(from, featureFlags);
for (final FlutterView view in views) {
await vmService.flutterPlatformOverride(
@@ -764,15 +751,17 @@
Future<Map<String, dynamic>> invokeFlutterExtensionRpcRawOnFirstIsolate(
String method, {
Map<String, dynamic> params,
- }) {
+ }) async {
+ final List<FlutterView> views = await flutterDevices
+ .first
+ .vmService.getFlutterViews();
return flutterDevices
.first
.vmService
.invokeFlutterExtensionRpcRaw(
method,
args: params,
- isolateId: flutterDevices
- .first.views
+ isolateId: views
.first.uiIsolate.id
);
}
@@ -811,13 +800,23 @@
throw Exception('Canvaskit not supported by this runner.');
}
+ /// List the attached flutter views.
+ Future<List<FlutterView>> listFlutterViews() async {
+ return (await Future.wait(
+ flutterDevices.map((FlutterDevice d) => d.vmService.getFlutterViews()))
+ ).expand((List<FlutterView> views) => views).toList();
+ }
+
/// Write the SkSL shaders to a zip file in build directory.
Future<void> writeSkSL() async {
if (!supportsWriteSkSL) {
throw Exception('writeSkSL is not supported by this runner.');
}
+ final List<FlutterView> views = await flutterDevices
+ .first
+ .vmService.getFlutterViews();
final Map<String, Object> data = await flutterDevices.first.vmService.getSkSLs(
- viewId: flutterDevices.first.views.first.id,
+ viewId: views.first.id,
);
if (data.isEmpty) {
globals.logger.printStatus(
@@ -902,78 +901,61 @@
appFinished();
}
- Future<void> refreshViews() async {
- final List<Future<void>> futures = <Future<void>>[
- for (final FlutterDevice device in flutterDevices) device.refreshViews(),
- ];
- await Future.wait(futures);
- }
-
Future<void> debugDumpApp() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.debugDumpApp();
}
}
Future<void> debugDumpRenderTree() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.debugDumpRenderTree();
}
}
Future<void> debugDumpLayerTree() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.debugDumpLayerTree();
}
}
Future<void> debugDumpSemanticsTreeInTraversalOrder() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.debugDumpSemanticsTreeInTraversalOrder();
}
}
Future<void> debugDumpSemanticsTreeInInverseHitTestOrder() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.debugDumpSemanticsTreeInInverseHitTestOrder();
}
}
Future<void> debugToggleDebugPaintSizeEnabled() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.toggleDebugPaintSizeEnabled();
}
}
Future<void> debugToggleDebugCheckElevationsEnabled() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.toggleDebugCheckElevationsEnabled();
}
}
Future<void> debugTogglePerformanceOverlayOverride() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.debugTogglePerformanceOverlayOverride();
}
}
Future<void> debugToggleWidgetInspector() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.toggleWidgetInspector();
}
}
Future<void> debugToggleProfileWidgetBuilds() async {
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
await device.toggleProfileWidgetBuilds();
}
@@ -997,11 +979,12 @@
'flutter',
'png',
);
+ final List<FlutterView> views = await device
+ .vmService.getFlutterViews();
try {
if (supportsServiceProtocol && isRunningDebug) {
- await device.refreshViews();
try {
- for (final FlutterView view in device.views) {
+ for (final FlutterView view in views) {
await device.vmService.flutterDebugAllowBanner(
false,
isolateId: view.uiIsolate.id,
@@ -1018,7 +1001,7 @@
} finally {
if (supportsServiceProtocol && isRunningDebug) {
try {
- for (final FlutterView view in device.views) {
+ for (final FlutterView view in views) {
await device.vmService.flutterDebugAllowBanner(
true,
isolateId: view.uiIsolate.id,
@@ -1043,9 +1026,10 @@
}
Future<void> debugTogglePlatform() async {
- await refreshViews();
- final String isolateId = flutterDevices
- .first.views.first.uiIsolate.id;
+ final List<FlutterView> views = await flutterDevices
+ .first
+ .vmService.getFlutterViews();
+ final String isolateId = views.first.uiIsolate.id;
final String from = await flutterDevices
.first.vmService.flutterPlatformOverride(
isolateId: isolateId,
@@ -1078,10 +1062,8 @@
if (!debuggingOptions.debuggingEnabled) {
throw 'The service protocol is not enabled.';
}
-
_finished = Completer<int>();
-
- bool viewFound = false;
+ // Listen for service protocol connection to close.
for (final FlutterDevice device in flutterDevices) {
await device.connect(
reloadSources: reloadSources,
@@ -1089,21 +1071,16 @@
compileExpression: compileExpression,
reloadMethod: reloadMethod,
);
- await device.refreshViews();
- if (device.views.isNotEmpty) {
- viewFound = true;
+ // This will wait for at least one flutter view before returning.
+ final Status status = globals.logger.startProgress(
+ 'Waiting for ${device.device.name} to report its views...',
+ timeout: const Duration(milliseconds: 200),
+ );
+ try {
+ await device.vmService.getFlutterViews();
+ } finally {
+ status.stop();
}
- }
- if (!viewFound) {
- if (flutterDevices.length == 1) {
- throw 'No Flutter view is available on ${flutterDevices.first.device.name}.';
- }
- throw 'No Flutter view is available on any device '
- '(${flutterDevices.map<String>((FlutterDevice device) => device.device.name).join(', ')}).';
- }
-
- // Listen for service protocol connection to close.
- for (final FlutterDevice device in flutterDevices) {
// This hooks up callbacks for when the connection stops in the future.
// We don't want to wait for them. We don't handle errors in those callbacks'
// futures either because they just print to logger and is not critical.
@@ -1372,8 +1349,7 @@
}
return false;
case 'l':
- final List<FlutterView> views = residentRunner.flutterDevices
- .expand((FlutterDevice d) => d.views).toList();
+ final List<FlutterView> views = await residentRunner.listFlutterViews();
globals.printStatus('Connected ${pluralize('view', views.length)}:');
for (final FlutterView v in views) {
globals.printStatus('${v.uiIsolate.name} (${v.uiIsolate.id})', indent: 2);
diff --git a/packages/flutter_tools/lib/src/run_cold.dart b/packages/flutter_tools/lib/src/run_cold.dart
index 1779426..8bfd230 100644
--- a/packages/flutter_tools/lib/src/run_cold.dart
+++ b/packages/flutter_tools/lib/src/run_cold.dart
@@ -95,7 +95,6 @@
continue;
}
await device.initLogReader();
- await device.refreshViews();
globals.printTrace('Connected to ${device.device.name}');
}
@@ -145,9 +144,9 @@
for (final FlutterDevice device in flutterDevices) {
await device.initLogReader();
}
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
- for (final FlutterView view in device.views) {
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
+ for (final FlutterView view in views) {
globals.printTrace('Connected to $view.');
}
}
diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart
index 38b36fb..3d8b312 100644
--- a/packages/flutter_tools/lib/src/run_hot.dart
+++ b/packages/flutter_tools/lib/src/run_hot.dart
@@ -198,7 +198,8 @@
}
for (final FlutterDevice device in flutterDevices) {
- for (final FlutterView view in device.views) {
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
+ for (final FlutterView view in views) {
await device.vmService.flutterFastReassemble(
classId,
isolateId: view.uiIsolate.id,
@@ -277,14 +278,14 @@
return 3;
}
- await refreshViews();
for (final FlutterDevice device in flutterDevices) {
// VM must have accepted the kernel binary, there will be no reload
// report, so we let incremental compiler know that source code was accepted.
if (device.generator != null) {
device.generator.accept();
}
- for (final FlutterView view in device.views) {
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
+ for (final FlutterView view in views) {
globals.printTrace('Connected to $view.');
}
}
@@ -474,15 +475,15 @@
Uri main,
Uri assetsDirectory,
) async {
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
await Future.wait(<Future<void>>[
- for (final FlutterView view in device.views)
+ for (final FlutterView view in views)
device.vmService.runInView(
viewId: view.id,
main: main,
assetsDirectory: assetsDirectory,
),
]);
- await device.refreshViews();
}
Future<void> _launchFromDevFS(String mainScript) async {
@@ -501,7 +502,8 @@
if (benchmarkMode) {
futures.clear();
for (final FlutterDevice device in flutterDevices) {
- for (final FlutterView view in device.views) {
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
+ for (final FlutterView view in views) {
futures.add(device.vmService
.flushUIThreadTasks(uiIsolateId: view.uiIsolate.id));
}
@@ -514,9 +516,6 @@
String reason,
bool benchmarkMode = false,
}) async {
- globals.printTrace('Refreshing active FlutterViews before restarting.');
- await refreshViews();
-
final Stopwatch restartTimer = Stopwatch()..start();
// TODO(aam): Add generator reset logic once we switch to using incremental
// compiler for full application recompilation on restart.
@@ -541,7 +540,8 @@
final List<Future<void>> operations = <Future<void>>[];
for (final FlutterDevice device in flutterDevices) {
final Set<String> uiIsolatesIds = <String>{};
- for (final FlutterView view in device.views) {
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
+ for (final FlutterView view in views) {
if (view.uiIsolate == null) {
continue;
}
@@ -810,7 +810,8 @@
void Function(String message) onSlow,
}) async {
for (final FlutterDevice device in flutterDevices) {
- for (final FlutterView view in device.views) {
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
+ for (final FlutterView view in views) {
if (view.uiIsolate == null) {
return OperationResult(2, 'Application isolate not found', fatal: true);
}
@@ -818,10 +819,6 @@
}
final Stopwatch reloadTimer = Stopwatch()..start();
-
- globals.printTrace('Refreshing active FlutterViews before reloading.');
- await refreshViews();
-
final Stopwatch devFSTimer = Stopwatch()..start();
final UpdateFSReport updatedDevFS = await _updateDevFS();
// Record time it took to synchronize to DevFS.
@@ -912,14 +909,6 @@
// Record time it took for the VM to reload the sources.
_addBenchmarkData('hotReloadVMReloadMilliseconds', vmReloadTimer.elapsed.inMilliseconds);
final Stopwatch reassembleTimer = Stopwatch()..start();
-
- // Reload the isolate data.
- await Future.wait(<Future<void>>[
- for (final FlutterDevice device in flutterDevices)
- device.refreshViews()
- ]);
-
- globals.printTrace('Evicting dirty assets');
await _evictDirtyAssets();
// Check if any isolates are paused and reassemble those
@@ -930,7 +919,8 @@
int pausedIsolatesFound = 0;
bool failedReassemble = false;
for (final FlutterDevice device in flutterDevices) {
- for (final FlutterView view in device.views) {
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
+ for (final FlutterView view in views) {
// Check if the isolate is paused, and if so, don't reassemble. Ignore the
// PostPauseEvent event - the client requesting the pause will resume the app.
final vm_service.Isolate isolate = await device.vmService
@@ -1055,11 +1045,7 @@
final StringBuffer message = StringBuffer();
bool plural;
if (pausedIsolatesFound == 1) {
- if (flutterDevices.length == 1 && flutterDevices.single.views.length == 1) {
- message.write('The application is ');
- } else {
- message.write('An isolate is ');
- }
+ message.write('The application is ');
plural = false;
} else {
message.write('$pausedIsolatesFound isolates are ');
@@ -1121,13 +1107,14 @@
}
}
- Future<void> _evictDirtyAssets() {
+ Future<void> _evictDirtyAssets() async {
final List<Future<Map<String, dynamic>>> futures = <Future<Map<String, dynamic>>>[];
for (final FlutterDevice device in flutterDevices) {
if (device.devFS.assetPathsToEvict.isEmpty) {
continue;
}
- if (device.views.first.uiIsolate == null) {
+ final List<FlutterView> views = await device.vmService.getFlutterViews();
+ if (views.first.uiIsolate == null) {
globals.printError('Application isolate not found for $device');
continue;
}
@@ -1136,7 +1123,7 @@
device.vmService
.flutterEvictAsset(
assetPath,
- isolateId: device.views.first.uiIsolate.id,
+ isolateId: views.first.uiIsolate.id,
)
);
}
diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart
index 9b34f08..14bc858 100644
--- a/packages/flutter_tools/lib/src/vmservice.dart
+++ b/packages/flutter_tools/lib/src/vmservice.dart
@@ -684,15 +684,29 @@
}
/// List all [FlutterView]s attached to the current VM.
- Future<List<FlutterView>> getFlutterViews() async {
- final vm_service.Response response = await callMethod(
- kListViewsMethod,
- );
- final List<Object> rawViews = response.json['views'] as List<Object>;
- return <FlutterView>[
- for (final Object rawView in rawViews)
- FlutterView.parse(rawView as Map<String, Object>)
- ];
+ ///
+ /// If this returns an empty list, it will poll forever unless [returnEarly]
+ /// is set to true.
+ ///
+ /// By default, the poll duration is 50 milliseconds.
+ Future<List<FlutterView>> getFlutterViews({
+ bool returnEarly = false,
+ Duration delay = const Duration(milliseconds: 50),
+ }) async {
+ while (true) {
+ final vm_service.Response response = await callMethod(
+ kListViewsMethod,
+ );
+ final List<Object> rawViews = response.json['views'] as List<Object>;
+ final List<FlutterView> views = <FlutterView>[
+ for (final Object rawView in rawViews)
+ FlutterView.parse(rawView as Map<String, Object>)
+ ];
+ if (views.isNotEmpty || returnEarly) {
+ return views;
+ }
+ await Future<void>.delayed(delay);
+ }
}
/// Attempt to retrieve the isolate with id [isolateId], or `null` if it has
diff --git a/packages/flutter_tools/lib/src/web/web_device.dart b/packages/flutter_tools/lib/src/web/web_device.dart
index fbb39c7..f984858 100644
--- a/packages/flutter_tools/lib/src/web/web_device.dart
+++ b/packages/flutter_tools/lib/src/web/web_device.dart
@@ -66,7 +66,7 @@
bool get supportsStartPaused => true;
@override
- bool get supportsFlutterExit => true;
+ bool get supportsFlutterExit => false;
@override
bool get supportsScreenshot => false;
@@ -344,6 +344,9 @@
Future<bool> isLatestBuildInstalled(ApplicationPackage app) async => true;
@override
+ bool get supportsFlutterExit => false;
+
+ @override
Future<bool> get isLocalEmulator async => false;
@override
diff --git a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart
index b79f653..bdf8dff 100644
--- a/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart
+++ b/packages/flutter_tools/test/commands.shard/hermetic/attach_test.dart
@@ -685,7 +685,6 @@
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '1',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
@@ -698,14 +697,12 @@
},
),
FakeVmServiceRequest(
- id: '2',
method: 'getVM',
args: null,
jsonResponse: vm_service.VM.parse(<String, Object>{})
.toJson(),
),
FakeVmServiceRequest(
- id: '3',
method: '_createDevFS',
args: <String, Object>{
'fsName': globals.fs.currentDirectory.absolute.path,
@@ -715,7 +712,6 @@
},
),
FakeVmServiceRequest(
- id: '4',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
diff --git a/packages/flutter_tools/test/commands.shard/permeable/devices_test.dart b/packages/flutter_tools/test/commands.shard/permeable/devices_test.dart
index 4be5eda..9c0bccd 100644
--- a/packages/flutter_tools/test/commands.shard/permeable/devices_test.dart
+++ b/packages/flutter_tools/test/commands.shard/permeable/devices_test.dart
@@ -65,7 +65,7 @@
'hotRestart': true,
'screenshot': false,
'fastStart': false,
- 'flutterExit': true,
+ 'flutterExit': false,
'hardwareRendering': false,
'startPaused': true
}
diff --git a/packages/flutter_tools/test/general.shard/coverage_collector_test.dart b/packages/flutter_tools/test/general.shard/coverage_collector_test.dart
index fe7f4ca..5648feb 100644
--- a/packages/flutter_tools/test/general.shard/coverage_collector_test.dart
+++ b/packages/flutter_tools/test/general.shard/coverage_collector_test.dart
@@ -12,7 +12,6 @@
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '1',
method: 'getVM',
jsonResponse: (vm_service.VM.parse(<String, Object>{})
..isolates = <vm_service.IsolateRef>[
@@ -23,7 +22,6 @@
).toJson(),
),
const FakeVmServiceRequest(
- id: '2',
method: 'getScripts',
args: <String, Object>{
'isolateId': '1',
diff --git a/packages/flutter_tools/test/general.shard/devfs_test.dart b/packages/flutter_tools/test/general.shard/devfs_test.dart
index 80e9963..2a631ee 100644
--- a/packages/flutter_tools/test/general.shard/devfs_test.dart
+++ b/packages/flutter_tools/test/general.shard/devfs_test.dart
@@ -129,7 +129,6 @@
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '1',
method: '_createDevFS',
args: <String, Object>{
'fsName': 'test',
@@ -202,7 +201,6 @@
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '1',
method: '_createDevFS',
args: <String, Object>{
'fsName': 'test',
diff --git a/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart b/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart
index 4f0bd41..dd91b10 100644
--- a/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart
+++ b/packages/flutter_tools/test/general.shard/fuchsia/fuchsia_device_test.dart
@@ -637,7 +637,6 @@
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '1',
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[
diff --git a/packages/flutter_tools/test/general.shard/hot_test.dart b/packages/flutter_tools/test/general.shard/hot_test.dart
index dae17c3..9c18f56 100644
--- a/packages/flutter_tools/test/general.shard/hot_test.dart
+++ b/packages/flutter_tools/test/general.shard/hot_test.dart
@@ -21,6 +21,36 @@
import '../src/context.dart';
import '../src/mocks.dart';
+final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
+ id: '1',
+ pauseEvent: vm_service.Event(
+ kind: vm_service.EventKind.kResume,
+ timestamp: 0
+ ),
+ breakpoints: <vm_service.Breakpoint>[],
+ exceptionPauseMode: null,
+ libraries: <vm_service.LibraryRef>[],
+ livePorts: 0,
+ name: 'test',
+ number: '1',
+ pauseOnExit: false,
+ runnable: true,
+ startTime: 0,
+);
+
+final FlutterView fakeFlutterView = FlutterView(
+ id: 'a',
+ uiIsolate: fakeUnpausedIsolate,
+);
+
+final FakeVmServiceRequest listViews = FakeVmServiceRequest(
+ method: kListViewsMethod,
+ jsonResponse: <String, Object>{
+ 'views': <Object>[
+ fakeFlutterView.toJson(),
+ ],
+ },
+);
void main() {
group('validateReloadReport', () {
testUsingContext('invalid', () async {
@@ -172,42 +202,72 @@
testUsingContext('Does hot restarts when all devices support it', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
- const FakeVmServiceRequest(
- id: '1',
- method: kListViewsMethod,
- jsonResponse: <String, Object>{
- 'views': <Object>[],
- }
- ),
- const FakeVmServiceRequest(
- id: '2',
- method: kListViewsMethod,
- jsonResponse: <String, Object>{
- 'views': <Object>[],
- }
+ listViews,
+ FakeVmServiceRequest(
+ method: 'getIsolate',
+ args: <String, Object>{
+ 'isolateId': fakeUnpausedIsolate.id,
+ },
+ jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
- id: '3',
method: 'getVM',
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson()
),
+ listViews,
FakeVmServiceRequest(
- id: '4',
+ method: 'getIsolate',
+ args: <String, Object>{
+ 'isolateId': fakeUnpausedIsolate.id,
+ },
+ jsonResponse: fakeUnpausedIsolate.toJson(),
+ ),
+ FakeVmServiceRequest(
method: 'getVM',
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson()
),
+ listViews,
+ listViews,
const FakeVmServiceRequest(
- id: '5',
- method: kListViewsMethod,
- jsonResponse: <String, Object>{
- 'views': <Object>[],
+ method: 'streamListen',
+ args: <String, Object>{
+ 'streamId': 'Isolate',
}
),
const FakeVmServiceRequest(
- id: '6',
- method: kListViewsMethod,
- jsonResponse: <String, Object>{
- 'views': <Object>[],
+ method: 'streamListen',
+ args: <String, Object>{
+ 'streamId': 'Isolate',
+ }
+ ),
+ FakeVmServiceStreamResponse(
+ streamId: 'Isolate',
+ event: vm_service.Event(
+ timestamp: 0,
+ kind: vm_service.EventKind.kIsolateRunnable,
+ )
+ ),
+ FakeVmServiceStreamResponse(
+ streamId: 'Isolate',
+ event: vm_service.Event(
+ timestamp: 0,
+ kind: vm_service.EventKind.kIsolateRunnable,
+ )
+ ),
+ FakeVmServiceRequest(
+ method: kRunInViewMethod,
+ args: <String, Object>{
+ 'viewId': fakeFlutterView.id,
+ 'mainScript': 'lib/main.dart.dill',
+ 'assetDirectory': 'build/flutter_assets',
+ }
+ ),
+ FakeVmServiceRequest(
+ method: kRunInViewMethod,
+ args: <String, Object>{
+ 'viewId': fakeFlutterView.id,
+ 'mainScript': 'lib/main.dart.dill',
+ 'assetDirectory': 'build/flutter_assets',
}
),
]);
@@ -257,25 +317,40 @@
testUsingContext('hot restart supported', () async {
// Setup mocks
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ FakeVmServiceRequest(
+ method: 'getIsolate',
+ args: <String, Object>{
+ 'isolateId': fakeUnpausedIsolate.id,
+ },
+ jsonResponse: fakeUnpausedIsolate.toJson(),
+ ),
+ FakeVmServiceRequest(
+ method: 'getVM',
+ jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
+ ),
+ listViews,
const FakeVmServiceRequest(
- id: '1',
- method: kListViewsMethod,
- jsonResponse: <String, Object>{
- 'views': <Object>[],
+ method: 'streamListen',
+ args: <String, Object>{
+ 'streamId': 'Isolate',
}
),
FakeVmServiceRequest(
- id: '2',
- method: 'getVM',
- jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson()
- ),
- const FakeVmServiceRequest(
- id: '3',
- method: kListViewsMethod,
- jsonResponse: <String, Object>{
- 'views': <Object>[],
+ method: kRunInViewMethod,
+ args: <String, Object>{
+ 'viewId': fakeFlutterView.id,
+ 'mainScript': 'lib/main.dart.dill',
+ 'assetDirectory': 'build/flutter_assets',
}
),
+ FakeVmServiceStreamResponse(
+ streamId: 'Isolate',
+ event: vm_service.Event(
+ timestamp: 0,
+ kind: vm_service.EventKind.kIsolateRunnable,
+ )
+ ),
]);
final MockDevice mockDevice = MockDevice();
when(mockDevice.supportsHotReload).thenReturn(true);
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 1ce0659..466836c 100644
--- a/packages/flutter_tools/test/general.shard/resident_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_runner_test.dart
@@ -70,6 +70,15 @@
uiIsolate: fakeUnpausedIsolate,
);
+final FakeVmServiceRequest listViews = FakeVmServiceRequest(
+ method: kListViewsMethod,
+ jsonResponse: <String, Object>{
+ 'views': <Object>[
+ fakeFlutterView.toJson(),
+ ],
+ },
+);
+
void main() {
final Uri testUri = Uri.parse('foo://bar');
Testbed testbed;
@@ -127,10 +136,6 @@
);
});
when(mockFlutterDevice.devFS).thenReturn(mockDevFS);
- when(mockFlutterDevice.views).thenReturn(<FlutterView>[
- // NB: still using mock FlutterDevice.
- fakeFlutterView,
- ]);
when(mockFlutterDevice.device).thenReturn(mockDevice);
when(mockFlutterDevice.stopEchoingDeviceLog()).thenAnswer((Invocation invocation) async { });
when(mockFlutterDevice.observatoryUris).thenAnswer((_) => Stream<Uri>.value(testUri));
@@ -146,7 +151,6 @@
when(mockFlutterDevice.vmService).thenAnswer((Invocation invocation) {
return fakeVmServiceHost.vmService;
});
- when(mockFlutterDevice.refreshViews()).thenAnswer((Invocation invocation) async { });
when(mockFlutterDevice.reloadSources(any, pause: anyNamed('pause'))).thenAnswer((Invocation invocation) async {
return <Future<vm_service.ReloadReport>>[
Future<vm_service.ReloadReport>.value(vm_service.ReloadReport.parse(<String, dynamic>{
@@ -166,15 +170,7 @@
test('FlutterDevice can list views with a filter', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
- FakeVmServiceRequest(
- id: '1',
- method: kListViewsMethod,
- jsonResponse: <String, Object>{
- 'views': <Object>[
- fakeFlutterView.toJson(),
- ],
- },
- ),
+ listViews,
]);
final MockDevice mockDevice = MockDevice();
final FlutterDevice flutterDevice = FlutterDevice(
@@ -184,14 +180,13 @@
);
flutterDevice.vmService = fakeVmServiceHost.vmService;
-
- await flutterDevice.refreshViews();
-
- expect(flutterDevice.views, isEmpty);
}));
test('ResidentRunner can attach to device successfully', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ listViews,
+ ]);
final Completer<DebugConnectionInfo> onConnectionInfo = Completer<DebugConnectionInfo>.sync();
final Completer<void> onAppStart = Completer<void>.sync();
final Future<int> result = residentRunner.attach(
@@ -207,12 +202,15 @@
expect(onConnectionInfo.isCompleted, true);
expect((await connectionInfo).baseUri, 'foo://bar');
expect(onAppStart.isCompleted, true);
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
test('ResidentRunner can attach to device successfully with --fast-start', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ listViews,
+ listViews,
FakeVmServiceRequest(
- id: '1',
method: 'getIsolate',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -220,19 +218,17 @@
jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
- id: '2',
method: 'getVM',
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
),
+ listViews,
const FakeVmServiceRequest(
- id: '3',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate',
}
),
FakeVmServiceRequest(
- id: '4',
method: kRunInViewMethod,
args: <String, Object>{
'viewId': fakeFlutterView.id,
@@ -284,10 +280,15 @@
expect(onConnectionInfo.isCompleted, true);
expect((await connectionInfo).baseUri, 'foo://bar');
expect(onAppStart.isCompleted, true);
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
test('ResidentRunner can handle an RPC exception from hot reload', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ listViews,
+ listViews,
+ ]);
when(mockDevice.sdkNameAndVersion).thenAnswer((Invocation invocation) async {
return 'Example';
});
@@ -329,15 +330,18 @@
cdKey(CustomDimensions.hotEventEmulator): 'false',
cdKey(CustomDimensions.hotEventFullRestart): 'false',
})).called(1);
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{
Usage: () => MockUsage(),
}));
test('ResidentRunner can send target platform to analytics from hot reload', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
- // Not all requests are present due to existing mocks
+ listViews,
+ listViews,
+ listViews,
+ listViews,
FakeVmServiceRequest(
- id: '1',
method: 'getIsolate',
args: <String, Object>{
'isolateId': '1',
@@ -345,7 +349,6 @@
jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
- id: '2',
method: 'ext.flutter.reassemble',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -381,10 +384,11 @@
}));
test('ResidentRunner can send target platform to analytics from full restart', () => testbed.run(() async {
- // Not all requests are present due to existing mocks
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ listViews,
+ listViews,
FakeVmServiceRequest(
- id: '1',
method: 'getIsolate',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -392,19 +396,17 @@
jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
- id: '2',
method: 'getVM',
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
),
+ listViews,
const FakeVmServiceRequest(
- id: '3',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate',
},
),
FakeVmServiceRequest(
- id: '4',
method: kRunInViewMethod,
args: <String, Object>{
'viewId': fakeFlutterView.id,
@@ -445,12 +447,16 @@
containsPair(cdKey(CustomDimensions.hotEventTargetPlatform),
getNameForTargetPlatform(TargetPlatform.android_arm)),
);
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{
Usage: () => MockUsage(),
}));
test('ResidentRunner Can handle an RPC exception from hot restart', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ listViews,
+ ]);
when(mockDevice.sdkNameAndVersion).thenAnswer((Invocation invocation) async {
return 'Example';
});
@@ -493,6 +499,7 @@
cdKey(CustomDimensions.hotEventEmulator): 'false',
cdKey(CustomDimensions.hotEventFullRestart): 'true',
})).called(1);
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{
Usage: () => MockUsage(),
}));
@@ -578,14 +585,15 @@
test('ResidentRunner does support CanvasKit', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+
expect(() => residentRunner.toggleCanvaskit(),
throwsA(isA<Exception>()));
}));
test('ResidentRunner handles writeSkSL returning no data', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
- FakeVmServiceRequest(
- id: '1',
+ listViews,
+ FakeVmServiceRequest(
method: kGetSkSLsMethod,
args: <String, Object>{
'viewId': fakeFlutterView.id,
@@ -593,17 +601,18 @@
jsonResponse: <String, Object>{
'SkSLs': <String, Object>{}
}
- )
+ ),
]);
await residentRunner.writeSkSL();
expect(testLogger.statusText, contains('No data was receieved'));
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
test('ResidentRunner can write SkSL data to a unique file with engine revision, platform, and device name', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
FakeVmServiceRequest(
- id: '1',
method: kGetSkSLsMethod,
args: <String, Object>{
'viewId': fakeFlutterView.id,
@@ -634,8 +643,8 @@
test('ResidentRunner can take screenshot on debug device', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
FakeVmServiceRequest(
- id: '1',
method: 'ext.flutter.debugAllowBanner',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -643,7 +652,6 @@
},
),
FakeVmServiceRequest(
- id: '2',
method: 'ext.flutter.debugAllowBanner',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -676,8 +684,8 @@
test('ResidentRunner bails taking screenshot on debug device if debugAllowBanner throws RpcError', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
FakeVmServiceRequest(
- id: '1',
method: 'ext.flutter.debugAllowBanner',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -696,8 +704,8 @@
test('ResidentRunner bails taking screenshot on debug device if debugAllowBanner during second request', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
FakeVmServiceRequest(
- id: '1',
method: 'ext.flutter.debugAllowBanner',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -705,7 +713,6 @@
},
),
FakeVmServiceRequest(
- id: '2',
method: 'ext.flutter.debugAllowBanner',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -719,12 +726,13 @@
await residentRunner.screenshot(mockFlutterDevice);
expect(testLogger.errorText, contains('Error'));
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
test('ResidentRunner bails taking screenshot on debug device if takeScreenshot throws', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
FakeVmServiceRequest(
- id: '1',
method: 'ext.flutter.debugAllowBanner',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -732,7 +740,6 @@
},
),
FakeVmServiceRequest(
- id: '2',
method: 'ext.flutter.debugAllowBanner',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -754,10 +761,13 @@
expect(() => residentRunner.screenshot(mockFlutterDevice),
throwsAssertionError);
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
test('ResidentRunner does not toggle banner in non-debug mode', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ ]);
residentRunner = HotRunner(
<FlutterDevice>[
mockFlutterDevice,
@@ -781,7 +791,6 @@
test('FlutterDevice will not exit a paused isolate', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '1',
method: '_flutter.listViews',
jsonResponse: <String, Object>{
'views': <Object>[
@@ -790,7 +799,6 @@
},
),
FakeVmServiceRequest(
- id: '2',
method: 'getIsolate',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -800,7 +808,6 @@
]);
final TestFlutterDevice flutterDevice = TestFlutterDevice(
mockDevice,
- <FlutterView>[ fakeFlutterView ],
);
flutterDevice.vmService = fakeVmServiceHost.vmService;
when(mockDevice.supportsFlutterExit).thenReturn(true);
@@ -811,10 +818,20 @@
expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
+ test('FlutterDevice can exit from a release mode isolate with no VmService', () => testbed.run(() async {
+ final TestFlutterDevice flutterDevice = TestFlutterDevice(
+ mockDevice,
+ );
+ when(mockDevice.supportsFlutterExit).thenReturn(true);
+
+ await flutterDevice.exitApps();
+
+ verify(mockDevice.stopApp(any)).called(1);
+ }));
+
test('FlutterDevice will call stopApp if the exit request times out', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '1',
method: '_flutter.listViews',
jsonResponse: <String, Object>{
'views': <Object>[
@@ -823,7 +840,6 @@
},
),
FakeVmServiceRequest(
- id: '2',
method: 'getIsolate',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -831,7 +847,6 @@
jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
- id: '3',
method: 'ext.flutter.exit',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -842,7 +857,6 @@
]);
final TestFlutterDevice flutterDevice = TestFlutterDevice(
mockDevice,
- <FlutterView>[ fakeFlutterView ],
);
flutterDevice.vmService = fakeVmServiceHost.vmService;
when(mockDevice.supportsFlutterExit).thenReturn(true);
@@ -858,7 +872,6 @@
test('FlutterDevice will exit an un-paused isolate', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '1',
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[
@@ -867,7 +880,6 @@
},
),
FakeVmServiceRequest(
- id: '2',
method: 'getIsolate',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id
@@ -875,7 +887,6 @@
jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
- id: '3',
method: 'ext.flutter.exit',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
@@ -885,7 +896,6 @@
]);
final TestFlutterDevice flutterDevice = TestFlutterDevice(
mockDevice,
- <FlutterView> [fakeFlutterView ],
);
flutterDevice.vmService = fakeVmServiceHost.vmService;
@@ -897,18 +907,10 @@
expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
- test('ResidentRunner refreshViews calls flutter device', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
- await residentRunner.refreshViews();
-
- verify(mockFlutterDevice.refreshViews()).called(1);
- }));
-
test('ResidentRunner debugDumpApp calls flutter device', () => testbed.run(() async {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugDumpApp();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.debugDumpApp()).called(1);
}));
@@ -916,7 +918,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugDumpRenderTree();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.debugDumpRenderTree()).called(1);
}));
@@ -924,7 +925,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugDumpLayerTree();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.debugDumpLayerTree()).called(1);
}));
@@ -932,7 +932,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugDumpSemanticsTreeInTraversalOrder();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.debugDumpSemanticsTreeInTraversalOrder()).called(1);
}));
@@ -940,7 +939,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugDumpSemanticsTreeInInverseHitTestOrder();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.debugDumpSemanticsTreeInInverseHitTestOrder()).called(1);
}));
@@ -948,7 +946,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugToggleDebugPaintSizeEnabled();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.toggleDebugPaintSizeEnabled()).called(1);
}));
@@ -956,7 +953,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugToggleDebugCheckElevationsEnabled();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.toggleDebugCheckElevationsEnabled()).called(1);
}));
@@ -964,7 +960,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugTogglePerformanceOverlayOverride();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.debugTogglePerformanceOverlayOverride()).called(1);
}));
@@ -972,7 +967,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugToggleWidgetInspector();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.toggleWidgetInspector()).called(1);
}));
@@ -980,12 +974,14 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
await residentRunner.debugToggleProfileWidgetBuilds();
- verify(mockFlutterDevice.refreshViews()).called(1);
verify(mockFlutterDevice.toggleProfileWidgetBuilds()).called(1);
}));
test('HotRunner writes vm service file when providing debugging option', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ listViews,
+ ]);
setWsAddress(testUri, fakeVmServiceHost.vmService);
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
residentRunner = HotRunner(
@@ -1007,7 +1003,10 @@
}));
test('HotRunner unforwards device ports', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ listViews,
+ ]);
final MockDevicePortForwarder mockPortForwarder = MockDevicePortForwarder();
when(mockDevice.portForwarder).thenReturn(mockPortForwarder);
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
@@ -1035,7 +1034,10 @@
}));
test('HotRunner handles failure to write vmservice file', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ listViews,
+ ]);
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
residentRunner = HotRunner(
<FlutterDevice>[
@@ -1053,13 +1055,16 @@
await residentRunner.run();
expect(testLogger.errorText, contains('Failed to write vmservice-out-file at foo'));
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}, overrides: <Type, Generator>{
FileSystem: () => ThrowingForwardingFileSystem(MemoryFileSystem()),
}));
test('ColdRunner writes vm service file when providing debugging option', () => testbed.run(() async {
- fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[]);
+ fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
+ listViews,
+ ]);
globals.fs.file(globals.fs.path.join('lib', 'main.dart')).createSync(recursive: true);
setWsAddress(testUri, fakeVmServiceHost.vmService);
residentRunner = ColdRunner(
@@ -1078,6 +1083,7 @@
await residentRunner.run();
expect(await globals.fs.file('foo').readAsString(), testUri.toString());
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
}));
test('FlutterDevice uses dartdevc configuration when targeting web', () => testbed.run(() async {
@@ -1117,7 +1123,6 @@
final TestFlutterDevice flutterDevice = TestFlutterDevice(
mockDevice,
- <FlutterView>[],
observatoryUris: Stream<Uri>.value(testUri),
);
@@ -1153,15 +1158,12 @@
class MockProcessManager extends Mock implements ProcessManager {}
class TestFlutterDevice extends FlutterDevice {
- TestFlutterDevice(Device device, this.views, { Stream<Uri> observatoryUris })
+ TestFlutterDevice(Device device, { Stream<Uri> observatoryUris })
: super(device, buildInfo: BuildInfo.debug) {
_observatoryUris = observatoryUris;
}
@override
- final List<FlutterView> views;
-
- @override
Stream<Uri> get observatoryUris => _observatoryUris;
Stream<Uri> _observatoryUris;
}
diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
index 7392b91..eaaa55a 100644
--- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
+++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart
@@ -36,14 +36,12 @@
const List<VmServiceExpectation> kAttachLogExpectations = <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '1',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Stdout',
},
),
FakeVmServiceRequest(
- id: '2',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Stderr',
@@ -53,14 +51,12 @@
const List<VmServiceExpectation> kAttachIsolateExpectations = <VmServiceExpectation>[
FakeVmServiceRequest(
- id: '3',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate'
}
),
FakeVmServiceRequest(
- id: '4',
method: 'registerService',
args: <String, Object>{
'service': 'reloadSources',
@@ -362,7 +358,6 @@
...kAttachExpectations,
const FakeVmServiceRequest(
method: 'hotRestart',
- id: '5',
jsonResponse: <String, Object>{
'type': 'Success',
}
@@ -439,7 +434,6 @@
...kAttachExpectations,
const FakeVmServiceRequest(
method: 'hotRestart',
- id: '5',
jsonResponse: <String, Object>{
'type': 'Success',
}
@@ -670,7 +664,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'hotRestart',
jsonResponse: <String, Object>{
'type': 'Failed',
@@ -693,7 +686,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'hotRestart',
// Failed response,
errorCode: RPCErrorCodes.kInternalError,
@@ -725,7 +717,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.debugDumpApp',
args: <String, Object>{
'isolateId': null,
@@ -747,7 +738,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.debugDumpLayerTree',
args: <String, Object>{
'isolateId': null,
@@ -769,7 +759,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.debugDumpRenderTree',
args: <String, Object>{
'isolateId': null,
@@ -791,7 +780,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.debugDumpSemanticsTreeInTraversalOrder',
args: <String, Object>{
'isolateId': null,
@@ -813,7 +801,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder',
args: <String, Object>{
'isolateId': null,
@@ -836,7 +823,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.debugPaint',
args: <String, Object>{
'isolateId': null,
@@ -846,7 +832,6 @@
},
),
const FakeVmServiceRequest(
- id: '6',
method: 'ext.flutter.debugPaint',
args: <String, Object>{
'isolateId': null,
@@ -874,7 +859,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.showPerformanceOverlay',
args: <String, Object>{
'isolateId': null,
@@ -884,7 +868,6 @@
},
),
const FakeVmServiceRequest(
- id: '6',
method: 'ext.flutter.showPerformanceOverlay',
args: <String, Object>{
'isolateId': null,
@@ -911,7 +894,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.inspector.show',
args: <String, Object>{
'isolateId': null,
@@ -921,7 +903,6 @@
},
),
const FakeVmServiceRequest(
- id: '6',
method: 'ext.flutter.inspector.show',
args: <String, Object>{
'isolateId': null,
@@ -948,7 +929,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.profileWidgetBuilds',
args: <String, Object>{
'isolateId': null,
@@ -958,7 +938,6 @@
},
),
const FakeVmServiceRequest(
- id: '6',
method: 'ext.flutter.profileWidgetBuilds',
args: <String, Object>{
'isolateId': null,
@@ -985,7 +964,6 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
- id: '5',
method: 'ext.flutter.platformOverride',
args: <String, Object>{
'isolateId': null,
@@ -995,7 +973,6 @@
},
),
const FakeVmServiceRequest(
- id: '6',
method: 'ext.flutter.platformOverride',
args: <String, Object>{
'isolateId': null,
@@ -1089,14 +1066,12 @@
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachLogExpectations,
const FakeVmServiceRequest(
- id: '3',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate'
}
),
const FakeVmServiceRequest(
- id: '4',
method: 'registerService',
args: <String, Object>{
'service': 'reloadSources',
diff --git a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart
index 4c289b9..3ed50fd 100644
--- a/packages/flutter_tools/test/general.shard/terminal_handler_test.dart
+++ b/packages/flutter_tools/test/general.shard/terminal_handler_test.dart
@@ -139,7 +139,9 @@
final MockFlutterDevice mockFlutterDevice = MockFlutterDevice();
when(mockResidentRunner.isRunningDebug).thenReturn(true);
when(mockResidentRunner.flutterDevices).thenReturn(<FlutterDevice>[mockFlutterDevice]);
- when(mockFlutterDevice.views).thenReturn(<FlutterView>[]);
+ when(mockResidentRunner.listFlutterViews()).thenAnswer((Invocation invocation) async {
+ return <FlutterView>[];
+ });
await terminalHandler.processTerminalInput('l');
diff --git a/packages/flutter_tools/test/general.shard/vmservice_test.dart b/packages/flutter_tools/test/general.shard/vmservice_test.dart
index 61007fa..3ae4062 100644
--- a/packages/flutter_tools/test/general.shard/vmservice_test.dart
+++ b/packages/flutter_tools/test/general.shard/vmservice_test.dart
@@ -231,10 +231,10 @@
testWithoutContext('runInView forwards arguments correctly', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
- const FakeVmServiceRequest(method: 'streamListen', id: '1', args: <String, Object>{
+ const FakeVmServiceRequest(method: 'streamListen', args: <String, Object>{
'streamId': 'Isolate'
}),
- const FakeVmServiceRequest(method: kRunInViewMethod, id: '2', args: <String, Object>{
+ const FakeVmServiceRequest(method: kRunInViewMethod, args: <String, Object>{
'viewId': '1234',
'mainScript': 'main.dart',
'assetDirectory': 'flutter_assets/',
@@ -256,6 +256,65 @@
);
expect(fakeVmServiceHost.hasRemainingExpectations, false);
});
+
+ testWithoutContext('getFlutterViews polls until a view is returned', () async {
+ final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
+ requests: <VmServiceExpectation>[
+ const FakeVmServiceRequest(
+ method: kListViewsMethod,
+ jsonResponse: <String, Object>{
+ 'views': <Object>[],
+ },
+ ),
+ const FakeVmServiceRequest(
+ method: kListViewsMethod,
+ jsonResponse: <String, Object>{
+ 'views': <Object>[],
+ },
+ ),
+ const FakeVmServiceRequest(
+ method: kListViewsMethod,
+ jsonResponse: <String, Object>{
+ 'views': <Object>[
+ <String, Object>{
+ 'id': 'a',
+ 'isolate': <String, Object>{},
+ },
+ ],
+ },
+ ),
+ ]
+ );
+
+ expect(
+ await fakeVmServiceHost.vmService.getFlutterViews(
+ delay: Duration.zero,
+ ),
+ isNotEmpty,
+ );
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
+ });
+
+ testWithoutContext('getFlutterViews does not poll if returnEarly is true', () async {
+ final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
+ requests: <VmServiceExpectation>[
+ const FakeVmServiceRequest(
+ method: kListViewsMethod,
+ jsonResponse: <String, Object>{
+ 'views': <Object>[],
+ },
+ ),
+ ]
+ );
+
+ expect(
+ await fakeVmServiceHost.vmService.getFlutterViews(
+ returnEarly: true,
+ ),
+ isEmpty,
+ );
+ expect(fakeVmServiceHost.hasRemainingExpectations, false);
+ });
}
class MockDevice extends Mock implements Device {}
diff --git a/packages/flutter_tools/test/general.shard/web/devices_test.dart b/packages/flutter_tools/test/general.shard/web/devices_test.dart
index c068fd4..e5dd330 100644
--- a/packages/flutter_tools/test/general.shard/web/devices_test.dart
+++ b/packages/flutter_tools/test/general.shard/web/devices_test.dart
@@ -76,7 +76,7 @@
expect(chromeDevice.supportsHotReload, true);
expect(chromeDevice.supportsHotRestart, true);
expect(chromeDevice.supportsStartPaused, true);
- expect(chromeDevice.supportsFlutterExit, true);
+ expect(chromeDevice.supportsFlutterExit, false);
expect(chromeDevice.supportsScreenshot, false);
expect(await chromeDevice.isLocalEmulator, false);
expect(chromeDevice.getLogReader(), isA<NoOpDeviceLogReader>());
@@ -96,7 +96,7 @@
expect(chromeDevice.supportsHotReload, true);
expect(chromeDevice.supportsHotRestart, true);
expect(chromeDevice.supportsStartPaused, true);
- expect(chromeDevice.supportsFlutterExit, true);
+ expect(chromeDevice.supportsFlutterExit, false);
expect(chromeDevice.supportsScreenshot, false);
expect(await chromeDevice.isLocalEmulator, false);
expect(chromeDevice.getLogReader(), isA<NoOpDeviceLogReader>());
@@ -114,7 +114,7 @@
expect(device.supportsHotReload, true);
expect(device.supportsHotRestart, true);
expect(device.supportsStartPaused, true);
- expect(device.supportsFlutterExit, true);
+ expect(device.supportsFlutterExit, false);
expect(device.supportsScreenshot, false);
expect(await device.isLocalEmulator, false);
expect(device.getLogReader(), isA<NoOpDeviceLogReader>());
diff --git a/packages/flutter_tools/test/src/common.dart b/packages/flutter_tools/test/src/common.dart
index c22c3a6..b29ea3e 100644
--- a/packages/flutter_tools/test/src/common.dart
+++ b/packages/flutter_tools/test/src/common.dart
@@ -239,7 +239,6 @@
final FakeVmServiceRequest fakeRequest = _requests.removeAt(0) as FakeVmServiceRequest;
expect(request, isA<Map<String, Object>>()
.having((Map<String, Object> request) => request['method'], 'method', fakeRequest.method)
- .having((Map<String, Object> request) => request['id'], 'id', fakeRequest.id)
.having((Map<String, Object> request) => request['params'], 'args', fakeRequest.args)
);
if (fakeRequest.close) {
@@ -250,13 +249,13 @@
if (fakeRequest.errorCode == null) {
_input.add(json.encode(<String, Object>{
'jsonrpc': '2.0',
- 'id': fakeRequest.id,
+ 'id': request['id'],
'result': fakeRequest.jsonResponse ?? <String, Object>{'type': 'Success'},
}));
} else {
_input.add(json.encode(<String, Object>{
'jsonrpc': '2.0',
- 'id': fakeRequest.id,
+ 'id': request['id'],
'error': <String, Object>{
'code': fakeRequest.errorCode,
}
@@ -299,7 +298,6 @@
class FakeVmServiceRequest implements VmServiceExpectation {
const FakeVmServiceRequest({
@required this.method,
- @required this.id,
this.args = const <String, Object>{},
this.jsonResponse,
this.errorCode,
@@ -307,7 +305,6 @@
});
final String method;
- final String id;
/// When true, the vm service is automatically closed.
final bool close;