Unverified Commit 209bdcb6 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] remove flutter view cache (#56223)

Remove caching of FlutterView. Perhaps the FlutterView RPC might return an empty list if the VM is not quite up yet? We had some old logic to poll the flutter views RPC for up to 200ms. That doesn't seem like a great approach, so instead we could forgo it entirely and trust that either the views come up before the developer tries to interact, or we crash.
parent a48a51b0
...@@ -190,6 +190,11 @@ abstract class ResidentWebRunner extends ResidentRunner { ...@@ -190,6 +190,11 @@ 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,38 +226,13 @@ class FlutterDevice { ...@@ -226,38 +226,13 @@ 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);
} }
await refreshViews(); final List<FlutterView> views = await vmService.getFlutterViews();
if (views == null || views.isEmpty) { if (views == null || views.isEmpty) {
return device.stopApp(package); return device.stopApp(package);
} }
...@@ -333,6 +308,7 @@ class FlutterDevice { ...@@ -333,6 +308,7 @@ 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,
...@@ -343,6 +319,7 @@ class FlutterDevice { ...@@ -343,6 +319,7 @@ 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,
...@@ -351,6 +328,7 @@ class FlutterDevice { ...@@ -351,6 +328,7 @@ 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,
...@@ -359,6 +337,7 @@ class FlutterDevice { ...@@ -359,6 +337,7 @@ 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,
...@@ -367,6 +346,7 @@ class FlutterDevice { ...@@ -367,6 +346,7 @@ 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,
...@@ -375,6 +355,7 @@ class FlutterDevice { ...@@ -375,6 +355,7 @@ 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,
...@@ -383,6 +364,7 @@ class FlutterDevice { ...@@ -383,6 +364,7 @@ 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,
...@@ -391,6 +373,7 @@ class FlutterDevice { ...@@ -391,6 +373,7 @@ 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,
...@@ -399,6 +382,7 @@ class FlutterDevice { ...@@ -399,6 +382,7 @@ 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,
...@@ -407,6 +391,7 @@ class FlutterDevice { ...@@ -407,6 +391,7 @@ 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,
...@@ -415,6 +400,7 @@ class FlutterDevice { ...@@ -415,6 +400,7 @@ 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,
...@@ -423,6 +409,7 @@ class FlutterDevice { ...@@ -423,6 +409,7 @@ 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(
...@@ -764,15 +751,17 @@ abstract class ResidentRunner { ...@@ -764,15 +751,17 @@ 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: flutterDevices isolateId: views
.first.views
.first.uiIsolate.id .first.uiIsolate.id
); );
} }
...@@ -811,13 +800,23 @@ abstract class ResidentRunner { ...@@ -811,13 +800,23 @@ 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: flutterDevices.first.views.first.id, viewId: views.first.id,
); );
if (data.isEmpty) { if (data.isEmpty) {
globals.logger.printStatus( globals.logger.printStatus(
...@@ -902,78 +901,61 @@ abstract class ResidentRunner { ...@@ -902,78 +901,61 @@ 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();
} }
...@@ -997,11 +979,12 @@ abstract class ResidentRunner { ...@@ -997,11 +979,12 @@ 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 device.views) { for (final FlutterView view in views) {
await device.vmService.flutterDebugAllowBanner( await device.vmService.flutterDebugAllowBanner(
false, false,
isolateId: view.uiIsolate.id, isolateId: view.uiIsolate.id,
...@@ -1018,7 +1001,7 @@ abstract class ResidentRunner { ...@@ -1018,7 +1001,7 @@ abstract class ResidentRunner {
} finally { } finally {
if (supportsServiceProtocol && isRunningDebug) { if (supportsServiceProtocol && isRunningDebug) {
try { try {
for (final FlutterView view in device.views) { for (final FlutterView view in views) {
await device.vmService.flutterDebugAllowBanner( await device.vmService.flutterDebugAllowBanner(
true, true,
isolateId: view.uiIsolate.id, isolateId: view.uiIsolate.id,
...@@ -1043,9 +1026,10 @@ abstract class ResidentRunner { ...@@ -1043,9 +1026,10 @@ abstract class ResidentRunner {
} }
Future<void> debugTogglePlatform() async { Future<void> debugTogglePlatform() async {
await refreshViews(); final List<FlutterView> views = await flutterDevices
final String isolateId = flutterDevices .first
.first.views.first.uiIsolate.id; .vmService.getFlutterViews();
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,
...@@ -1078,10 +1062,8 @@ abstract class ResidentRunner { ...@@ -1078,10 +1062,8 @@ 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,
...@@ -1089,21 +1071,16 @@ abstract class ResidentRunner { ...@@ -1089,21 +1071,16 @@ abstract class ResidentRunner {
compileExpression: compileExpression, compileExpression: compileExpression,
reloadMethod: reloadMethod, reloadMethod: reloadMethod,
); );
await device.refreshViews(); // This will wait for at least one flutter view before returning.
if (device.views.isNotEmpty) { final Status status = globals.logger.startProgress(
viewFound = true; 'Waiting for ${device.device.name} to report its views...',
} timeout: const Duration(milliseconds: 200),
} );
if (!viewFound) { try {
if (flutterDevices.length == 1) { await device.vmService.getFlutterViews();
throw 'No Flutter view is available on ${flutterDevices.first.device.name}.'; } finally {
} 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.
...@@ -1372,8 +1349,7 @@ class TerminalHandler { ...@@ -1372,8 +1349,7 @@ class TerminalHandler {
} }
return false; return false;
case 'l': case 'l':
final List<FlutterView> views = residentRunner.flutterDevices final List<FlutterView> views = await residentRunner.listFlutterViews();
.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,7 +95,6 @@ class ColdRunner extends ResidentRunner { ...@@ -95,7 +95,6 @@ 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}');
} }
...@@ -145,9 +144,9 @@ class ColdRunner extends ResidentRunner { ...@@ -145,9 +144,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) {
for (final FlutterView view in device.views) { final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
globals.printTrace('Connected to $view.'); globals.printTrace('Connected to $view.');
} }
} }
......
...@@ -198,7 +198,8 @@ class HotRunner extends ResidentRunner { ...@@ -198,7 +198,8 @@ class HotRunner extends ResidentRunner {
} }
for (final FlutterDevice device in flutterDevices) { for (final FlutterDevice device in flutterDevices) {
for (final FlutterView view in device.views) { final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
await device.vmService.flutterFastReassemble( await device.vmService.flutterFastReassemble(
classId, classId,
isolateId: view.uiIsolate.id, isolateId: view.uiIsolate.id,
...@@ -277,14 +278,14 @@ class HotRunner extends ResidentRunner { ...@@ -277,14 +278,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();
} }
for (final FlutterView view in device.views) { final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
globals.printTrace('Connected to $view.'); globals.printTrace('Connected to $view.');
} }
} }
...@@ -474,15 +475,15 @@ class HotRunner extends ResidentRunner { ...@@ -474,15 +475,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 device.views) for (final FlutterView view in 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 {
...@@ -501,7 +502,8 @@ class HotRunner extends ResidentRunner { ...@@ -501,7 +502,8 @@ class HotRunner extends ResidentRunner {
if (benchmarkMode) { if (benchmarkMode) {
futures.clear(); futures.clear();
for (final FlutterDevice device in flutterDevices) { for (final FlutterDevice device in flutterDevices) {
for (final FlutterView view in device.views) { final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
futures.add(device.vmService futures.add(device.vmService
.flushUIThreadTasks(uiIsolateId: view.uiIsolate.id)); .flushUIThreadTasks(uiIsolateId: view.uiIsolate.id));
} }
...@@ -514,9 +516,6 @@ class HotRunner extends ResidentRunner { ...@@ -514,9 +516,6 @@ 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.
...@@ -541,7 +540,8 @@ class HotRunner extends ResidentRunner { ...@@ -541,7 +540,8 @@ 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>{};
for (final FlutterView view in device.views) { final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
if (view.uiIsolate == null) { if (view.uiIsolate == null) {
continue; continue;
} }
...@@ -810,7 +810,8 @@ class HotRunner extends ResidentRunner { ...@@ -810,7 +810,8 @@ 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) {
for (final FlutterView view in device.views) { final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
if (view.uiIsolate == null) { if (view.uiIsolate == null) {
return OperationResult(2, 'Application isolate not found', fatal: true); return OperationResult(2, 'Application isolate not found', fatal: true);
} }
...@@ -818,10 +819,6 @@ class HotRunner extends ResidentRunner { ...@@ -818,10 +819,6 @@ 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.
...@@ -912,14 +909,6 @@ class HotRunner extends ResidentRunner { ...@@ -912,14 +909,6 @@ 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
...@@ -930,7 +919,8 @@ class HotRunner extends ResidentRunner { ...@@ -930,7 +919,8 @@ 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) {
for (final FlutterView view in device.views) { final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
// Check if the isolate is paused, and if so, don't reassemble. Ignore the // 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
...@@ -1055,11 +1045,7 @@ class HotRunner extends ResidentRunner { ...@@ -1055,11 +1045,7 @@ class HotRunner extends ResidentRunner {
final StringBuffer message = StringBuffer(); final StringBuffer message = StringBuffer();
bool plural; bool plural;
if (pausedIsolatesFound == 1) { if (pausedIsolatesFound == 1) {
if (flutterDevices.length == 1 && flutterDevices.single.views.length == 1) {
message.write('The application is '); 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 ');
...@@ -1121,13 +1107,14 @@ class HotRunner extends ResidentRunner { ...@@ -1121,13 +1107,14 @@ class HotRunner extends ResidentRunner {
} }
} }
Future<void> _evictDirtyAssets() { Future<void> _evictDirtyAssets() async {
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;
} }
if (device.views.first.uiIsolate == null) { final List<FlutterView> views = await device.vmService.getFlutterViews();
if (views.first.uiIsolate == null) {
globals.printError('Application isolate not found for $device'); globals.printError('Application isolate not found for $device');
continue; continue;
} }
...@@ -1136,7 +1123,7 @@ class HotRunner extends ResidentRunner { ...@@ -1136,7 +1123,7 @@ class HotRunner extends ResidentRunner {
device.vmService device.vmService
.flutterEvictAsset( .flutterEvictAsset(
assetPath, assetPath,
isolateId: device.views.first.uiIsolate.id, isolateId: views.first.uiIsolate.id,
) )
); );
} }
......
...@@ -684,15 +684,29 @@ extension FlutterVmService on vm_service.VmService { ...@@ -684,15 +684,29 @@ 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]
/// is set to true.
///
/// By default, the poll duration is 50 milliseconds.
Future<List<FlutterView>> getFlutterViews({
bool returnEarly = false,
Duration delay = const Duration(milliseconds: 50),
}) async {
while (true) {
final vm_service.Response response = await callMethod( final vm_service.Response response = await callMethod(
kListViewsMethod, kListViewsMethod,
); );
final List<Object> rawViews = response.json['views'] as List<Object>; final List<Object> rawViews = response.json['views'] as List<Object>;
return <FlutterView>[ final List<FlutterView> views = <FlutterView>[
for (final Object rawView in rawViews) for (final Object rawView in rawViews)
FlutterView.parse(rawView as Map<String, Object>) 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 => true; bool get supportsFlutterExit => false;
@override @override
bool get supportsScreenshot => false; bool get supportsScreenshot => false;
...@@ -343,6 +343,9 @@ class WebServerDevice extends Device { ...@@ -343,6 +343,9 @@ 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,7 +685,6 @@ VMServiceConnector getFakeVmServiceFactory({ ...@@ -685,7 +685,6 @@ 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>{
...@@ -698,14 +697,12 @@ VMServiceConnector getFakeVmServiceFactory({ ...@@ -698,14 +697,12 @@ 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,
...@@ -715,7 +712,6 @@ VMServiceConnector getFakeVmServiceFactory({ ...@@ -715,7 +712,6 @@ 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': true, 'flutterExit': false,
'hardwareRendering': false, 'hardwareRendering': false,
'startPaused': true 'startPaused': true
} }
......
...@@ -12,7 +12,6 @@ void main() { ...@@ -12,7 +12,6 @@ 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>[
...@@ -23,7 +22,6 @@ void main() { ...@@ -23,7 +22,6 @@ 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,7 +129,6 @@ void main() { ...@@ -129,7 +129,6 @@ 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',
...@@ -202,7 +201,6 @@ void main() { ...@@ -202,7 +201,6 @@ 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,7 +637,6 @@ void main() { ...@@ -637,7 +637,6 @@ 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,6 +21,36 @@ import '../src/common.dart'; ...@@ -21,6 +21,36 @@ 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 {
...@@ -172,42 +202,72 @@ void main() { ...@@ -172,42 +202,72 @@ 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>[
const FakeVmServiceRequest( listViews,
id: '1', FakeVmServiceRequest(
method: kListViewsMethod, method: 'getIsolate',
jsonResponse: <String, Object>{ args: <String, Object>{
'views': <Object>[], 'isolateId': fakeUnpausedIsolate.id,
} },
), 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(
id: '5', method: 'streamListen',
method: kListViewsMethod, args: <String, Object>{
jsonResponse: <String, Object>{ 'streamId': 'Isolate',
'views': <Object>[],
} }
), ),
const FakeVmServiceRequest( const FakeVmServiceRequest(
id: '6', method: 'streamListen',
method: kListViewsMethod, args: <String, Object>{
jsonResponse: <String, Object>{ 'streamId': 'Isolate',
'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',
} }
), ),
]); ]);
...@@ -257,25 +317,40 @@ void main() { ...@@ -257,25 +317,40 @@ 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>[
const FakeVmServiceRequest( listViews,
id: '1', FakeVmServiceRequest(
method: kListViewsMethod, method: 'getIsolate',
jsonResponse: <String, Object>{ args: <String, Object>{
'views': <Object>[], 'isolateId': fakeUnpausedIsolate.id,
} },
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: kListViewsMethod, args: <String, Object>{
jsonResponse: <String, Object>{ 'streamId': 'Isolate',
'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,6 +70,15 @@ final FlutterView fakeFlutterView = FlutterView( ...@@ -70,6 +70,15 @@ 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;
...@@ -127,10 +136,6 @@ void main() { ...@@ -127,10 +136,6 @@ 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));
...@@ -146,7 +151,6 @@ void main() { ...@@ -146,7 +151,6 @@ 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>{
...@@ -166,15 +170,7 @@ void main() { ...@@ -166,15 +170,7 @@ 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>[
FakeVmServiceRequest( listViews,
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(
...@@ -184,14 +180,13 @@ void main() { ...@@ -184,14 +180,13 @@ 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(
...@@ -207,12 +202,15 @@ void main() { ...@@ -207,12 +202,15 @@ 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,
...@@ -220,19 +218,17 @@ void main() { ...@@ -220,19 +218,17 @@ 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,
...@@ -284,10 +280,15 @@ void main() { ...@@ -284,10 +280,15 @@ 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';
}); });
...@@ -329,15 +330,18 @@ void main() { ...@@ -329,15 +330,18 @@ 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>[
// Not all requests are present due to existing mocks listViews,
listViews,
listViews,
listViews,
FakeVmServiceRequest( FakeVmServiceRequest(
id: '1',
method: 'getIsolate', method: 'getIsolate',
args: <String, Object>{ args: <String, Object>{
'isolateId': '1', 'isolateId': '1',
...@@ -345,7 +349,6 @@ void main() { ...@@ -345,7 +349,6 @@ 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,
...@@ -381,10 +384,11 @@ void main() { ...@@ -381,10 +384,11 @@ 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,
...@@ -392,19 +396,17 @@ void main() { ...@@ -392,19 +396,17 @@ 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,
...@@ -445,12 +447,16 @@ void main() { ...@@ -445,12 +447,16 @@ 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';
}); });
...@@ -493,6 +499,7 @@ void main() { ...@@ -493,6 +499,7 @@ 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(),
})); }));
...@@ -578,14 +585,15 @@ void main() { ...@@ -578,14 +585,15 @@ 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,
...@@ -593,17 +601,18 @@ void main() { ...@@ -593,17 +601,18 @@ 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,
...@@ -634,8 +643,8 @@ void main() { ...@@ -634,8 +643,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,
...@@ -643,7 +652,6 @@ void main() { ...@@ -643,7 +652,6 @@ 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,
...@@ -676,8 +684,8 @@ void main() { ...@@ -676,8 +684,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,
...@@ -696,8 +704,8 @@ void main() { ...@@ -696,8 +704,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,
...@@ -705,7 +713,6 @@ void main() { ...@@ -705,7 +713,6 @@ 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,
...@@ -719,12 +726,13 @@ void main() { ...@@ -719,12 +726,13 @@ 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,
...@@ -732,7 +740,6 @@ void main() { ...@@ -732,7 +740,6 @@ 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,
...@@ -754,10 +761,13 @@ void main() { ...@@ -754,10 +761,13 @@ 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,
...@@ -781,7 +791,6 @@ void main() { ...@@ -781,7 +791,6 @@ 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>[
...@@ -790,7 +799,6 @@ void main() { ...@@ -790,7 +799,6 @@ void main() {
}, },
), ),
FakeVmServiceRequest( FakeVmServiceRequest(
id: '2',
method: 'getIsolate', method: 'getIsolate',
args: <String, Object>{ args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id, 'isolateId': fakeUnpausedIsolate.id,
...@@ -800,7 +808,6 @@ void main() { ...@@ -800,7 +808,6 @@ 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);
...@@ -814,7 +821,6 @@ void main() { ...@@ -814,7 +821,6 @@ 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>[
...@@ -823,7 +829,6 @@ void main() { ...@@ -823,7 +829,6 @@ void main() {
}, },
), ),
FakeVmServiceRequest( FakeVmServiceRequest(
id: '2',
method: 'getIsolate', method: 'getIsolate',
args: <String, Object>{ args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id, 'isolateId': fakeUnpausedIsolate.id,
...@@ -831,7 +836,6 @@ void main() { ...@@ -831,7 +836,6 @@ 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,
...@@ -842,7 +846,6 @@ void main() { ...@@ -842,7 +846,6 @@ 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);
...@@ -858,7 +861,6 @@ void main() { ...@@ -858,7 +861,6 @@ 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>[
...@@ -867,7 +869,6 @@ void main() { ...@@ -867,7 +869,6 @@ void main() {
}, },
), ),
FakeVmServiceRequest( FakeVmServiceRequest(
id: '2',
method: 'getIsolate', method: 'getIsolate',
args: <String, Object>{ args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id 'isolateId': fakeUnpausedIsolate.id
...@@ -875,7 +876,6 @@ void main() { ...@@ -875,7 +876,6 @@ 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,7 +885,6 @@ void main() { ...@@ -885,7 +885,6 @@ void main() {
]); ]);
final TestFlutterDevice flutterDevice = TestFlutterDevice( final TestFlutterDevice flutterDevice = TestFlutterDevice(
mockDevice, mockDevice,
<FlutterView> [fakeFlutterView ],
); );
flutterDevice.vmService = fakeVmServiceHost.vmService; flutterDevice.vmService = fakeVmServiceHost.vmService;
...@@ -897,18 +896,10 @@ void main() { ...@@ -897,18 +896,10 @@ 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);
})); }));
...@@ -916,7 +907,6 @@ void main() { ...@@ -916,7 +907,6 @@ 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);
})); }));
...@@ -924,7 +914,6 @@ void main() { ...@@ -924,7 +914,6 @@ 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);
})); }));
...@@ -932,7 +921,6 @@ void main() { ...@@ -932,7 +921,6 @@ 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);
})); }));
...@@ -940,7 +928,6 @@ void main() { ...@@ -940,7 +928,6 @@ 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);
})); }));
...@@ -948,7 +935,6 @@ void main() { ...@@ -948,7 +935,6 @@ 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);
})); }));
...@@ -956,7 +942,6 @@ void main() { ...@@ -956,7 +942,6 @@ 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);
})); }));
...@@ -964,7 +949,6 @@ void main() { ...@@ -964,7 +949,6 @@ 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);
})); }));
...@@ -972,7 +956,6 @@ void main() { ...@@ -972,7 +956,6 @@ 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);
})); }));
...@@ -980,12 +963,14 @@ void main() { ...@@ -980,12 +963,14 @@ 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(
...@@ -1007,7 +992,10 @@ void main() { ...@@ -1007,7 +992,10 @@ 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);
...@@ -1035,7 +1023,10 @@ void main() { ...@@ -1035,7 +1023,10 @@ 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>[
...@@ -1053,13 +1044,16 @@ void main() { ...@@ -1053,13 +1044,16 @@ 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(
...@@ -1078,6 +1072,7 @@ void main() { ...@@ -1078,6 +1072,7 @@ 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 {
...@@ -1117,7 +1112,6 @@ void main() { ...@@ -1117,7 +1112,6 @@ void main() {
final TestFlutterDevice flutterDevice = TestFlutterDevice( final TestFlutterDevice flutterDevice = TestFlutterDevice(
mockDevice, mockDevice,
<FlutterView>[],
observatoryUris: Stream<Uri>.value(testUri), observatoryUris: Stream<Uri>.value(testUri),
); );
...@@ -1153,14 +1147,11 @@ class MockUsage extends Mock implements Usage {} ...@@ -1153,14 +1147,11 @@ 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, this.views, { Stream<Uri> observatoryUris }) TestFlutterDevice(Device device, { 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,14 +36,12 @@ import '../src/testbed.dart'; ...@@ -36,14 +36,12 @@ 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',
...@@ -53,14 +51,12 @@ const List<VmServiceExpectation> kAttachLogExpectations = <VmServiceExpectation> ...@@ -53,14 +51,12 @@ 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',
...@@ -362,7 +358,6 @@ void main() { ...@@ -362,7 +358,6 @@ void main() {
...kAttachExpectations, ...kAttachExpectations,
const FakeVmServiceRequest( const FakeVmServiceRequest(
method: 'hotRestart', method: 'hotRestart',
id: '5',
jsonResponse: <String, Object>{ jsonResponse: <String, Object>{
'type': 'Success', 'type': 'Success',
} }
...@@ -439,7 +434,6 @@ void main() { ...@@ -439,7 +434,6 @@ void main() {
...kAttachExpectations, ...kAttachExpectations,
const FakeVmServiceRequest( const FakeVmServiceRequest(
method: 'hotRestart', method: 'hotRestart',
id: '5',
jsonResponse: <String, Object>{ jsonResponse: <String, Object>{
'type': 'Success', 'type': 'Success',
} }
...@@ -670,7 +664,6 @@ void main() { ...@@ -670,7 +664,6 @@ 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',
...@@ -693,7 +686,6 @@ void main() { ...@@ -693,7 +686,6 @@ 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,
...@@ -725,7 +717,6 @@ void main() { ...@@ -725,7 +717,6 @@ 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,
...@@ -747,7 +738,6 @@ void main() { ...@@ -747,7 +738,6 @@ 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,
...@@ -769,7 +759,6 @@ void main() { ...@@ -769,7 +759,6 @@ 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,
...@@ -791,7 +780,6 @@ void main() { ...@@ -791,7 +780,6 @@ 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,
...@@ -813,7 +801,6 @@ void main() { ...@@ -813,7 +801,6 @@ 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,
...@@ -836,7 +823,6 @@ void main() { ...@@ -836,7 +823,6 @@ 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,
...@@ -846,7 +832,6 @@ void main() { ...@@ -846,7 +832,6 @@ 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,
...@@ -874,7 +859,6 @@ void main() { ...@@ -874,7 +859,6 @@ 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,
...@@ -884,7 +868,6 @@ void main() { ...@@ -884,7 +868,6 @@ 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,
...@@ -911,7 +894,6 @@ void main() { ...@@ -911,7 +894,6 @@ 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,
...@@ -921,7 +903,6 @@ void main() { ...@@ -921,7 +903,6 @@ 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,
...@@ -948,7 +929,6 @@ void main() { ...@@ -948,7 +929,6 @@ 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,
...@@ -958,7 +938,6 @@ void main() { ...@@ -958,7 +938,6 @@ 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,
...@@ -985,7 +964,6 @@ void main() { ...@@ -985,7 +964,6 @@ 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,
...@@ -995,7 +973,6 @@ void main() { ...@@ -995,7 +973,6 @@ 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,
...@@ -1089,14 +1066,12 @@ void main() { ...@@ -1089,14 +1066,12 @@ 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,7 +139,9 @@ void main() { ...@@ -139,7 +139,9 @@ 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(mockFlutterDevice.views).thenReturn(<FlutterView>[]); when(mockResidentRunner.listFlutterViews()).thenAnswer((Invocation invocation) async {
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', id: '1', args: <String, Object>{ const FakeVmServiceRequest(method: 'streamListen', args: <String, Object>{
'streamId': 'Isolate' 'streamId': 'Isolate'
}), }),
const FakeVmServiceRequest(method: kRunInViewMethod, id: '2', args: <String, Object>{ const FakeVmServiceRequest(method: kRunInViewMethod, args: <String, Object>{
'viewId': '1234', 'viewId': '1234',
'mainScript': 'main.dart', 'mainScript': 'main.dart',
'assetDirectory': 'flutter_assets/', 'assetDirectory': 'flutter_assets/',
...@@ -256,6 +256,65 @@ void main() { ...@@ -256,6 +256,65 @@ 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, true); expect(chromeDevice.supportsFlutterExit, false);
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, true); expect(chromeDevice.supportsFlutterExit, false);
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, true); expect(device.supportsFlutterExit, false);
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,7 +239,6 @@ class FakeVmServiceHost { ...@@ -239,7 +239,6 @@ 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) {
...@@ -250,13 +249,13 @@ class FakeVmServiceHost { ...@@ -250,13 +249,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': fakeRequest.id, 'id': request['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': fakeRequest.id, 'id': request['id'],
'error': <String, Object>{ 'error': <String, Object>{
'code': fakeRequest.errorCode, 'code': fakeRequest.errorCode,
} }
...@@ -299,7 +298,6 @@ abstract class VmServiceExpectation { ...@@ -299,7 +298,6 @@ 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,
...@@ -307,7 +305,6 @@ class FakeVmServiceRequest implements VmServiceExpectation { ...@@ -307,7 +305,6 @@ 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