Unverified Commit 9b7b9d79 authored by Jonah Williams's avatar Jonah Williams Committed by GitHub

[flutter_tools] reland remove flutter view cache (#56387)

Fixes #56194

Remove caching of FlutterView and poll forever if the list of flutter views is empty. Added test for missing release mode logic.
parent f84d16a5
...@@ -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 {
......
...@@ -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 { ///
final vm_service.Response response = await callMethod( /// If this returns an empty list, it will poll forever unless [returnEarly]
kListViewsMethod, /// is set to true.
); ///
final List<Object> rawViews = response.json['views'] as List<Object>; /// By default, the poll duration is 50 milliseconds.
return <FlutterView>[ Future<List<FlutterView>> getFlutterViews({
for (final Object rawView in rawViews) bool returnEarly = false,
FlutterView.parse(rawView as Map<String, Object>) Duration delay = const Duration(milliseconds: 50),
]; }) async {
while (true) {
final vm_service.Response response = await callMethod(
kListViewsMethod,
);
final List<Object> rawViews = response.json['views'] as List<Object>;
final List<FlutterView> views = <FlutterView>[
for (final Object rawView in rawViews)
FlutterView.parse(rawView as Map<String, Object>)
];
if (views.isNotEmpty || returnEarly) {
return views;
}
await Future<void>.delayed(delay);
}
} }
/// Attempt to retrieve the isolate with id [isolateId], or `null` if it has /// 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);
......
...@@ -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