mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

* Update project.pbxproj files to say Flutter rather than Chromium Also, the templates now have an empty organization so that we don't cause people to give their apps a Flutter copyright. * Update the copyright notice checker to require a standard notice on all files * Update copyrights on Dart files. (This was a mechanical commit.) * Fix weird license headers on Dart files that deviate from our conventions; relicense Shrine. Some were already marked "The Flutter Authors", not clear why. Their dates have been normalized. Some were missing the blank line after the license. Some were randomly different in trivial ways for no apparent reason (e.g. missing the trailing period). * Clean up the copyrights in non-Dart files. (Manual edits.) Also, make sure templates don't have copyrights. * Fix some more ORGANIZATIONNAMEs
167 lines
5.9 KiB
Dart
167 lines
5.9 KiB
Dart
// Copyright 2014 The Flutter Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
import 'dart:async';
|
|
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';
|
|
|
|
void main() {
|
|
Map<String, dynamic> parseFlutterResponse(String line) {
|
|
if (line.startsWith('[') && line.endsWith(']')) {
|
|
try {
|
|
return json.decode(line)[0];
|
|
} catch (e) {
|
|
// Not valid JSON, so likely some other output that was surrounded by [brackets]
|
|
return null;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
Stream<String> transformToLines(Stream<List<int>> byteStream) {
|
|
return byteStream.transform<String>(utf8.decoder).transform<String>(const LineSplitter());
|
|
}
|
|
|
|
task(() async {
|
|
Uri vmServiceUri;
|
|
String appId;
|
|
|
|
final Device device = await devices.workingDevice;
|
|
await device.unlock();
|
|
final Directory appDir =
|
|
dir(path.join(flutterDirectory.path, 'dev/integration_tests/ui'));
|
|
await inDirectory(appDir, () async {
|
|
final Completer<void> ready = Completer<void>();
|
|
bool ok;
|
|
print('run: starting...');
|
|
final Process run = await startProcess(
|
|
path.join(flutterDirectory.path, 'bin', 'flutter'),
|
|
<String>[
|
|
'run',
|
|
'--machine',
|
|
'--verbose',
|
|
'-d',
|
|
device.deviceId,
|
|
'lib/commands.dart',
|
|
],
|
|
);
|
|
final StreamController<String> stdout = StreamController<String>.broadcast();
|
|
transformToLines(run.stdout).listen((String line) {
|
|
print('run:stdout: $line');
|
|
stdout.add(line);
|
|
final dynamic json = parseFlutterResponse(line);
|
|
if (json != null) {
|
|
if (json['event'] == 'app.debugPort') {
|
|
vmServiceUri = Uri.parse(json['params']['wsUri']);
|
|
print('service protocol connection available at $vmServiceUri');
|
|
} else if (json['event'] == 'app.started') {
|
|
appId = json['params']['appId'];
|
|
print('application identifier is $appId');
|
|
}
|
|
}
|
|
if (vmServiceUri != null && appId != null && !ready.isCompleted) {
|
|
print('run: ready!');
|
|
ready.complete();
|
|
ok ??= true;
|
|
}
|
|
});
|
|
transformToLines(run.stderr).listen((String line) {
|
|
stderr.writeln('run:stderr: $line');
|
|
ok = false;
|
|
});
|
|
run.exitCode.then<void>((int exitCode) {
|
|
ok = false;
|
|
});
|
|
await Future.any<dynamic>(<Future<dynamic>>[ready.future, run.exitCode]);
|
|
if (!ok)
|
|
throw 'Failed to run test app.';
|
|
|
|
final VMServiceClient client = VMServiceClient.connect(vmServiceUri);
|
|
|
|
int id = 1;
|
|
Future<Map<String, dynamic>> sendRequest(String method, dynamic params) async {
|
|
final int requestId = id++;
|
|
final Completer<Map<String, dynamic>> response = Completer<Map<String, dynamic>>();
|
|
final StreamSubscription<String> responseSubscription = stdout.stream.listen((String line) {
|
|
final Map<String, dynamic> json = parseFlutterResponse(line);
|
|
if (json != null && json['id'] == requestId)
|
|
response.complete(json);
|
|
});
|
|
final Map<String, dynamic> req = <String, dynamic>{
|
|
'id': requestId,
|
|
'method': method,
|
|
'params': params,
|
|
};
|
|
final String jsonEncoded = json.encode(<Map<String, dynamic>>[req]);
|
|
print('run:stdin: $jsonEncoded');
|
|
run.stdin.writeln(jsonEncoded);
|
|
final Map<String, dynamic> result = await response.future;
|
|
responseSubscription.cancel();
|
|
return result;
|
|
}
|
|
|
|
print('test: sending two hot reloads...');
|
|
final Future<dynamic> hotReload1 = sendRequest(
|
|
'app.restart',
|
|
<String, dynamic>{'appId': appId, 'fullRestart': false},
|
|
);
|
|
final Future<dynamic> hotReload2 = sendRequest(
|
|
'app.restart',
|
|
<String, dynamic>{'appId': appId, 'fullRestart': false},
|
|
);
|
|
final Future<List<dynamic>> reloadRequests = Future.wait<dynamic>(<Future<dynamic>>[
|
|
hotReload1,
|
|
hotReload2,
|
|
]);
|
|
final dynamic results = await Future.any<dynamic>(<Future<dynamic>>[
|
|
run.exitCode,
|
|
reloadRequests,
|
|
]);
|
|
|
|
if (!ok)
|
|
throw 'App failed or crashed during hot reloads.';
|
|
|
|
final List<dynamic> responses = results;
|
|
final List<dynamic> errorResponses = responses.where(
|
|
(dynamic r) => r['error'] != null
|
|
).toList();
|
|
final List<dynamic> successResponses = responses.where(
|
|
(dynamic r) => r['error'] == null &&
|
|
r['result'] != null &&
|
|
r['result']['code'] == 0
|
|
).toList();
|
|
|
|
if (errorResponses.length != 1)
|
|
throw 'Did not receive the expected (exactly one) hot reload error response.';
|
|
final String errorMessage = errorResponses.first['error'];
|
|
if (!errorMessage.contains('in progress'))
|
|
throw 'Error response was not that hot reload was in progress.';
|
|
if (successResponses.length != 1)
|
|
throw 'Did not receive the expected (exactly one) successful hot reload response.';
|
|
|
|
final dynamic hotReload3 = await sendRequest(
|
|
'app.restart',
|
|
<String, dynamic>{'appId': appId, 'fullRestart': false},
|
|
);
|
|
if (hotReload3['error'] != null)
|
|
throw 'Received an error response from a hot reload after all other hot reloads had completed.';
|
|
|
|
sendRequest('app.stop', <String, dynamic>{'appId': appId});
|
|
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;
|
|
});
|
|
return TaskResult.success(null);
|
|
});
|
|
}
|