Unverified Commit d98d3a97 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

Revert "[flutter_tools] remove flutter view cache (#56223)" (#56385)

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