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 {
globals.printStatus('For a more detailed help message, press "h". $quitMessage');
}
@override
Future<List<FlutterView>> listFlutterViews() async {
return <FlutterView>[];
}
@override
Future<void> debugDumpApp() async {
try {
......
......@@ -95,7 +95,6 @@ class ColdRunner extends ResidentRunner {
continue;
}
await device.initLogReader();
await device.refreshViews();
globals.printTrace('Connected to ${device.device.name}');
}
......@@ -145,9 +144,9 @@ class ColdRunner extends ResidentRunner {
for (final FlutterDevice device in flutterDevices) {
await device.initLogReader();
}
await refreshViews();
for (final FlutterDevice device in flutterDevices) {
for (final FlutterView view in device.views) {
final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
globals.printTrace('Connected to $view.');
}
}
......
......@@ -198,7 +198,8 @@ class HotRunner extends ResidentRunner {
}
for (final FlutterDevice device in flutterDevices) {
for (final FlutterView view in device.views) {
final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
await device.vmService.flutterFastReassemble(
classId,
isolateId: view.uiIsolate.id,
......@@ -277,14 +278,14 @@ class HotRunner extends ResidentRunner {
return 3;
}
await refreshViews();
for (final FlutterDevice device in flutterDevices) {
// VM must have accepted the kernel binary, there will be no reload
// report, so we let incremental compiler know that source code was accepted.
if (device.generator != null) {
device.generator.accept();
}
for (final FlutterView view in device.views) {
final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
globals.printTrace('Connected to $view.');
}
}
......@@ -474,15 +475,15 @@ class HotRunner extends ResidentRunner {
Uri main,
Uri assetsDirectory,
) async {
final List<FlutterView> views = await device.vmService.getFlutterViews();
await Future.wait(<Future<void>>[
for (final FlutterView view in device.views)
for (final FlutterView view in views)
device.vmService.runInView(
viewId: view.id,
main: main,
assetsDirectory: assetsDirectory,
),
]);
await device.refreshViews();
}
Future<void> _launchFromDevFS(String mainScript) async {
......@@ -501,7 +502,8 @@ class HotRunner extends ResidentRunner {
if (benchmarkMode) {
futures.clear();
for (final FlutterDevice device in flutterDevices) {
for (final FlutterView view in device.views) {
final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
futures.add(device.vmService
.flushUIThreadTasks(uiIsolateId: view.uiIsolate.id));
}
......@@ -514,9 +516,6 @@ class HotRunner extends ResidentRunner {
String reason,
bool benchmarkMode = false,
}) async {
globals.printTrace('Refreshing active FlutterViews before restarting.');
await refreshViews();
final Stopwatch restartTimer = Stopwatch()..start();
// TODO(aam): Add generator reset logic once we switch to using incremental
// compiler for full application recompilation on restart.
......@@ -541,7 +540,8 @@ class HotRunner extends ResidentRunner {
final List<Future<void>> operations = <Future<void>>[];
for (final FlutterDevice device in flutterDevices) {
final Set<String> uiIsolatesIds = <String>{};
for (final FlutterView view in device.views) {
final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
if (view.uiIsolate == null) {
continue;
}
......@@ -810,7 +810,8 @@ class HotRunner extends ResidentRunner {
void Function(String message) onSlow,
}) async {
for (final FlutterDevice device in flutterDevices) {
for (final FlutterView view in device.views) {
final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
if (view.uiIsolate == null) {
return OperationResult(2, 'Application isolate not found', fatal: true);
}
......@@ -818,10 +819,6 @@ class HotRunner extends ResidentRunner {
}
final Stopwatch reloadTimer = Stopwatch()..start();
globals.printTrace('Refreshing active FlutterViews before reloading.');
await refreshViews();
final Stopwatch devFSTimer = Stopwatch()..start();
final UpdateFSReport updatedDevFS = await _updateDevFS();
// Record time it took to synchronize to DevFS.
......@@ -912,14 +909,6 @@ class HotRunner extends ResidentRunner {
// Record time it took for the VM to reload the sources.
_addBenchmarkData('hotReloadVMReloadMilliseconds', vmReloadTimer.elapsed.inMilliseconds);
final Stopwatch reassembleTimer = Stopwatch()..start();
// Reload the isolate data.
await Future.wait(<Future<void>>[
for (final FlutterDevice device in flutterDevices)
device.refreshViews()
]);
globals.printTrace('Evicting dirty assets');
await _evictDirtyAssets();
// Check if any isolates are paused and reassemble those
......@@ -930,7 +919,8 @@ class HotRunner extends ResidentRunner {
int pausedIsolatesFound = 0;
bool failedReassemble = false;
for (final FlutterDevice device in flutterDevices) {
for (final FlutterView view in device.views) {
final List<FlutterView> views = await device.vmService.getFlutterViews();
for (final FlutterView view in views) {
// Check if the isolate is paused, and if so, don't reassemble. Ignore the
// PostPauseEvent event - the client requesting the pause will resume the app.
final vm_service.Isolate isolate = await device.vmService
......@@ -1055,11 +1045,7 @@ class HotRunner extends ResidentRunner {
final StringBuffer message = StringBuffer();
bool plural;
if (pausedIsolatesFound == 1) {
if (flutterDevices.length == 1 && flutterDevices.single.views.length == 1) {
message.write('The application is ');
} else {
message.write('An isolate is ');
}
message.write('The application is ');
plural = false;
} else {
message.write('$pausedIsolatesFound isolates are ');
......@@ -1121,13 +1107,14 @@ class HotRunner extends ResidentRunner {
}
}
Future<void> _evictDirtyAssets() {
Future<void> _evictDirtyAssets() async {
final List<Future<Map<String, dynamic>>> futures = <Future<Map<String, dynamic>>>[];
for (final FlutterDevice device in flutterDevices) {
if (device.devFS.assetPathsToEvict.isEmpty) {
continue;
}
if (device.views.first.uiIsolate == null) {
final List<FlutterView> views = await device.vmService.getFlutterViews();
if (views.first.uiIsolate == null) {
globals.printError('Application isolate not found for $device');
continue;
}
......@@ -1136,7 +1123,7 @@ class HotRunner extends ResidentRunner {
device.vmService
.flutterEvictAsset(
assetPath,
isolateId: device.views.first.uiIsolate.id,
isolateId: views.first.uiIsolate.id,
)
);
}
......
......@@ -684,15 +684,29 @@ extension FlutterVmService on vm_service.VmService {
}
/// List all [FlutterView]s attached to the current VM.
Future<List<FlutterView>> getFlutterViews() async {
final vm_service.Response response = await callMethod(
kListViewsMethod,
);
final List<Object> rawViews = response.json['views'] as List<Object>;
return <FlutterView>[
for (final Object rawView in rawViews)
FlutterView.parse(rawView as Map<String, Object>)
];
///
/// If this returns an empty list, it will poll forever unless [returnEarly]
/// is set to true.
///
/// By default, the poll duration is 50 milliseconds.
Future<List<FlutterView>> getFlutterViews({
bool returnEarly = false,
Duration delay = const Duration(milliseconds: 50),
}) async {
while (true) {
final vm_service.Response response = await callMethod(
kListViewsMethod,
);
final List<Object> rawViews = response.json['views'] as List<Object>;
final List<FlutterView> views = <FlutterView>[
for (final Object rawView in rawViews)
FlutterView.parse(rawView as Map<String, Object>)
];
if (views.isNotEmpty || returnEarly) {
return views;
}
await Future<void>.delayed(delay);
}
}
/// Attempt to retrieve the isolate with id [isolateId], or `null` if it has
......
......@@ -66,7 +66,7 @@ abstract class ChromiumDevice extends Device {
bool get supportsStartPaused => true;
@override
bool get supportsFlutterExit => true;
bool get supportsFlutterExit => false;
@override
bool get supportsScreenshot => false;
......@@ -343,6 +343,9 @@ class WebServerDevice extends Device {
@override
Future<bool> isLatestBuildInstalled(ApplicationPackage app) async => true;
@override
bool get supportsFlutterExit => false;
@override
Future<bool> get isLocalEmulator async => false;
......
......@@ -685,7 +685,6 @@ VMServiceConnector getFakeVmServiceFactory({
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
id: '1',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
......@@ -698,14 +697,12 @@ VMServiceConnector getFakeVmServiceFactory({
},
),
FakeVmServiceRequest(
id: '2',
method: 'getVM',
args: null,
jsonResponse: vm_service.VM.parse(<String, Object>{})
.toJson(),
),
FakeVmServiceRequest(
id: '3',
method: '_createDevFS',
args: <String, Object>{
'fsName': globals.fs.currentDirectory.absolute.path,
......@@ -715,7 +712,6 @@ VMServiceConnector getFakeVmServiceFactory({
},
),
FakeVmServiceRequest(
id: '4',
method: kListViewsMethod,
args: null,
jsonResponse: <String, Object>{
......
......@@ -65,7 +65,7 @@ void main() {
'hotRestart': true,
'screenshot': false,
'fastStart': false,
'flutterExit': true,
'flutterExit': false,
'hardwareRendering': false,
'startPaused': true
}
......
......@@ -12,7 +12,6 @@ void main() {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
id: '1',
method: 'getVM',
jsonResponse: (vm_service.VM.parse(<String, Object>{})
..isolates = <vm_service.IsolateRef>[
......@@ -23,7 +22,6 @@ void main() {
).toJson(),
),
const FakeVmServiceRequest(
id: '2',
method: 'getScripts',
args: <String, Object>{
'isolateId': '1',
......
......@@ -129,7 +129,6 @@ void main() {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
id: '1',
method: '_createDevFS',
args: <String, Object>{
'fsName': 'test',
......@@ -202,7 +201,6 @@ void main() {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
id: '1',
method: '_createDevFS',
args: <String, Object>{
'fsName': 'test',
......
......@@ -637,7 +637,6 @@ void main() {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
FakeVmServiceRequest(
id: '1',
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[
......
......@@ -21,6 +21,36 @@ import '../src/common.dart';
import '../src/context.dart';
import '../src/mocks.dart';
final vm_service.Isolate fakeUnpausedIsolate = vm_service.Isolate(
id: '1',
pauseEvent: vm_service.Event(
kind: vm_service.EventKind.kResume,
timestamp: 0
),
breakpoints: <vm_service.Breakpoint>[],
exceptionPauseMode: null,
libraries: <vm_service.LibraryRef>[],
livePorts: 0,
name: 'test',
number: '1',
pauseOnExit: false,
runnable: true,
startTime: 0,
);
final FlutterView fakeFlutterView = FlutterView(
id: 'a',
uiIsolate: fakeUnpausedIsolate,
);
final FakeVmServiceRequest listViews = FakeVmServiceRequest(
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[
fakeFlutterView.toJson(),
],
},
);
void main() {
group('validateReloadReport', () {
testUsingContext('invalid', () async {
......@@ -172,42 +202,72 @@ void main() {
testUsingContext('Does hot restarts when all devices support it', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
const FakeVmServiceRequest(
id: '1',
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[],
}
),
const FakeVmServiceRequest(
id: '2',
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[],
}
listViews,
FakeVmServiceRequest(
method: 'getIsolate',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
},
jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
id: '3',
method: 'getVM',
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson()
),
listViews,
FakeVmServiceRequest(
method: 'getIsolate',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
},
jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
id: '4',
method: 'getVM',
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson()
),
listViews,
listViews,
const FakeVmServiceRequest(
id: '5',
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[],
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate',
}
),
const FakeVmServiceRequest(
id: '6',
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[],
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate',
}
),
FakeVmServiceStreamResponse(
streamId: 'Isolate',
event: vm_service.Event(
timestamp: 0,
kind: vm_service.EventKind.kIsolateRunnable,
)
),
FakeVmServiceStreamResponse(
streamId: 'Isolate',
event: vm_service.Event(
timestamp: 0,
kind: vm_service.EventKind.kIsolateRunnable,
)
),
FakeVmServiceRequest(
method: kRunInViewMethod,
args: <String, Object>{
'viewId': fakeFlutterView.id,
'mainScript': 'lib/main.dart.dill',
'assetDirectory': 'build/flutter_assets',
}
),
FakeVmServiceRequest(
method: kRunInViewMethod,
args: <String, Object>{
'viewId': fakeFlutterView.id,
'mainScript': 'lib/main.dart.dill',
'assetDirectory': 'build/flutter_assets',
}
),
]);
......@@ -257,25 +317,40 @@ void main() {
testUsingContext('hot restart supported', () async {
// Setup mocks
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
const FakeVmServiceRequest(
id: '1',
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[],
}
listViews,
FakeVmServiceRequest(
method: 'getIsolate',
args: <String, Object>{
'isolateId': fakeUnpausedIsolate.id,
},
jsonResponse: fakeUnpausedIsolate.toJson(),
),
FakeVmServiceRequest(
id: '2',
method: 'getVM',
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson()
jsonResponse: vm_service.VM.parse(<String, Object>{}).toJson(),
),
listViews,
const FakeVmServiceRequest(
id: '3',
method: kListViewsMethod,
jsonResponse: <String, Object>{
'views': <Object>[],
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate',
}
),
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();
when(mockDevice.supportsHotReload).thenReturn(true);
......
......@@ -36,14 +36,12 @@ import '../src/testbed.dart';
const List<VmServiceExpectation> kAttachLogExpectations = <VmServiceExpectation>[
FakeVmServiceRequest(
id: '1',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Stdout',
},
),
FakeVmServiceRequest(
id: '2',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Stderr',
......@@ -53,14 +51,12 @@ const List<VmServiceExpectation> kAttachLogExpectations = <VmServiceExpectation>
const List<VmServiceExpectation> kAttachIsolateExpectations = <VmServiceExpectation>[
FakeVmServiceRequest(
id: '3',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate'
}
),
FakeVmServiceRequest(
id: '4',
method: 'registerService',
args: <String, Object>{
'service': 'reloadSources',
......@@ -362,7 +358,6 @@ void main() {
...kAttachExpectations,
const FakeVmServiceRequest(
method: 'hotRestart',
id: '5',
jsonResponse: <String, Object>{
'type': 'Success',
}
......@@ -439,7 +434,6 @@ void main() {
...kAttachExpectations,
const FakeVmServiceRequest(
method: 'hotRestart',
id: '5',
jsonResponse: <String, Object>{
'type': 'Success',
}
......@@ -670,7 +664,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'hotRestart',
jsonResponse: <String, Object>{
'type': 'Failed',
......@@ -693,7 +686,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'hotRestart',
// Failed response,
errorCode: RPCErrorCodes.kInternalError,
......@@ -725,7 +717,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.debugDumpApp',
args: <String, Object>{
'isolateId': null,
......@@ -747,7 +738,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.debugDumpLayerTree',
args: <String, Object>{
'isolateId': null,
......@@ -769,7 +759,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.debugDumpRenderTree',
args: <String, Object>{
'isolateId': null,
......@@ -791,7 +780,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.debugDumpSemanticsTreeInTraversalOrder',
args: <String, Object>{
'isolateId': null,
......@@ -813,7 +801,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.debugDumpSemanticsTreeInInverseHitTestOrder',
args: <String, Object>{
'isolateId': null,
......@@ -836,7 +823,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.debugPaint',
args: <String, Object>{
'isolateId': null,
......@@ -846,7 +832,6 @@ void main() {
},
),
const FakeVmServiceRequest(
id: '6',
method: 'ext.flutter.debugPaint',
args: <String, Object>{
'isolateId': null,
......@@ -874,7 +859,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.showPerformanceOverlay',
args: <String, Object>{
'isolateId': null,
......@@ -884,7 +868,6 @@ void main() {
},
),
const FakeVmServiceRequest(
id: '6',
method: 'ext.flutter.showPerformanceOverlay',
args: <String, Object>{
'isolateId': null,
......@@ -911,7 +894,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.inspector.show',
args: <String, Object>{
'isolateId': null,
......@@ -921,7 +903,6 @@ void main() {
},
),
const FakeVmServiceRequest(
id: '6',
method: 'ext.flutter.inspector.show',
args: <String, Object>{
'isolateId': null,
......@@ -948,7 +929,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.profileWidgetBuilds',
args: <String, Object>{
'isolateId': null,
......@@ -958,7 +938,6 @@ void main() {
},
),
const FakeVmServiceRequest(
id: '6',
method: 'ext.flutter.profileWidgetBuilds',
args: <String, Object>{
'isolateId': null,
......@@ -985,7 +964,6 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachExpectations,
const FakeVmServiceRequest(
id: '5',
method: 'ext.flutter.platformOverride',
args: <String, Object>{
'isolateId': null,
......@@ -995,7 +973,6 @@ void main() {
},
),
const FakeVmServiceRequest(
id: '6',
method: 'ext.flutter.platformOverride',
args: <String, Object>{
'isolateId': null,
......@@ -1089,14 +1066,12 @@ void main() {
fakeVmServiceHost = FakeVmServiceHost(requests: <VmServiceExpectation>[
...kAttachLogExpectations,
const FakeVmServiceRequest(
id: '3',
method: 'streamListen',
args: <String, Object>{
'streamId': 'Isolate'
}
),
const FakeVmServiceRequest(
id: '4',
method: 'registerService',
args: <String, Object>{
'service': 'reloadSources',
......
......@@ -139,7 +139,9 @@ void main() {
final MockFlutterDevice mockFlutterDevice = MockFlutterDevice();
when(mockResidentRunner.isRunningDebug).thenReturn(true);
when(mockResidentRunner.flutterDevices).thenReturn(<FlutterDevice>[mockFlutterDevice]);
when(mockFlutterDevice.views).thenReturn(<FlutterView>[]);
when(mockResidentRunner.listFlutterViews()).thenAnswer((Invocation invocation) async {
return <FlutterView>[];
});
await terminalHandler.processTerminalInput('l');
......
......@@ -231,10 +231,10 @@ void main() {
testWithoutContext('runInView forwards arguments correctly', () async {
final FakeVmServiceHost fakeVmServiceHost = FakeVmServiceHost(
requests: <VmServiceExpectation>[
const FakeVmServiceRequest(method: 'streamListen', id: '1', args: <String, Object>{
const FakeVmServiceRequest(method: 'streamListen', args: <String, Object>{
'streamId': 'Isolate'
}),
const FakeVmServiceRequest(method: kRunInViewMethod, id: '2', args: <String, Object>{
const FakeVmServiceRequest(method: kRunInViewMethod, args: <String, Object>{
'viewId': '1234',
'mainScript': 'main.dart',
'assetDirectory': 'flutter_assets/',
......@@ -256,6 +256,65 @@ void main() {
);
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 {}
......
......@@ -76,7 +76,7 @@ void main() {
expect(chromeDevice.supportsHotReload, true);
expect(chromeDevice.supportsHotRestart, true);
expect(chromeDevice.supportsStartPaused, true);
expect(chromeDevice.supportsFlutterExit, true);
expect(chromeDevice.supportsFlutterExit, false);
expect(chromeDevice.supportsScreenshot, false);
expect(await chromeDevice.isLocalEmulator, false);
expect(chromeDevice.getLogReader(), isA<NoOpDeviceLogReader>());
......@@ -96,7 +96,7 @@ void main() {
expect(chromeDevice.supportsHotReload, true);
expect(chromeDevice.supportsHotRestart, true);
expect(chromeDevice.supportsStartPaused, true);
expect(chromeDevice.supportsFlutterExit, true);
expect(chromeDevice.supportsFlutterExit, false);
expect(chromeDevice.supportsScreenshot, false);
expect(await chromeDevice.isLocalEmulator, false);
expect(chromeDevice.getLogReader(), isA<NoOpDeviceLogReader>());
......@@ -114,7 +114,7 @@ void main() {
expect(device.supportsHotReload, true);
expect(device.supportsHotRestart, true);
expect(device.supportsStartPaused, true);
expect(device.supportsFlutterExit, true);
expect(device.supportsFlutterExit, false);
expect(device.supportsScreenshot, false);
expect(await device.isLocalEmulator, false);
expect(device.getLogReader(), isA<NoOpDeviceLogReader>());
......
......@@ -239,7 +239,6 @@ class FakeVmServiceHost {
final FakeVmServiceRequest fakeRequest = _requests.removeAt(0) as FakeVmServiceRequest;
expect(request, isA<Map<String, Object>>()
.having((Map<String, Object> request) => request['method'], 'method', fakeRequest.method)
.having((Map<String, Object> request) => request['id'], 'id', fakeRequest.id)
.having((Map<String, Object> request) => request['params'], 'args', fakeRequest.args)
);
if (fakeRequest.close) {
......@@ -250,13 +249,13 @@ class FakeVmServiceHost {
if (fakeRequest.errorCode == null) {
_input.add(json.encode(<String, Object>{
'jsonrpc': '2.0',
'id': fakeRequest.id,
'id': request['id'],
'result': fakeRequest.jsonResponse ?? <String, Object>{'type': 'Success'},
}));
} else {
_input.add(json.encode(<String, Object>{
'jsonrpc': '2.0',
'id': fakeRequest.id,
'id': request['id'],
'error': <String, Object>{
'code': fakeRequest.errorCode,
}
......@@ -299,7 +298,6 @@ abstract class VmServiceExpectation {
class FakeVmServiceRequest implements VmServiceExpectation {
const FakeVmServiceRequest({
@required this.method,
@required this.id,
this.args = const <String, Object>{},
this.jsonResponse,
this.errorCode,
......@@ -307,7 +305,6 @@ class FakeVmServiceRequest implements VmServiceExpectation {
});
final String method;
final String id;
/// When true, the vm service is automatically closed.
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