diff --git a/dev/devicelab/bin/tasks/commands_test.dart b/dev/devicelab/bin/tasks/commands_test.dart index 01641289dbe..8cd99159c22 100644 --- a/dev/devicelab/bin/tasks/commands_test.dart +++ b/dev/devicelab/bin/tasks/commands_test.dart @@ -7,11 +7,14 @@ import 'dart:convert'; import 'dart:io'; 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/framework.dart'; import 'package:flutter_devicelab/framework/utils.dart'; +const int kObservatoryPort = 8888; + void main() { task(() async { final Device device = await devices.workingDevice; @@ -23,13 +26,15 @@ void main() { print('run: starting...'); final Process run = await startProcess( path.join(flutterDirectory.path, 'bin', 'flutter'), - ['run', '--verbose', '--observatory-port=8888', '-d', device.deviceId, 'lib/commands.dart'], + ['run', '--verbose', '--observatory-port=$kObservatoryPort', '-d', device.deviceId, 'lib/commands.dart'], ); + final StreamController stdout = new StreamController.broadcast(); run.stdout .transform(UTF8.decoder) .transform(const LineSplitter()) .listen((String 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"\.'))) { print('run: ready!'); ready.complete(); @@ -46,6 +51,9 @@ void main() { await Future.any(>[ ready.future, run.exitCode ]); if (!ok) throw 'Failed to run test app.'; + + final VMServiceClient client = new VMServiceClient.connect('ws://localhost:$kObservatoryPort/ws'); + await drive('none'); print('test: pressing "p" to enable debugPaintSize...'); run.stdin.write('p'); @@ -59,10 +67,24 @@ void main() { print('test: pressing "P" again...'); run.stdin.write('P'); await drive('none'); + final Future 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 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'); final int result = await run.exitCode; if (result != 0) 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); }); @@ -72,7 +94,7 @@ Future drive(String name) async { print('drive: running commands_$name check...'); final Process drive = await startProcess( path.join(flutterDirectory.path, 'bin', 'flutter'), - ['drive', '--use-existing-app', 'http://127.0.0.1:8888/', '--keep-app-running', '--driver', 'test_driver/commands_${name}_test.dart'], + ['drive', '--use-existing-app', 'http://127.0.0.1:$kObservatoryPort/', '--keep-app-running', '--driver', 'test_driver/commands_${name}_test.dart'], ); drive.stdout .transform(UTF8.decoder) @@ -90,4 +112,4 @@ Future drive(String name) async { if (result != 0) throw 'Failed to drive test app (exit code $result).'; print('drive: finished commands_$name check successfully.'); -} \ No newline at end of file +} diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index f03822d9f95..b509a8ee9f4 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -33,16 +33,11 @@ class FlutterDevice { DevFS devFS; ApplicationPackage package; - String _viewFilter; StreamSubscription _loggingSubscription; FlutterDevice(this.device); - String get viewFilter => _viewFilter; - set viewFilter(String filter) { - _viewFilter = filter; - _viewsCache = null; - } + String viewFilter; /// If the [reloadSources] parameter is not null the 'reloadSources' service /// will be registered. @@ -63,33 +58,22 @@ class FlutterDevice { } Future refreshViews() async { - if ((vmServices == null) || vmServices.isEmpty) + if (vmServices == null || vmServices.isEmpty) return; for (VMService service in vmServices) await service.vm.refreshViews(); - _viewsCache = null; } - List _viewsCache; List get views { - if (_viewsCache == null) { - if ((vmServices == null) || vmServices.isEmpty) - return null; - final List result = []; - if (_viewFilter == null) { - for (VMService service in vmServices) { - if (!service.isClosed) - result.addAll(service.vm.views.toList()); - } - } else { - for (VMService service in vmServices) { - if (!service.isClosed) - result.addAll(service.vm.allViewsWithName(_viewFilter)); - } - } - _viewsCache = result; - } - return _viewsCache; + if (vmServices == null) + return []; + + return vmServices + .where((VMService service) => !service.isClosed) + .expand((VMService service) => viewFilter != null + ? service.vm.allViewsWithName(viewFilter) + : service.vm.views) + .toList(); } Future getVMs() async { @@ -115,9 +99,9 @@ class FlutterDevice { } Future setupDevFS(String fsName, - Directory rootDirectory, { - String packagesFilePath - }) { + Directory rootDirectory, { + String packagesFilePath + }) { // One devFS per device. Shared by all running instances. devFS = new DevFS( vmServices[0], diff --git a/packages/flutter_tools/lib/src/vmservice.dart b/packages/flutter_tools/lib/src/vmservice.dart index 9b255ced901..07659c2d2ba 100644 --- a/packages/flutter_tools/lib/src/vmservice.dart +++ b/packages/flutter_tools/lib/src/vmservice.dart @@ -207,6 +207,10 @@ class VMService { final String streamId = data['streamId']; final Map eventData = data['event']; final Map eventIsolate = eventData['isolate']; + + // Log event information. + printTrace(data.toString()); + ServiceEvent event; if (eventIsolate != null) { // getFromMap creates the Isolate if necessary. @@ -336,8 +340,7 @@ abstract class ServiceObject { // If we don't have a model object for this service object type, as a // fallback return a ServiceMap object. serviceObject ??= new ServiceMap._empty(owner); - // We have now constructed an emtpy service object, call update to - // populate it. + // We have now constructed an empty service object, call update to populate it. serviceObject.update(map); return serviceObject; } @@ -717,6 +720,8 @@ class VM extends ServiceObjectOwner { Duration timeout, bool timeoutFatal: true, }) async { + printTrace('$method: $params'); + assert(params != null); timeout ??= _vmService._requestTimeout; try { @@ -1029,7 +1034,6 @@ class Isolate extends ServiceObjectOwner { return invokeRpcRaw('resume'); } - // Flutter extension methods. // Invoke a flutter extension method, if the flutter extension is not @@ -1140,6 +1144,9 @@ class Isolate extends ServiceObjectOwner { return result['value']; return 'unknown'; } + + @override + String toString() => 'Isolate $id'; } class ServiceMap extends ServiceObject implements Map {