Commit 990dae85 authored by Devon Carew's avatar Devon Carew Committed by GitHub

remove the flutter view cache; fix the ability to quit the app after a full restart (#11420)

* remove the flutter view cache; fix the ability to quit the app after a full restart

* improve test

* update test
parent 2225e21f
...@@ -7,11 +7,14 @@ import 'dart:convert'; ...@@ -7,11 +7,14 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:path/path.dart' as path; import 'package:path/path.dart' as path;
import 'package:vm_service_client/vm_service_client.dart';
import 'package:flutter_devicelab/framework/adb.dart'; import 'package:flutter_devicelab/framework/adb.dart';
import 'package:flutter_devicelab/framework/framework.dart'; import 'package:flutter_devicelab/framework/framework.dart';
import 'package:flutter_devicelab/framework/utils.dart'; import 'package:flutter_devicelab/framework/utils.dart';
const int kObservatoryPort = 8888;
void main() { void main() {
task(() async { task(() async {
final Device device = await devices.workingDevice; final Device device = await devices.workingDevice;
...@@ -23,13 +26,15 @@ void main() { ...@@ -23,13 +26,15 @@ void main() {
print('run: starting...'); print('run: starting...');
final Process run = await startProcess( final Process run = await startProcess(
path.join(flutterDirectory.path, 'bin', 'flutter'), path.join(flutterDirectory.path, 'bin', 'flutter'),
<String>['run', '--verbose', '--observatory-port=8888', '-d', device.deviceId, 'lib/commands.dart'], <String>['run', '--verbose', '--observatory-port=$kObservatoryPort', '-d', device.deviceId, 'lib/commands.dart'],
); );
final StreamController<String> stdout = new StreamController<String>.broadcast();
run.stdout run.stdout
.transform(UTF8.decoder) .transform(UTF8.decoder)
.transform(const LineSplitter()) .transform(const LineSplitter())
.listen((String line) { .listen((String line) {
print('run:stdout: $line'); print('run:stdout: $line');
stdout.add(line);
if (line.contains(new RegExp(r'^\[\s+\] For a more detailed help message, press "h"\. To quit, press "q"\.'))) { if (line.contains(new RegExp(r'^\[\s+\] For a more detailed help message, press "h"\. To quit, press "q"\.'))) {
print('run: ready!'); print('run: ready!');
ready.complete(); ready.complete();
...@@ -46,6 +51,9 @@ void main() { ...@@ -46,6 +51,9 @@ void main() {
await Future.any<dynamic>(<Future<dynamic>>[ ready.future, run.exitCode ]); await Future.any<dynamic>(<Future<dynamic>>[ ready.future, run.exitCode ]);
if (!ok) if (!ok)
throw 'Failed to run test app.'; throw 'Failed to run test app.';
final VMServiceClient client = new VMServiceClient.connect('ws://localhost:$kObservatoryPort/ws');
await drive('none'); await drive('none');
print('test: pressing "p" to enable debugPaintSize...'); print('test: pressing "p" to enable debugPaintSize...');
run.stdin.write('p'); run.stdin.write('p');
...@@ -59,10 +67,24 @@ void main() { ...@@ -59,10 +67,24 @@ void main() {
print('test: pressing "P" again...'); print('test: pressing "P" again...');
run.stdin.write('P'); run.stdin.write('P');
await drive('none'); await drive('none');
final Future<String> reloadStartingText =
stdout.stream.firstWhere((String line) => line.endsWith('hot reload...'));
print('test: pressing "r" to perform a hot reload...');
run.stdin.write('r');
await reloadStartingText;
await drive('none');
final Future<String> restartStartingText =
stdout.stream.firstWhere((String line) => line.endsWith('full restart...'));
print('test: pressing "R" to perform a full reload...');
run.stdin.write('R');
await restartStartingText;
await drive('none');
run.stdin.write('q'); run.stdin.write('q');
final int result = await run.exitCode; final int result = await run.exitCode;
if (result != 0) if (result != 0)
throw 'Received unexpected exit code $result from run process.'; throw 'Received unexpected exit code $result from run process.';
print('test: validating that the app has in fact closed...');
await client.done.timeout(new Duration(seconds: 5));
}); });
return new TaskResult.success(null); return new TaskResult.success(null);
}); });
...@@ -72,7 +94,7 @@ Future<Null> drive(String name) async { ...@@ -72,7 +94,7 @@ Future<Null> drive(String name) async {
print('drive: running commands_$name check...'); print('drive: running commands_$name check...');
final Process drive = await startProcess( final Process drive = await startProcess(
path.join(flutterDirectory.path, 'bin', 'flutter'), path.join(flutterDirectory.path, 'bin', 'flutter'),
<String>['drive', '--use-existing-app', 'http://127.0.0.1:8888/', '--keep-app-running', '--driver', 'test_driver/commands_${name}_test.dart'], <String>['drive', '--use-existing-app', 'http://127.0.0.1:$kObservatoryPort/', '--keep-app-running', '--driver', 'test_driver/commands_${name}_test.dart'],
); );
drive.stdout drive.stdout
.transform(UTF8.decoder) .transform(UTF8.decoder)
......
...@@ -33,16 +33,11 @@ class FlutterDevice { ...@@ -33,16 +33,11 @@ class FlutterDevice {
DevFS devFS; DevFS devFS;
ApplicationPackage package; ApplicationPackage package;
String _viewFilter;
StreamSubscription<String> _loggingSubscription; StreamSubscription<String> _loggingSubscription;
FlutterDevice(this.device); FlutterDevice(this.device);
String get viewFilter => _viewFilter; String viewFilter;
set viewFilter(String filter) {
_viewFilter = filter;
_viewsCache = null;
}
/// If the [reloadSources] parameter is not null the 'reloadSources' service /// If the [reloadSources] parameter is not null the 'reloadSources' service
/// will be registered. /// will be registered.
...@@ -63,33 +58,22 @@ class FlutterDevice { ...@@ -63,33 +58,22 @@ class FlutterDevice {
} }
Future<Null> refreshViews() async { Future<Null> refreshViews() async {
if ((vmServices == null) || vmServices.isEmpty) if (vmServices == null || vmServices.isEmpty)
return; return;
for (VMService service in vmServices) for (VMService service in vmServices)
await service.vm.refreshViews(); await service.vm.refreshViews();
_viewsCache = null;
} }
List<FlutterView> _viewsCache;
List<FlutterView> get views { List<FlutterView> get views {
if (_viewsCache == null) { if (vmServices == null)
if ((vmServices == null) || vmServices.isEmpty) return <FlutterView>[];
return null;
final List<FlutterView> result = <FlutterView>[]; return vmServices
if (_viewFilter == null) { .where((VMService service) => !service.isClosed)
for (VMService service in vmServices) { .expand((VMService service) => viewFilter != null
if (!service.isClosed) ? service.vm.allViewsWithName(viewFilter)
result.addAll(service.vm.views.toList()); : service.vm.views)
} .toList();
} else {
for (VMService service in vmServices) {
if (!service.isClosed)
result.addAll(service.vm.allViewsWithName(_viewFilter));
}
}
_viewsCache = result;
}
return _viewsCache;
} }
Future<Null> getVMs() async { Future<Null> getVMs() async {
......
...@@ -207,6 +207,10 @@ class VMService { ...@@ -207,6 +207,10 @@ class VMService {
final String streamId = data['streamId']; final String streamId = data['streamId'];
final Map<String, dynamic> eventData = data['event']; final Map<String, dynamic> eventData = data['event'];
final Map<String, dynamic> eventIsolate = eventData['isolate']; final Map<String, dynamic> eventIsolate = eventData['isolate'];
// Log event information.
printTrace(data.toString());
ServiceEvent event; ServiceEvent event;
if (eventIsolate != null) { if (eventIsolate != null) {
// getFromMap creates the Isolate if necessary. // getFromMap creates the Isolate if necessary.
...@@ -336,8 +340,7 @@ abstract class ServiceObject { ...@@ -336,8 +340,7 @@ abstract class ServiceObject {
// If we don't have a model object for this service object type, as a // If we don't have a model object for this service object type, as a
// fallback return a ServiceMap object. // fallback return a ServiceMap object.
serviceObject ??= new ServiceMap._empty(owner); serviceObject ??= new ServiceMap._empty(owner);
// We have now constructed an emtpy service object, call update to // We have now constructed an empty service object, call update to populate it.
// populate it.
serviceObject.update(map); serviceObject.update(map);
return serviceObject; return serviceObject;
} }
...@@ -717,6 +720,8 @@ class VM extends ServiceObjectOwner { ...@@ -717,6 +720,8 @@ class VM extends ServiceObjectOwner {
Duration timeout, Duration timeout,
bool timeoutFatal: true, bool timeoutFatal: true,
}) async { }) async {
printTrace('$method: $params');
assert(params != null); assert(params != null);
timeout ??= _vmService._requestTimeout; timeout ??= _vmService._requestTimeout;
try { try {
...@@ -1029,7 +1034,6 @@ class Isolate extends ServiceObjectOwner { ...@@ -1029,7 +1034,6 @@ class Isolate extends ServiceObjectOwner {
return invokeRpcRaw('resume'); return invokeRpcRaw('resume');
} }
// Flutter extension methods. // Flutter extension methods.
// Invoke a flutter extension method, if the flutter extension is not // Invoke a flutter extension method, if the flutter extension is not
...@@ -1140,6 +1144,9 @@ class Isolate extends ServiceObjectOwner { ...@@ -1140,6 +1144,9 @@ class Isolate extends ServiceObjectOwner {
return result['value']; return result['value'];
return 'unknown'; return 'unknown';
} }
@override
String toString() => 'Isolate $id';
} }
class ServiceMap extends ServiceObject implements Map<String, dynamic> { class ServiceMap extends ServiceObject implements Map<String, dynamic> {
......
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