Revert "Migrate core devicelab framework to null safety. (#85993)" (#86269)
This reverts commit 2175e64e4fdb387c5f01242c9a82779d3423e531.
diff --git a/dev/devicelab/lib/command/test.dart b/dev/devicelab/lib/command/test.dart
index 9e35fdd..feab3ca 100644
--- a/dev/devicelab/lib/command/test.dart
+++ b/dev/devicelab/lib/command/test.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'package:args/command_runner.dart';
import 'package:flutter_devicelab/framework/runner.dart';
@@ -62,19 +64,19 @@
@override
Future<void> run() async {
- final List<String> taskArgsRaw = argResults!['task-args'] as List<String>;
+ final List<String> taskArgsRaw = argResults['task-args'] as List<String>;
// Prepend '--' to convert args to options when passed to task
final List<String> taskArgs = taskArgsRaw.map((String taskArg) => '--$taskArg').toList();
print(taskArgs);
await runTasks(
- <String>[argResults!['task'] as String],
- deviceId: argResults!['device-id'] as String?,
- gitBranch: argResults!['git-branch'] as String?,
- localEngine: argResults!['local-engine'] as String?,
- localEngineSrcPath: argResults!['local-engine-src-path'] as String?,
- luciBuilder: argResults!['luci-builder'] as String?,
- resultsPath: argResults!['results-file'] as String?,
- silent: (argResults!['silent'] as bool?) ?? false,
+ <String>[argResults['task'] as String],
+ deviceId: argResults['device-id'] as String,
+ gitBranch: argResults['git-branch'] as String,
+ localEngine: argResults['local-engine'] as String,
+ localEngineSrcPath: argResults['local-engine-src-path'] as String,
+ luciBuilder: argResults['luci-builder'] as String,
+ resultsPath: argResults['results-file'] as String,
+ silent: argResults['silent'] as bool,
taskArgs: taskArgs,
);
}
diff --git a/dev/devicelab/lib/command/upload_metrics.dart b/dev/devicelab/lib/command/upload_metrics.dart
index 89742cb..f44da32 100644
--- a/dev/devicelab/lib/command/upload_metrics.dart
+++ b/dev/devicelab/lib/command/upload_metrics.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'package:args/command_runner.dart';
import '../framework/cocoon.dart';
@@ -23,8 +25,8 @@
@override
Future<void> run() async {
- final String resultsPath = argResults!['results-file'] as String;
- final String? serviceAccountTokenFile = argResults!['service-account-token-file'] as String?;
+ final String resultsPath = argResults['results-file'] as String;
+ final String serviceAccountTokenFile = argResults['service-account-token-file'] as String;
final Cocoon cocoon = Cocoon(serviceAccountTokenPath: serviceAccountTokenFile);
return cocoon.sendResultsPath(resultsPath);
diff --git a/dev/devicelab/lib/framework/ab.dart b/dev/devicelab/lib/framework/ab.dart
index 4f214f9..af3c737 100644
--- a/dev/devicelab/lib/framework/ab.dart
+++ b/dev/devicelab/lib/framework/ab.dart
@@ -2,7 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:math' as math;
+import 'package:meta/meta.dart';
import 'task_result.dart';
@@ -40,8 +43,8 @@
final String localEngine;
final String taskName;
final DateTime runStart;
- DateTime? _runEnd;
- DateTime? get runEnd => _runEnd;
+ DateTime _runEnd;
+ DateTime get runEnd => _runEnd;
final Map<String, List<double>> _aResults;
final Map<String, List<double>> _bResults;
@@ -88,15 +91,15 @@
kLocalEngineKeyName: localEngine,
kTaskNameKeyName: taskName,
kRunStartKeyName: runStart.toIso8601String(),
- kRunEndKeyName: runEnd!.toIso8601String(),
+ kRunEndKeyName: runEnd.toIso8601String(),
kAResultsKeyName: _aResults,
kBResultsKeyName: _bResults,
};
- static void updateColumnLengths(List<int> lengths, List<String?> results) {
+ static void updateColumnLengths(List<int> lengths, List<String> results) {
for (int column = 0; column < lengths.length; column++) {
if (results[column] != null) {
- lengths[column] = math.max(lengths[column], results[column]?.length ?? 0);
+ lengths[column] = math.max(lengths[column], results[column].length);
}
}
}
@@ -104,10 +107,10 @@
static void formatResult(StringBuffer buffer,
List<int> lengths,
List<FieldJustification> aligns,
- List<String?> values) {
+ List<String> values) {
for (int column = 0; column < lengths.length; column++) {
final int len = lengths[column];
- String? value = values[column];
+ String value = values[column];
if (value == null) {
value = ''.padRight(len);
} else {
@@ -139,9 +142,9 @@
final Map<String, _ScoreSummary> summariesA = _summarize(_aResults);
final Map<String, _ScoreSummary> summariesB = _summarize(_bResults);
- final List<List<String?>> tableRows = <List<String?>>[
+ final List<List<String>> tableRows = <List<String>>[
for (final String scoreKey in <String>{...summariesA.keys, ...summariesB.keys})
- <String?>[
+ <String>[
scoreKey,
summariesA[scoreKey]?.averageString, summariesA[scoreKey]?.noiseString,
summariesB[scoreKey]?.averageString, summariesB[scoreKey]?.noiseString,
@@ -164,7 +167,7 @@
final List<int> lengths = List<int>.filled(6, 0);
updateColumnLengths(lengths, titles);
- for (final List<String?> row in tableRows) {
+ for (final List<String> row in tableRows) {
updateColumnLengths(lengths, row);
}
@@ -174,7 +177,7 @@
FieldJustification.CENTER,
...alignments.skip(1),
], titles);
- for (final List<String?> row in tableRows) {
+ for (final List<String> row in tableRows) {
formatResult(buffer, lengths, alignments, row);
}
@@ -189,7 +192,7 @@
buffer.writeln('$scoreKey:');
buffer.write(' A:\t');
if (_aResults.containsKey(scoreKey)) {
- for (final double score in _aResults[scoreKey]!) {
+ for (final double score in _aResults[scoreKey]) {
buffer.write('${score.toStringAsFixed(2)}\t');
}
} else {
@@ -199,7 +202,7 @@
buffer.write(' B:\t');
if (_bResults.containsKey(scoreKey)) {
- for (final double score in _bResults[scoreKey]!) {
+ for (final double score in _bResults[scoreKey]) {
buffer.write('${score.toStringAsFixed(2)}\t');
}
} else {
@@ -229,8 +232,8 @@
);
for (final String scoreKey in _allScoreKeys) {
- final _ScoreSummary? summaryA = summariesA[scoreKey];
- final _ScoreSummary? summaryB = summariesB[scoreKey];
+ final _ScoreSummary summaryA = summariesA[scoreKey];
+ final _ScoreSummary summaryB = summariesB[scoreKey];
buffer.write('$scoreKey\t');
if (summaryA != null) {
@@ -258,8 +261,8 @@
class _ScoreSummary {
_ScoreSummary({
- required this.average,
- required this.noise,
+ @required this.average,
+ @required this.noise,
});
/// Average (arithmetic mean) of a series of values collected by a benchmark.
@@ -272,14 +275,14 @@
String get averageString => average.toStringAsFixed(2);
String get noiseString => '(${_ratioToPercent(noise)})';
- String improvementOver(_ScoreSummary? other) {
+ String improvementOver(_ScoreSummary other) {
return other == null ? '' : '${(average / other.average).toStringAsFixed(2)}x';
}
}
void _addResult(TaskResult result, Map<String, List<double>> results) {
- for (final String scoreKey in result.benchmarkScoreKeys ?? <String>[]) {
- final double score = (result.data![scoreKey] as num).toDouble();
+ for (final String scoreKey in result.benchmarkScoreKeys) {
+ final double score = (result.data[scoreKey] as num).toDouble();
results.putIfAbsent(scoreKey, () => <double>[]).add(score);
}
}
diff --git a/dev/devicelab/lib/framework/apk_utils.dart b/dev/devicelab/lib/framework/apk_utils.dart
index 2baec6c..2def05b 100644
--- a/dev/devicelab/lib/framework/apk_utils.dart
+++ b/dev/devicelab/lib/framework/apk_utils.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:io';
import 'package:path/path.dart' as path;
@@ -104,7 +106,7 @@
/// The Android home directory.
String get _androidHome {
- final String? androidHome = Platform.environment['ANDROID_HOME'] ??
+ final String androidHome = Platform.environment['ANDROID_HOME'] ??
Platform.environment['ANDROID_SDK_ROOT'];
if (androidHome == null || androidHome.isEmpty) {
throw Exception('Environment variable `ANDROID_SDK_ROOT` is not set.');
@@ -116,9 +118,9 @@
Future<String> _evalApkAnalyzer(
List<String> args, {
bool printStdout = false,
- String? workingDirectory,
+ String workingDirectory,
}) async {
- final String? javaHome = await findJavaHome();
+ final String javaHome = await findJavaHome();
if (javaHome == null || javaHome.isEmpty) {
throw Exception('No JAVA_HOME set.');
}
@@ -257,7 +259,7 @@
String get androidPath => path.join(rootPath, 'android');
String get iosPath => path.join(rootPath, 'ios');
- Future<void> addCustomBuildType(String name, {required String initWith}) async {
+ Future<void> addCustomBuildType(String name, {String initWith}) async {
final File buildScript = File(
path.join(androidPath, 'app', 'build.gradle'),
);
@@ -274,7 +276,7 @@
''');
}
- Future<void> addGlobalBuildType(String name, {required String initWith}) async {
+ Future<void> addGlobalBuildType(String name, {String initWith}) async {
final File buildScript = File(
path.join(androidPath, 'build.gradle'),
);
@@ -358,11 +360,11 @@
pubspec.writeAsStringSync(newContents);
}
- Future<void> runGradleTask(String task, {List<String>? options}) async {
+ Future<void> runGradleTask(String task, {List<String> options}) async {
return _runGradleTask(workingDirectory: androidPath, task: task, options: options);
}
- Future<ProcessResult> resultOfGradleTask(String task, {List<String>? options}) {
+ Future<ProcessResult> resultOfGradleTask(String task, {List<String> options}) {
return _resultOfGradleTask(workingDirectory: androidPath, task: task, options: options);
}
@@ -414,11 +416,7 @@
String get rootPath => path.join(parent.path, name);
}
-Future<void> _runGradleTask({
- required String workingDirectory,
- required String task,
- List<String>? options,
-}) async {
+Future<void> _runGradleTask({String workingDirectory, String task, List<String> options}) async {
final ProcessResult result = await _resultOfGradleTask(
workingDirectory: workingDirectory,
task: task,
@@ -433,13 +431,10 @@
throw 'Gradle exited with error';
}
-Future<ProcessResult> _resultOfGradleTask({
- required String workingDirectory,
- required String task,
- List<String>? options,
-}) async {
+Future<ProcessResult> _resultOfGradleTask({String workingDirectory, String task,
+ List<String> options}) async {
section('Find Java');
- final String? javaHome = await findJavaHome();
+ final String javaHome = await findJavaHome();
if (javaHome == null)
throw TaskResult.failure('Could not find Java');
@@ -470,7 +465,7 @@
}
/// Returns [null] if target matches [expectedTarget], otherwise returns an error message.
-String? validateSnapshotDependency(FlutterProject project, String expectedTarget) {
+String validateSnapshotDependency(FlutterProject project, String expectedTarget) {
final File snapshotBlob = File(
path.join(project.rootPath, 'build', 'app', 'intermediates',
'flutter', 'debug', 'flutter_build.d'));
diff --git a/dev/devicelab/lib/framework/browser.dart b/dev/devicelab/lib/framework/browser.dart
index 3b65e83..9d2f544 100644
--- a/dev/devicelab/lib/framework/browser.dart
+++ b/dev/devicelab/lib/framework/browser.dart
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert' show json, utf8, LineSplitter, JsonEncoder;
import 'dart:io' as io;
import 'dart:math' as math;
import 'package:flutter_devicelab/common.dart';
+import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:webkit_inspection_protocol/webkit_inspection_protocol.dart';
@@ -29,10 +32,10 @@
});
/// If not null passed as `--user-data-dir`.
- final String? userDataDirectory;
+ final String userDataDirectory;
/// If not null launches a Chrome tab at this URL.
- final String? url;
+ final String url;
/// The width of the Chrome window.
///
@@ -46,14 +49,14 @@
/// Launches code in "headless" mode, which allows running Chrome in
/// environments without a display, such as LUCI and Cirrus.
- final bool? headless;
+ final bool headless;
/// The port Chrome will use for its debugging protocol.
///
/// If null, Chrome is launched without debugging. When running in headless
/// mode without a debug port, Chrome quits immediately. For most tests it is
/// typical to set [headless] to true and set a non-null debug port.
- final int? debugPort;
+ final int debugPort;
}
/// A function called when the Chrome process encounters an error.
@@ -76,7 +79,7 @@
/// The [onError] callback is called with an error message when the Chrome
/// process encounters an error. In particular, [onError] is called when the
/// Chrome process exits prematurely, i.e. before [stop] is called.
- static Future<Chrome> launch(ChromeOptions options, { String? workingDirectory, required ChromeErrorCallback onError }) async {
+ static Future<Chrome> launch(ChromeOptions options, { String workingDirectory, @required ChromeErrorCallback onError }) async {
if (!io.Platform.isWindows) {
final io.ProcessResult versionResult = io.Process.runSync(_findSystemChromeExecutable(), const <String>['--version']);
print('Launching ${versionResult.stdout}');
@@ -89,10 +92,10 @@
if (options.userDataDirectory != null)
'--user-data-dir=${options.userDataDirectory}',
if (options.url != null)
- options.url!,
+ options.url,
if (io.Platform.environment['CHROME_NO_SANDBOX'] == 'true')
'--no-sandbox',
- if (options.headless == true)
+ if (options.headless)
'--headless',
if (withDebugging)
'--remote-debugging-port=${options.debugPort}',
@@ -113,9 +116,9 @@
workingDirectory: workingDirectory,
);
- WipConnection? debugConnection;
+ WipConnection debugConnection;
if (withDebugging) {
- debugConnection = await _connectToChromeDebugPort(chromeProcess, options.debugPort!);
+ debugConnection = await _connectToChromeDebugPort(chromeProcess, options.debugPort);
}
return Chrome._(chromeProcess, onError, debugConnection);
@@ -123,12 +126,12 @@
final io.Process _chromeProcess;
final ChromeErrorCallback _onError;
- final WipConnection? _debugConnection;
+ final WipConnection _debugConnection;
bool _isStopped = false;
- Completer<void> ?_tracingCompleter;
- StreamSubscription<WipEvent>? _tracingSubscription;
- List<Map<String, dynamic>>? _tracingData;
+ Completer<void> _tracingCompleter;
+ StreamSubscription<WipEvent> _tracingSubscription;
+ List<Map<String, dynamic>> _tracingData;
/// Starts recording a performance trace.
///
@@ -148,24 +151,24 @@
// Subscribe to tracing events prior to calling "Tracing.start". Otherwise,
// we'll miss tracing data.
- _tracingSubscription = _debugConnection?.onNotification.listen((WipEvent event) {
+ _tracingSubscription = _debugConnection.onNotification.listen((WipEvent event) {
// We receive data as a sequence of "Tracing.dataCollected" followed by
// "Tracing.tracingComplete" at the end. Until "Tracing.tracingComplete"
// is received, the data may be incomplete.
if (event.method == 'Tracing.tracingComplete') {
- _tracingCompleter!.complete();
- _tracingSubscription!.cancel();
+ _tracingCompleter.complete();
+ _tracingSubscription.cancel();
_tracingSubscription = null;
} else if (event.method == 'Tracing.dataCollected') {
- final dynamic value = event.params?['value'];
+ final dynamic value = event.params['value'];
if (value is! List) {
throw FormatException('"Tracing.dataCollected" returned malformed data. '
'Expected a List but got: ${value.runtimeType}');
}
- _tracingData?.addAll((event.params?['value'] as List<dynamic>).cast<Map<String, dynamic>>());
+ _tracingData.addAll((event.params['value'] as List<dynamic>).cast<Map<String, dynamic>>());
}
});
- await _debugConnection?.sendCommand('Tracing.start', <String, dynamic>{
+ await _debugConnection.sendCommand('Tracing.start', <String, dynamic>{
// The choice of categories is as follows:
//
// blink:
@@ -187,23 +190,22 @@
/// Stops a performance tracing session started by [beginRecordingPerformance].
///
/// Returns all the collected tracing data unfiltered.
- Future<List<Map<String, dynamic>>?> endRecordingPerformance() async {
- await _debugConnection!.sendCommand('Tracing.end');
- await _tracingCompleter!.future;
- final List<Map<String, dynamic>>? data = _tracingData;
+ Future<List<Map<String, dynamic>>> endRecordingPerformance() async {
+ await _debugConnection.sendCommand('Tracing.end');
+ await _tracingCompleter.future;
+ final List<Map<String, dynamic>> data = _tracingData;
_tracingCompleter = null;
_tracingData = null;
return data;
}
Future<void> reloadPage({bool ignoreCache = false}) async {
- await _debugConnection?.page.reload(ignoreCache: ignoreCache);
+ await _debugConnection.page.reload(ignoreCache: ignoreCache);
}
/// Stops the Chrome process.
void stop() {
_isStopped = true;
- _tracingSubscription?.cancel();
_chromeProcess.kill();
}
}
@@ -212,7 +214,7 @@
// On some environments, such as the Dart HHH tester, Chrome resides in a
// non-standard location and is provided via the following environment
// variable.
- final String? envExecutable = io.Platform.environment['CHROME_EXECUTABLE'];
+ final String envExecutable = io.Platform.environment['CHROME_EXECUTABLE'];
if (envExecutable != null) {
return envExecutable;
}
@@ -230,12 +232,15 @@
return '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome';
} else if (io.Platform.isWindows) {
const String kWindowsExecutable = r'Google\Chrome\Application\chrome.exe';
- final List<String> kWindowsPrefixes = <String?>[
+ final List<String> kWindowsPrefixes = <String>[
io.Platform.environment['LOCALAPPDATA'],
io.Platform.environment['PROGRAMFILES'],
io.Platform.environment['PROGRAMFILES(X86)'],
- ].whereType<String>().toList();
+ ];
final String windowsPrefix = kWindowsPrefixes.firstWhere((String prefix) {
+ if (prefix == null) {
+ return false;
+ }
final String expectedPath = path.join(prefix, kWindowsExecutable);
return io.File(expectedPath).existsSync();
}, orElse: () => '.');
@@ -264,7 +269,7 @@
final io.HttpClient client = io.HttpClient();
final io.HttpClientRequest request = await client.getUrl(base.resolve('/json/list'));
final io.HttpClientResponse response = await request.close();
- final List<dynamic>? jsonObject = await json.fuse(utf8).decoder.bind(response).single as List<dynamic>?;
+ final List<dynamic> jsonObject = await json.fuse(utf8).decoder.bind(response).single as List<dynamic>;
if (jsonObject == null || jsonObject.isEmpty) {
return base;
}
@@ -274,17 +279,17 @@
/// Summarizes a Blink trace down to a few interesting values.
class BlinkTraceSummary {
BlinkTraceSummary._({
- required this.averageBeginFrameTime,
- required this.averageUpdateLifecyclePhasesTime,
+ @required this.averageBeginFrameTime,
+ @required this.averageUpdateLifecyclePhasesTime,
}) : averageTotalUIFrameTime = averageBeginFrameTime + averageUpdateLifecyclePhasesTime;
- static BlinkTraceSummary? fromJson(List<Map<String, dynamic>> traceJson) {
+ static BlinkTraceSummary fromJson(List<Map<String, dynamic>> traceJson) {
try {
// Convert raw JSON data to BlinkTraceEvent objects sorted by timestamp.
List<BlinkTraceEvent> events = traceJson
.map<BlinkTraceEvent>(BlinkTraceEvent.fromJson)
.toList()
- ..sort((BlinkTraceEvent a, BlinkTraceEvent b) => a.ts! - b.ts!);
+ ..sort((BlinkTraceEvent a, BlinkTraceEvent b) => a.ts - b.ts);
Exception noMeasuredFramesFound() => Exception(
'No measured frames found in benchmark tracing data. This likely '
@@ -311,7 +316,7 @@
return null;
}
- final int tabPid = firstMeasuredFrameEvent.pid!;
+ final int tabPid = firstMeasuredFrameEvent.pid;
// Filter out data from unrelated processes
events = events.where((BlinkTraceEvent element) => element.pid == tabPid).toList();
@@ -347,8 +352,8 @@
// Compute averages and summarize.
return BlinkTraceSummary._(
- averageBeginFrameTime: _computeAverageDuration(frames.map((BlinkFrame frame) => frame.beginFrame).whereType<BlinkTraceEvent>().toList()),
- averageUpdateLifecyclePhasesTime: _computeAverageDuration(frames.map((BlinkFrame frame) => frame.updateAllLifecyclePhases).whereType<BlinkTraceEvent>().toList()),
+ averageBeginFrameTime: _computeAverageDuration(frames.map((BlinkFrame frame) => frame.beginFrame).toList()),
+ averageUpdateLifecyclePhasesTime: _computeAverageDuration(frames.map((BlinkFrame frame) => frame.updateAllLifecyclePhases).toList()),
);
} catch (_, __) {
final io.File traceFile = io.File('./chrome-trace.json');
@@ -387,16 +392,16 @@
/// Contains events pertaining to a single frame in the Blink trace data.
class BlinkFrame {
/// Corresponds to 'WebViewImpl::beginFrame' event.
- BlinkTraceEvent? beginFrame;
+ BlinkTraceEvent beginFrame;
/// Corresponds to 'WebViewImpl::updateAllLifecyclePhases' event.
- BlinkTraceEvent? updateAllLifecyclePhases;
+ BlinkTraceEvent updateAllLifecyclePhases;
/// Corresponds to 'measured_frame' begin event.
- BlinkTraceEvent? beginMeasuredFrame;
+ BlinkTraceEvent beginMeasuredFrame;
/// Corresponds to 'measured_frame' end event.
- BlinkTraceEvent? endMeasuredFrame;
+ BlinkTraceEvent endMeasuredFrame;
}
/// Takes a list of events that have non-null [BlinkTraceEvent.tdur] computes
@@ -409,7 +414,7 @@
if (event.tdur == null) {
throw FormatException('Trace event lacks "tdur" field: $event');
}
- return previousValue + event.tdur!;
+ return previousValue + event.tdur;
});
final int sampleCount = math.min(events.length, _kMeasuredSampleCount);
return Duration(microseconds: sum ~/ sampleCount);
@@ -421,15 +426,15 @@
/// * https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview
class BlinkTraceEvent {
BlinkTraceEvent._({
- required this.args,
- required this.cat,
- required this.name,
- required this.ph,
- this.pid,
- this.tid,
- this.ts,
- this.tts,
- this.tdur,
+ @required this.args,
+ @required this.cat,
+ @required this.name,
+ @required this.ph,
+ @required this.pid,
+ @required this.tid,
+ @required this.ts,
+ @required this.tts,
+ @required this.tdur,
});
/// Parses an event from its JSON representation.
@@ -483,19 +488,19 @@
final String ph;
/// Process ID of the process that emitted the event.
- final int? pid;
+ final int pid;
/// Thread ID of the thread that emitted the event.
- final int? tid;
+ final int tid;
/// Timestamp in microseconds using tracer clock.
- final int? ts;
+ final int ts;
/// Timestamp in microseconds using thread clock.
- final int? tts;
+ final int tts;
/// Event duration in microseconds.
- final int? tdur;
+ final int tdur;
/// A "begin frame" event contains all of the scripting time of an animation
/// frame (JavaScript, WebAssembly), plus a negligible amount of internal
@@ -551,7 +556,7 @@
/// validation and conversion is needed.
///
/// Returns null if the value is null.
-int? _readInt(Map<String, dynamic> json, String key) {
+int _readInt(Map<String, dynamic> json, String key) {
final num jsonValue = json[key] as num;
if (jsonValue == null) {
@@ -573,10 +578,10 @@
/// Inconsistency detected by ld.so: ../elf/dl-tls.c: 493: _dl_allocate_tls_init: Assertion `listp->slotinfo[cnt].gen <= GL(dl_tls_generation)' failed!
const String _kGlibcError = 'Inconsistency detected by ld.so';
-Future<io.Process> _spawnChromiumProcess(String executable, List<String> args, { String? workingDirectory }) async {
+Future<io.Process> _spawnChromiumProcess(String executable, List<String> args, { String workingDirectory }) async {
// Keep attempting to launch the browser until one of:
// - Chrome launched successfully, in which case we just return from the loop.
- // - The tool detected an unretryable Chrome error, in which case we throw ToolExit.
+ // - The tool detected an unretriable Chrome error, in which case we throw ToolExit.
while (true) {
final io.Process process = await io.Process.start(executable, args, workingDirectory: workingDirectory);
@@ -606,7 +611,7 @@
'Encountered glibc bug https://sourceware.org/bugzilla/show_bug.cgi?id=19329. '
'Will try launching browser again.',
);
- return '';
+ return null;
}
print('Failed to launch browser. Command used to launch it: ${args.join(' ')}');
throw Exception(
@@ -625,7 +630,7 @@
// launching more processes.
unawaited(process.exitCode.timeout(const Duration(seconds: 1), onTimeout: () {
process.kill();
- return 0;
+ return null;
}));
}
}
diff --git a/dev/devicelab/lib/framework/cocoon.dart b/dev/devicelab/lib/framework/cocoon.dart
index bdca7db..1f09875 100644
--- a/dev/devicelab/lib/framework/cocoon.dart
+++ b/dev/devicelab/lib/framework/cocoon.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert' show Encoding, json;
import 'dart:io';
@@ -18,12 +20,12 @@
typedef ProcessRunSync = ProcessResult Function(
String,
List<String>, {
- Map<String, String>? environment,
+ Map<String, String> environment,
bool includeParentEnvironment,
bool runInShell,
- Encoding? stderrEncoding,
- Encoding? stdoutEncoding,
- String? workingDirectory,
+ Encoding stderrEncoding,
+ Encoding stdoutEncoding,
+ String workingDirectory,
});
/// Class for test runner to interact with Flutter's infrastructure service, Cocoon.
@@ -32,8 +34,8 @@
/// To retrieve these results, the test runner needs to send results back so the database can be updated.
class Cocoon {
Cocoon({
- String? serviceAccountTokenPath,
- @visibleForTesting Client? httpClient,
+ String serviceAccountTokenPath,
+ @visibleForTesting Client httpClient,
@visibleForTesting this.fs = const LocalFileSystem(),
@visibleForTesting this.processRunSync = Process.runSync,
@visibleForTesting this.requestRetryLimit = 5,
@@ -56,7 +58,7 @@
final int requestRetryLimit;
String get commitSha => _commitSha ?? _readCommitSha();
- String? _commitSha;
+ String _commitSha;
/// Parse the local repo for the current running commit.
String _readCommitSha() {
@@ -83,9 +85,9 @@
/// Send [TaskResult] to Cocoon.
// TODO(chillers): Remove when sendResultsPath is used in prod. https://github.com/flutter/flutter/issues/72457
Future<void> sendTaskResult({
- required String builderName,
- required TaskResult result,
- required String gitBranch,
+ @required String builderName,
+ @required TaskResult result,
+ @required String gitBranch,
}) async {
assert(builderName != null);
assert(gitBranch != null);
@@ -107,10 +109,10 @@
/// Write the given parameters into an update task request and store the JSON in [resultsPath].
Future<void> writeTaskResultToFile({
- required String builderName,
- required String gitBranch,
- required TaskResult result,
- required String resultsPath,
+ @required String builderName,
+ @required String gitBranch,
+ @required TaskResult result,
+ @required String resultsPath,
}) async {
assert(builderName != null);
assert(gitBranch != null);
@@ -132,9 +134,9 @@
}
Map<String, dynamic> _constructUpdateRequest({
- String? builderName,
- required TaskResult result,
- required String gitBranch,
+ @required String builderName,
+ @required TaskResult result,
+ @required String gitBranch,
}) {
final Map<String, dynamic> updateRequest = <String, dynamic>{
'CommitBranch': gitBranch,
@@ -149,12 +151,12 @@
final List<String> validScoreKeys = <String>[];
if (result.benchmarkScoreKeys != null) {
- for (final String scoreKey in result.benchmarkScoreKeys!) {
- final Object score = result.data![scoreKey] as Object;
+ for (final String scoreKey in result.benchmarkScoreKeys) {
+ final Object score = result.data[scoreKey];
if (score is num) {
// Convert all metrics to double, which provide plenty of precision
// without having to add support for multiple numeric types in Cocoon.
- result.data![scoreKey] = score.toDouble();
+ result.data[scoreKey] = score.toDouble();
validScoreKeys.add(scoreKey);
}
}
@@ -193,15 +195,15 @@
class AuthenticatedCocoonClient extends BaseClient {
AuthenticatedCocoonClient(
this._serviceAccountTokenPath, {
- @visibleForTesting Client? httpClient,
- @visibleForTesting FileSystem? filesystem,
+ @visibleForTesting Client httpClient,
+ @visibleForTesting FileSystem filesystem,
}) : _delegate = httpClient ?? Client(),
_fs = filesystem ?? const LocalFileSystem();
/// Authentication token to have the ability to upload and record test results.
///
/// This is intended to only be passed on automated runs on LUCI post-submit.
- final String? _serviceAccountTokenPath;
+ final String _serviceAccountTokenPath;
/// Underlying [HttpClient] to send requests to.
final Client _delegate;
@@ -211,7 +213,7 @@
/// Value contained in the service account token file that can be used in http requests.
String get serviceAccountToken => _serviceAccountToken ?? _readServiceAccountTokenFile();
- String? _serviceAccountToken;
+ String _serviceAccountToken;
/// Get [serviceAccountToken] from the given service account file.
String _readServiceAccountTokenFile() {
diff --git a/dev/devicelab/lib/framework/devices.dart b/dev/devicelab/lib/framework/devices.dart
index a4945bb..4800311 100644
--- a/dev/devicelab/lib/framework/devices.dart
+++ b/dev/devicelab/lib/framework/devices.dart
@@ -2,12 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:math' as math;
import 'package:flutter_devicelab/common.dart';
+import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'utils.dart';
@@ -34,8 +37,8 @@
}
/// Return the item is in idList if find a match, otherwise return null
-String? _findMatchId(List<String> idList, String idPattern) {
- String? candidate;
+String _findMatchId(List<String> idList, String idPattern) {
+ String candidate;
idPattern = idPattern.toLowerCase();
for(final String id in idList) {
if (id.toLowerCase() == idPattern) {
@@ -181,46 +184,47 @@
}
class AndroidDeviceDiscovery implements DeviceDiscovery {
- factory AndroidDeviceDiscovery({AndroidCPU? cpu}) {
+ factory AndroidDeviceDiscovery({AndroidCPU cpu}) {
return _instance ??= AndroidDeviceDiscovery._(cpu);
}
AndroidDeviceDiscovery._(this.cpu);
- final AndroidCPU? cpu;
+ final AndroidCPU cpu;
// Parses information about a device. Example:
//
// 015d172c98400a03 device usb:340787200X product:nakasi model:Nexus_7 device:grouper
static final RegExp _kDeviceRegex = RegExp(r'^(\S+)\s+(\S+)(.*)');
- static AndroidDeviceDiscovery? _instance;
+ static AndroidDeviceDiscovery _instance;
- AndroidDevice? _workingDevice;
+ AndroidDevice _workingDevice;
@override
Future<AndroidDevice> get workingDevice async {
if (_workingDevice == null) {
if (Platform.environment.containsKey(DeviceIdEnvName)) {
- final String deviceId = Platform.environment[DeviceIdEnvName]!;
+ final String deviceId = Platform.environment[DeviceIdEnvName];
await chooseWorkingDeviceById(deviceId);
- return _workingDevice!;
+ return _workingDevice;
}
await chooseWorkingDevice();
}
- return _workingDevice!;
+ return _workingDevice;
}
Future<bool> _matchesCPURequirement(AndroidDevice device) async {
+ if (cpu == null)
+ return true;
switch (cpu) {
- case null:
- return true;
case AndroidCPU.arm64:
return device.isArm64();
case AndroidCPU.arm:
return device.isArm();
}
+ return true;
}
/// Picks a random Android device out of connected devices and sets it as
@@ -255,11 +259,11 @@
@override
Future<void> chooseWorkingDeviceById(String deviceId) async {
- final String? matchedId = _findMatchId(await discoverDevices(), deviceId);
+ final String matchedId = _findMatchId(await discoverDevices(), deviceId);
if (matchedId != null) {
_workingDevice = AndroidDevice(deviceId: matchedId);
if (cpu != null) {
- if (!await _matchesCPURequirement(_workingDevice!)) {
+ if (!await _matchesCPURequirement(_workingDevice)) {
throw DeviceException('The selected device $matchedId does not match the cpu requirement');
}
}
@@ -286,10 +290,10 @@
continue;
if (_kDeviceRegex.hasMatch(line)) {
- final Match match = _kDeviceRegex.firstMatch(line)!;
+ final Match match = _kDeviceRegex.firstMatch(line);
- final String deviceID = match[1]!;
- final String deviceState = match[2]!;
+ final String deviceID = match[1];
+ final String deviceState = match[2];
if (!const <String>['unauthorized', 'offline'].contains(deviceState)) {
results.add(deviceID);
@@ -338,9 +342,9 @@
FuchsiaDeviceDiscovery._();
- static FuchsiaDeviceDiscovery? _instance;
+ static FuchsiaDeviceDiscovery _instance;
- FuchsiaDevice? _workingDevice;
+ FuchsiaDevice _workingDevice;
String get _ffx {
final String ffx = path.join(getArtifactPath(), 'fuchsia', 'tools','x64', 'ffx');
@@ -354,13 +358,13 @@
Future<FuchsiaDevice> get workingDevice async {
if (_workingDevice == null) {
if (Platform.environment.containsKey(DeviceIdEnvName)) {
- final String deviceId = Platform.environment[DeviceIdEnvName]!;
+ final String deviceId = Platform.environment[DeviceIdEnvName];
await chooseWorkingDeviceById(deviceId);
- return _workingDevice!;
+ return _workingDevice;
}
await chooseWorkingDevice();
}
- return _workingDevice!;
+ return _workingDevice;
}
/// Picks the first connected Fuchsia device.
@@ -379,8 +383,8 @@
@override
Future<void> chooseWorkingDeviceById(String deviceId) async {
- final String? matchedId = _findMatchId(await discoverDevices(), deviceId);
- if (matchedId != null) {
+ final String matchedId = _findMatchId(await discoverDevices(), deviceId);
+ if (deviceId != null) {
_workingDevice = FuchsiaDevice(deviceId: matchedId);
print('Choose device by ID: $matchedId');
return;
@@ -438,7 +442,7 @@
}
class AndroidDevice extends Device {
- AndroidDevice({required this.deviceId}) {
+ AndroidDevice({@required this.deviceId}) {
_updateDeviceInfo();
}
@@ -536,19 +540,19 @@
}
/// Executes [command] on `adb shell` and returns its exit code.
- Future<void> shellExec(String command, List<String> arguments, { Map<String, String>? environment, bool silent = false }) async {
+ Future<void> shellExec(String command, List<String> arguments, { Map<String, String> environment, bool silent = false }) async {
await adb(<String>['shell', command, ...arguments], environment: environment, silent: silent);
}
/// Executes [command] on `adb shell` and returns its standard output as a [String].
- Future<String> shellEval(String command, List<String> arguments, { Map<String, String>? environment, bool silent = false }) {
+ Future<String> shellEval(String command, List<String> arguments, { Map<String, String> environment, bool silent = false }) {
return adb(<String>['shell', command, ...arguments], environment: environment, silent: silent);
}
/// Runs `adb` with the given [arguments], selecting this device.
Future<String> adb(
List<String> arguments, {
- Map<String, String>? environment,
+ Map<String, String> environment,
bool silent = false,
}) {
return eval(
@@ -564,10 +568,10 @@
@override
Future<Map<String, dynamic>> getMemoryStats(String packageName) async {
final String meminfo = await shellEval('dumpsys', <String>['meminfo', packageName]);
- final Match? match = RegExp(r'TOTAL\s+(\d+)').firstMatch(meminfo);
+ final Match match = RegExp(r'TOTAL\s+(\d+)').firstMatch(meminfo);
assert(match != null, 'could not parse dumpsys meminfo output');
return <String, dynamic>{
- 'total_kb': int.parse(match!.group(1)!),
+ 'total_kb': int.parse(match.group(1)),
};
}
@@ -575,7 +579,7 @@
bool get canStreamLogs => true;
bool _abortedLogging/*!*/ = false;
- Process? _loggingProcess;
+ Process/*?*/ _loggingProcess;
@override
Future<void> startLoggingToSink(IOSink sink, {bool clear = true}) async {
@@ -592,17 +596,17 @@
// to view the whole log, or just run logcat alongside this.
<String>['-s', deviceId, 'logcat', 'ActivityManager:I', 'flutter:V', '*:F'],
);
- _loggingProcess!.stdout
+ _loggingProcess.stdout
.transform<String>(const Utf8Decoder(allowMalformed: true))
.listen((String line) {
sink.write(line);
});
- _loggingProcess!.stderr
+ _loggingProcess.stderr
.transform<String>(const Utf8Decoder(allowMalformed: true))
.listen((String line) {
sink.write(line);
});
- unawaited(_loggingProcess!.exitCode.then<void>((int exitCode) {
+ unawaited(_loggingProcess.exitCode.then<void>((int exitCode) {
if (!_abortedLogging) {
sink.writeln('adb logcat failed with exit code $exitCode.\n');
}
@@ -613,8 +617,8 @@
Future<void> stopLoggingToSink() async {
if (_loggingProcess != null) {
_abortedLogging = true;
- _loggingProcess!.kill();
- await _loggingProcess!.exitCode;
+ _loggingProcess.kill();
+ await _loggingProcess.exitCode;
}
}
@@ -625,7 +629,7 @@
final Completer<void> processDone = Completer<void>();
final Completer<void> abort = Completer<void>();
bool aborted = false;
- late final StreamController<String> stream;
+ StreamController<String> stream;
stream = StreamController<String>(
onListen: () async {
await adb(<String>['logcat', '--clear']);
@@ -709,22 +713,22 @@
IosDeviceDiscovery._();
- static IosDeviceDiscovery? _instance;
+ static IosDeviceDiscovery _instance;
- IosDevice? _workingDevice;
+ IosDevice _workingDevice;
@override
Future<IosDevice> get workingDevice async {
if (_workingDevice == null) {
if (Platform.environment.containsKey(DeviceIdEnvName)) {
- final String deviceId = Platform.environment[DeviceIdEnvName]!;
+ final String deviceId = Platform.environment[DeviceIdEnvName];
await chooseWorkingDeviceById(deviceId);
- return _workingDevice!;
+ return _workingDevice;
}
await chooseWorkingDevice();
}
- return _workingDevice!;
+ return _workingDevice;
}
/// Picks a random iOS device out of connected devices and sets it as
@@ -745,7 +749,7 @@
@override
Future<void> chooseWorkingDeviceById(String deviceId) async {
- final String? matchedId = _findMatchId(await discoverDevices(), deviceId);
+ final String matchedId = _findMatchId(await discoverDevices(), deviceId);
if (matchedId != null) {
_workingDevice = IosDevice(deviceId: matchedId);
print('Choose device by ID: $matchedId');
@@ -820,7 +824,7 @@
/// iOS device.
class IosDevice extends Device {
- IosDevice({ required this.deviceId });
+ IosDevice({ @required this.deviceId });
@override
final String deviceId;
@@ -842,8 +846,8 @@
@override
bool get canStreamLogs => true;
- bool _abortedLogging = false;
- Process? _loggingProcess;
+ bool _abortedLogging/*!*/ = false;
+ Process/*?*/ _loggingProcess;
@override
Future<void> startLoggingToSink(IOSink sink, {bool clear = true}) async {
@@ -855,17 +859,17 @@
'DYLD_LIBRARY_PATH': dyldLibraryPath,
},
);
- _loggingProcess!.stdout
+ _loggingProcess.stdout
.transform<String>(const Utf8Decoder(allowMalformed: true))
.listen((String line) {
sink.write(line);
});
- _loggingProcess!.stderr
+ _loggingProcess.stderr
.transform<String>(const Utf8Decoder(allowMalformed: true))
.listen((String line) {
sink.write(line);
});
- unawaited(_loggingProcess!.exitCode.then<void>((int exitCode) {
+ unawaited(_loggingProcess.exitCode.then<void>((int exitCode) {
if (!_abortedLogging) {
sink.writeln('idevicesyslog failed with exit code $exitCode.\n');
}
@@ -876,8 +880,8 @@
Future<void> stopLoggingToSink() async {
if (_loggingProcess != null) {
_abortedLogging = true;
- _loggingProcess!.kill();
- await _loggingProcess!.exitCode;
+ _loggingProcess.kill();
+ await _loggingProcess.exitCode;
}
}
@@ -930,7 +934,7 @@
/// Fuchsia device.
class FuchsiaDevice extends Device {
- const FuchsiaDevice({ required this.deviceId });
+ const FuchsiaDevice({ @required this.deviceId });
@override
final String deviceId;
@@ -978,7 +982,7 @@
/// Path to the `adb` executable.
String get adbPath {
- final String? androidHome = Platform.environment['ANDROID_HOME'] ?? Platform.environment['ANDROID_SDK_ROOT'];
+ final String androidHome = Platform.environment['ANDROID_HOME'] ?? Platform.environment['ANDROID_SDK_ROOT'];
if (androidHome == null) {
throw const DeviceException(
@@ -997,7 +1001,7 @@
}
class FakeDevice extends Device {
- const FakeDevice({ required this.deviceId });
+ const FakeDevice({ @required this.deviceId });
@override
final String deviceId;
@@ -1051,22 +1055,22 @@
FakeDeviceDiscovery._();
- static FakeDeviceDiscovery? _instance;
+ static FakeDeviceDiscovery _instance;
- FakeDevice? _workingDevice;
+ FakeDevice _workingDevice;
@override
Future<FakeDevice> get workingDevice async {
if (_workingDevice == null) {
if (Platform.environment.containsKey(DeviceIdEnvName)) {
- final String deviceId = Platform.environment[DeviceIdEnvName]!;
+ final String deviceId = Platform.environment[DeviceIdEnvName];
await chooseWorkingDeviceById(deviceId);
- return _workingDevice!;
+ return _workingDevice;
}
await chooseWorkingDevice();
}
- return _workingDevice!;
+ return _workingDevice;
}
/// The Fake is only available for by ID device discovery.
@@ -1077,7 +1081,7 @@
@override
Future<void> chooseWorkingDeviceById(String deviceId) async {
- final String? matchedId = _findMatchId(await discoverDevices(), deviceId);
+ final String matchedId = _findMatchId(await discoverDevices(), deviceId);
if (matchedId != null) {
_workingDevice = FakeDevice(deviceId: matchedId);
print('Choose device by ID: $matchedId');
diff --git a/dev/devicelab/lib/framework/framework.dart b/dev/devicelab/lib/framework/framework.dart
index a304102..e73e373 100644
--- a/dev/devicelab/lib/framework/framework.dart
+++ b/dev/devicelab/lib/framework/framework.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
@@ -62,8 +64,8 @@
_TaskRunner(this.task) {
registerExtension('ext.cocoonRunTask',
(String method, Map<String, String> parameters) async {
- final Duration? taskTimeout = parameters.containsKey('timeoutInMinutes')
- ? Duration(minutes: int.parse(parameters['timeoutInMinutes']!))
+ final Duration taskTimeout = parameters.containsKey('timeoutInMinutes')
+ ? Duration(minutes: int.parse(parameters['timeoutInMinutes']))
: null;
// This is only expected to be passed in unit test runs so they do not
// kill the Dart process that is running them and waste time running config.
@@ -80,7 +82,7 @@
final TaskFunction task;
- Future<Device?> _getWorkingDeviceIfAvailable() async {
+ Future<Device/*?*/> _getWorkingDeviceIfAvailable() async {
try {
return await devices.workingDevice;
} on DeviceException {
@@ -89,8 +91,8 @@
}
// TODO(ianh): workaround for https://github.com/dart-lang/sdk/issues/23797
- RawReceivePort? _keepAlivePort;
- Timer? _startTaskTimeout;
+ RawReceivePort _keepAlivePort;
+ Timer _startTaskTimeout;
bool _taskStarted = false;
final Completer<TaskResult> _completer = Completer<TaskResult>();
@@ -100,7 +102,7 @@
/// Signals that this task runner finished running the task.
Future<TaskResult> get whenDone => _completer.future;
- Future<TaskResult> run(Duration? taskTimeout, {
+ Future<TaskResult> run(Duration taskTimeout, {
bool runFlutterConfig = true,
bool runProcessCleanup = true,
}) async {
@@ -108,7 +110,7 @@
_taskStarted = true;
print('Running task with a timeout of $taskTimeout.');
final String exe = Platform.isWindows ? '.exe' : '';
- late Set<RunningProcessInfo> beforeRunningDartInstances;
+ Set<RunningProcessInfo> beforeRunningDartInstances;
if (runProcessCleanup) {
section('Checking running Dart$exe processes');
beforeRunningDartInstances = await getRunningProcesses(
@@ -134,7 +136,7 @@
'--enable-windows-desktop',
'--enable-linux-desktop',
'--enable-web',
- if (localEngine != null) ...<String>['--local-engine', localEngine!],
+ if (localEngine != null) ...<String>['--local-engine', localEngine],
], canFail: true);
if (configResult != 0) {
print('Failed to enable configuration, tasks may not run.');
@@ -143,12 +145,12 @@
print('Skipping enabling configs for macOS, Linux, Windows, and Web');
}
- final Device? device = await _getWorkingDeviceIfAvailable();
- late TaskResult result;
- IOSink? sink;
+ final Device/*?*/ device = await _getWorkingDeviceIfAvailable();
+ /*late*/ TaskResult result;
+ IOSink/*?*/ sink;
try {
if (device != null && device.canStreamLogs && hostAgent.dumpDirectory != null) {
- sink = File(path.join(hostAgent.dumpDirectory!.path, '${device.deviceId}.log')).openWrite();
+ sink = File(path.join(hostAgent.dumpDirectory.path, '${device.deviceId}.log')).openWrite();
await device.startLoggingToSink(sink);
}
@@ -210,7 +212,7 @@
final File rebootFile = _rebootFile();
int runCount;
if (rebootFile.existsSync()) {
- runCount = int.tryParse(rebootFile.readAsStringSync().trim()) ?? 0;
+ runCount = int.tryParse(rebootFile.readAsStringSync().trim());
} else {
runCount = 0;
}
@@ -281,10 +283,10 @@
File _rebootFile() {
if (Platform.isLinux || Platform.isMacOS) {
- return File(path.join(Platform.environment['HOME']!, '.reboot-count'));
+ return File(path.join(Platform.environment['HOME'], '.reboot-count'));
}
if (!Platform.isWindows) {
throw StateError('Unexpected platform ${Platform.operatingSystem}');
}
- return File(path.join(Platform.environment['USERPROFILE']!, '.reboot-count'));
+ return File(path.join(Platform.environment['USERPROFILE'], '.reboot-count'));
}
diff --git a/dev/devicelab/lib/framework/ios.dart b/dev/devicelab/lib/framework/ios.dart
index 3e03bd9..6598011 100644
--- a/dev/devicelab/lib/framework/ios.dart
+++ b/dev/devicelab/lib/framework/ios.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:convert';
import 'utils.dart';
@@ -40,10 +42,17 @@
final List<String> lines = LineSplitter.split(loadCommands).toList();
lines.asMap().forEach((int index, String line) {
if (line.contains('segname __LLVM') && lines.length - index - 1 > 3) {
- emptyBitcodeMarkerFound |= lines
+ final String emptyBitcodeMarker = lines
.skip(index - 1)
.take(4)
- .any((String line) => line.contains(' size 0x0000000000000001'));
+ .firstWhere(
+ (String line) => line.contains(' size 0x0000000000000001'),
+ orElse: () => null,
+ );
+ if (emptyBitcodeMarker != null) {
+ emptyBitcodeMarkerFound = true;
+ return;
+ }
}
});
return !emptyBitcodeMarkerFound;
@@ -70,16 +79,16 @@
workingDirectory: flutterDirectory.path,
);
- String? iOSSimRuntime;
+ String iOSSimRuntime;
final RegExp iOSRuntimePattern = RegExp(r'iOS .*\) - (.*)');
for (final String runtime in LineSplitter.split(availableRuntimes)) {
// These seem to be in order, so allow matching multiple lines so it grabs
// the last (hopefully latest) one.
- final RegExpMatch? iOSRuntimeMatch = iOSRuntimePattern.firstMatch(runtime);
+ final RegExpMatch iOSRuntimeMatch = iOSRuntimePattern.firstMatch(runtime);
if (iOSRuntimeMatch != null) {
- iOSSimRuntime = iOSRuntimeMatch.group(1)!.trim();
+ iOSSimRuntime = iOSRuntimeMatch.group(1).trim();
continue;
}
}
diff --git a/dev/devicelab/lib/framework/manifest.dart b/dev/devicelab/lib/framework/manifest.dart
index a52ab10..836c8ab 100644
--- a/dev/devicelab/lib/framework/manifest.dart
+++ b/dev/devicelab/lib/framework/manifest.dart
@@ -2,14 +2,17 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:io';
+import 'package:meta/meta.dart';
import 'package:yaml/yaml.dart';
import 'utils.dart';
/// Loads manifest data from `manifest.yaml` file or from [yaml], if present.
-Manifest loadTaskManifest([ String? yaml ]) {
+Manifest loadTaskManifest([ String yaml ]) {
final dynamic manifestYaml = yaml == null
? loadYaml(file('manifest.yaml').readAsStringSync())
: loadYamlNode(yaml);
@@ -29,13 +32,13 @@
/// A CI task.
class ManifestTask {
ManifestTask._({
- required this.name,
- required this.description,
- required this.stage,
- required this.requiredAgentCapabilities,
- required this.isFlaky,
- required this.timeoutInMinutes,
- required this.onLuci,
+ @required this.name,
+ @required this.description,
+ @required this.stage,
+ @required this.requiredAgentCapabilities,
+ @required this.isFlaky,
+ @required this.timeoutInMinutes,
+ @required this.onLuci,
}) {
final String taskName = 'task "$name"';
_checkIsNotBlank(name, 'Task name', taskName);
@@ -145,9 +148,9 @@
// ignore: avoid_dynamic_calls
stage: taskYaml['stage'] as String,
requiredAgentCapabilities: capabilities as List<String>,
- isFlaky: isFlaky as bool,
+ isFlaky: isFlaky as bool ?? false,
timeoutInMinutes: timeoutInMinutes as int,
- onLuci: onLuci as bool,
+ onLuci: onLuci as bool ?? false,
);
}
@@ -158,7 +161,7 @@
final dynamic capability = capabilities[i];
_checkType(capability is String, capability, 'required_agent_capabilities[$i]', 'string');
}
- return capabilitiesYaml.cast<String>();
+ return (capabilitiesYaml as List<dynamic>).cast<String>();
}
void _checkType(bool isValid, dynamic value, String variableName, String typeName) {
diff --git a/dev/devicelab/lib/framework/runner.dart b/dev/devicelab/lib/framework/runner.dart
index bbfc959..7a84e9f 100644
--- a/dev/devicelab/lib/framework/runner.dart
+++ b/dev/devicelab/lib/framework/runner.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@@ -19,13 +21,13 @@
List<String> taskNames, {
bool exitOnFirstTestFailure = false,
bool silent = false,
- String? deviceId,
- String? gitBranch,
- String? localEngine,
- String? localEngineSrcPath,
- String? luciBuilder,
- String? resultsPath,
- List<String>? taskArgs,
+ String deviceId,
+ String gitBranch,
+ String localEngine,
+ String localEngineSrcPath,
+ String luciBuilder,
+ String resultsPath,
+ List<String> taskArgs,
}) async {
for (final String taskName in taskNames) {
section('Running task "$taskName"');
@@ -42,10 +44,10 @@
print(const JsonEncoder.withIndent(' ').convert(result));
section('Finished task "$taskName"');
- if (resultsPath != null && gitBranch != null) {
+ if (resultsPath != null) {
final Cocoon cocoon = Cocoon();
await cocoon.writeTaskResultToFile(
- builderName: luciBuilder!,
+ builderName: luciBuilder,
gitBranch: gitBranch,
result: result,
resultsPath: resultsPath,
@@ -74,11 +76,11 @@
Future<TaskResult> runTask(
String taskName, {
bool silent = false,
- String? localEngine,
- String? localEngineSrcPath,
- String? deviceId,
- List<String> ?taskArgs,
- @visibleForTesting Map<String, String>? isolateParams,
+ String localEngine,
+ String localEngineSrcPath,
+ String deviceId,
+ List<String> taskArgs,
+ @visibleForTesting Map<String, String> isolateParams,
}) async {
final String taskExecutable = 'bin/tasks/$taskName.dart';
@@ -115,7 +117,7 @@
.transform<String>(const LineSplitter())
.listen((String line) {
if (!uri.isCompleted) {
- final Uri? serviceUri = parseServiceUri(line, prefix: 'Observatory listening on ');
+ final Uri serviceUri = parseServiceUri(line, prefix: 'Observatory listening on ');
if (serviceUri != null)
uri.complete(serviceUri);
}
@@ -137,7 +139,7 @@
'ext.cocoonRunTask',
args: isolateParams,
isolateId: result.isolate.id,
- )).json!;
+ )).json;
final TaskResult taskResult = TaskResult.fromJson(taskResultJson);
await runner.exitCode;
return taskResult;
@@ -166,13 +168,13 @@
// Look up the isolate.
final VmService client = await vmServiceConnectUri(url);
VM vm = await client.getVM();
- while (vm.isolates!.isEmpty) {
+ while (vm.isolates.isEmpty) {
await Future<void>.delayed(const Duration(seconds: 1));
vm = await client.getVM();
}
- final IsolateRef isolate = vm.isolates!.first;
+ final IsolateRef isolate = vm.isolates.first;
final Response response = await client.callServiceExtension('ext.cocoonRunnerReady', isolateId: isolate.id);
- if (response.json!['response'] != 'ready')
+ if (response.json['response'] != 'ready')
throw 'not ready yet';
return ConnectionResult(client, isolate);
} catch (error) {
@@ -191,7 +193,7 @@
}
/// The cocoon client sends an invalid VM service response, we need to intercept it.
-Future<VmService> vmServiceConnectUri(String wsUri, {Log? log}) async {
+Future<VmService> vmServiceConnectUri(String wsUri, {Log log}) async {
final WebSocket socket = await WebSocket.connect(wsUri);
final StreamController<dynamic> controller = StreamController<dynamic>();
final Completer<dynamic> streamClosedCompleter = Completer<dynamic>();
@@ -205,7 +207,7 @@
controller.add(data);
}
},
- onError: (Object err, StackTrace stackTrace) => controller.addError(err, stackTrace),
+ onError: (dynamic err, StackTrace stackTrace) => controller.addError(err, stackTrace),
onDone: () => streamClosedCompleter.complete(),
);
diff --git a/dev/devicelab/lib/framework/running_processes.dart b/dev/devicelab/lib/framework/running_processes.dart
index 07a5e52..b07f1c1 100644
--- a/dev/devicelab/lib/framework/running_processes.dart
+++ b/dev/devicelab/lib/framework/running_processes.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:io';
import 'package:meta/meta.dart';
@@ -34,7 +36,7 @@
}
}
-Future<bool> killProcess(String pid, {ProcessManager? processManager}) async {
+Future<bool> killProcess(String pid, {ProcessManager processManager}) async {
assert(pid != null, 'Must specify a pid to kill');
processManager ??= const LocalProcessManager();
ProcessResult result;
@@ -56,8 +58,8 @@
}
Stream<RunningProcessInfo> getRunningProcesses({
- String? processName,
- ProcessManager? processManager,
+ String processName,
+ ProcessManager processManager,
}) {
processManager ??= const LocalProcessManager();
if (Platform.isWindows) {
@@ -67,7 +69,7 @@
}
@visibleForTesting
-Stream<RunningProcessInfo> windowsRunningProcesses(String? processName) async* {
+Stream<RunningProcessInfo> windowsRunningProcesses(String processName) async* {
// PowerShell script to get the command line arguments and create time of
// a process.
// See: https://docs.microsoft.com/en-us/windows/desktop/cimwin32prov/win32-process
@@ -105,8 +107,8 @@
const int processIdHeaderSize = 'ProcessId'.length;
const int creationDateHeaderStart = processIdHeaderSize + 1;
- late int creationDateHeaderEnd;
- late int commandLineHeaderStart;
+ int creationDateHeaderEnd;
+ int commandLineHeaderStart;
bool inTableBody = false;
for (final String line in output.split('\n')) {
if (line.startsWith('ProcessId')) {
@@ -158,7 +160,7 @@
@visibleForTesting
Stream<RunningProcessInfo> posixRunningProcesses(
- String? processName,
+ String processName,
ProcessManager processManager,
) async* {
// Cirrus is missing this in Linux for some reason.
@@ -192,7 +194,7 @@
@visibleForTesting
Iterable<RunningProcessInfo> processPsOutput(
String output,
- String? processName,
+ String processName,
) sync* {
if (output == null) {
return;
@@ -233,7 +235,7 @@
final String rawTime = line.substring(0, 24);
final String year = rawTime.substring(20, 24);
- final String month = months[rawTime.substring(4, 7)]!;
+ final String month = months[rawTime.substring(4, 7)];
final String day = rawTime.substring(8, 10).replaceFirst(' ', '0');
final String time = rawTime.substring(11, 19);
diff --git a/dev/devicelab/lib/framework/task_result.dart b/dev/devicelab/lib/framework/task_result.dart
index 3fa821d..be6e4e4 100644
--- a/dev/devicelab/lib/framework/task_result.dart
+++ b/dev/devicelab/lib/framework/task_result.dart
@@ -41,7 +41,7 @@
List<String> detailFiles = const <String>[],
}) {
return TaskResult.success(
- json.decode(file.readAsStringSync()) as Map<String, dynamic>?,
+ json.decode(file.readAsStringSync()) as Map<String, dynamic>,
benchmarkScoreKeys: benchmarkScoreKeys,
detailFiles: detailFiles,
);
@@ -53,14 +53,14 @@
if (success) {
final List<String> benchmarkScoreKeys = (json['benchmarkScoreKeys'] as List<dynamic>? ?? <String>[]).cast<String>();
final List<String> detailFiles = (json['detailFiles'] as List<dynamic>? ?? <String>[]).cast<String>();
- return TaskResult.success(json['data'] as Map<String, dynamic>?,
+ return TaskResult.success(json['data'] as Map<String, dynamic>,
benchmarkScoreKeys: benchmarkScoreKeys,
detailFiles: detailFiles,
- message: json['reason'] as String?,
+ message: json['reason'] as String,
);
}
- return TaskResult.failure(json['reason'] as String?);
+ return TaskResult.failure(json['reason'] as String);
}
/// Constructs an unsuccessful result.
@@ -88,7 +88,7 @@
bool get failed => !succeeded;
/// Explains the result in a human-readable format.
- final String? message;
+ final String message;
/// Serializes this task result to JSON format.
///
@@ -124,7 +124,7 @@
}
@override
- String toString() => message ?? '';
+ String toString() => message;
}
class TaskResultCheckProcesses extends TaskResult {
diff --git a/dev/devicelab/lib/framework/utils.dart b/dev/devicelab/lib/framework/utils.dart
index 7983e27..aeb501a 100644
--- a/dev/devicelab/lib/framework/utils.dart
+++ b/dev/devicelab/lib/framework/utils.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@@ -9,6 +11,7 @@
import 'package:flutter_devicelab/common.dart';
import 'package:flutter_devicelab/framework/devices.dart';
+import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:process/process.dart';
import 'package:stack_trace/stack_trace.dart';
@@ -20,7 +23,7 @@
String cwd = Directory.current.path;
/// The local engine to use for [flutter] and [evalFlutter], if any.
-String? get localEngine {
+String get localEngine {
// Use two distinct `defaultValue`s to determine whether a 'localEngine'
// declaration exists in the environment.
const bool isDefined =
@@ -31,7 +34,7 @@
/// The local engine source path to use if a local engine is used for [flutter]
/// and [evalFlutter].
-String? get localEngineSrcPath {
+String get localEngineSrcPath {
// Use two distinct `defaultValue`s to determine whether a
// 'localEngineSrcPath' declaration exists in the environment.
const bool isDefined =
@@ -67,18 +70,18 @@
HealthCheckResult.failure(this.details) : succeeded = false;
HealthCheckResult.error(dynamic error, dynamic stackTrace)
: succeeded = false,
- details = 'ERROR: $error${stackTrace != null ? '\n$stackTrace' : ''}';
+ details = 'ERROR: $error${'\n$stackTrace' ?? ''}';
final bool succeeded;
- final String? details;
+ final String details;
@override
String toString() {
final StringBuffer buf = StringBuffer(succeeded ? 'succeeded' : 'failed');
- if (details != null && details!.trim().isNotEmpty) {
+ if (details != null && details.trim().isNotEmpty) {
buf.writeln();
// Indent details by 4 spaces
- for (final String line in details!.trim().split('\n')) {
+ for (final String line in details.trim().split('\n')) {
buf.writeln(' $line');
}
}
@@ -124,7 +127,7 @@
File file(String path) => File(path);
-void copy(File sourceFile, Directory targetDirectory, {String? name}) {
+void copy(File sourceFile, Directory targetDirectory, {String name}) {
final File target = file(
path.join(targetDirectory.path, name ?? path.basename(sourceFile.path)));
target.writeAsBytesSync(sourceFile.readAsBytesSync());
@@ -151,7 +154,7 @@
}
FileSystemEntity move(FileSystemEntity whatToMove,
- {required Directory to, String? name}) {
+ {Directory to, String name}) {
return whatToMove
.renameSync(path.join(to.path, name ?? path.basename(whatToMove.path)));
}
@@ -222,9 +225,9 @@
return version.replaceAll('"', "'");
}
-Future<String?> getCurrentFlutterRepoCommit() {
+Future<String> getCurrentFlutterRepoCommit() {
if (!dir('${flutterDirectory.path}/.git').existsSync()) {
- return Future<String?>.value(null);
+ return Future<String>.value(null);
}
return inDirectory<String>(flutterDirectory, () {
@@ -272,10 +275,10 @@
/// returned in the form of a [Future] that completes to a [Process] object.
Future<Process> startProcess(
String executable,
- List<String>? arguments, {
- Map<String, String>? environment,
+ List<String> arguments, {
+ Map<String, String> environment,
bool isBot = true, // set to false to pretend not to be on a bot (e.g. to test user-facing outputs)
- String? workingDirectory,
+ String workingDirectory,
}) async {
assert(isBot != null);
final String command = '$executable ${arguments?.join(" ") ?? ""}';
@@ -285,7 +288,7 @@
newEnvironment['LANG'] = 'en_US.UTF-8';
print('\nExecuting: $command in $finalWorkingDirectory with environment $newEnvironment');
final Process process = await _processManager.start(
- <String>[executable, ...?arguments],
+ <String>[executable, ...arguments],
environment: newEnvironment,
workingDirectory: finalWorkingDirectory,
);
@@ -321,9 +324,9 @@
Future<int> exec(
String executable,
List<String> arguments, {
- Map<String, String>? environment,
+ Map<String, String> environment,
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
- String? workingDirectory,
+ String workingDirectory,
}) async {
return _execute(
executable,
@@ -337,11 +340,11 @@
Future<int> _execute(
String executable,
List<String> arguments, {
- Map<String, String>? environment,
+ Map<String, String> environment,
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
- String? workingDirectory,
- StringBuffer? output, // if not null, the stdout will be written here
- StringBuffer? stderr, // if not null, the stderr will be written here
+ String workingDirectory,
+ StringBuffer output, // if not null, the stdout will be written here
+ StringBuffer stderr, // if not null, the stderr will be written here
bool printStdout = true,
bool printStderr = true,
}) async {
@@ -373,8 +376,8 @@
/// Returns a future that completes when both out and error streams a closed.
Future<void> forwardStandardStreams(
Process process, {
- StringBuffer? output,
- StringBuffer? stderr,
+ StringBuffer output,
+ StringBuffer stderr,
bool printStdout = true,
bool printStderr = true,
}) {
@@ -411,10 +414,10 @@
Future<String> eval(
String executable,
List<String> arguments, {
- Map<String, String>? environment,
+ Map<String, String> environment,
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
- String? workingDirectory,
- StringBuffer? stderr, // if not null, the stderr will be written here
+ String workingDirectory,
+ StringBuffer stderr, // if not null, the stderr will be written here
bool printStdout = true,
bool printStderr = true,
}) async {
@@ -454,10 +457,10 @@
if (command == 'drive' && hostAgent.dumpDirectory != null) ...<String>[
'--screenshot',
- hostAgent.dumpDirectory!.path,
+ hostAgent.dumpDirectory.path,
],
- if (localEngine != null) ...<String>['--local-engine', localEngine!],
- if (localEngineSrcPath != null) ...<String>['--local-engine-src-path', localEngineSrcPath!],
+ if (localEngine != null) ...<String>['--local-engine', localEngine],
+ if (localEngineSrcPath != null) ...<String>['--local-engine-src-path', localEngineSrcPath],
...options,
];
}
@@ -467,7 +470,7 @@
Future<int> flutter(String command, {
List<String> options = const <String>[],
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
- Map<String, String>? environment,
+ Map<String, String> environment = const <String, String>{},
}) {
final List<String> args = flutterCommandArgs(command, options);
return exec(path.join(flutterDirectory.path, 'bin', 'flutter'), args,
@@ -490,8 +493,8 @@
Future<String> evalFlutter(String command, {
List<String> options = const <String>[],
bool canFail = false, // as in, whether failures are ok. False means that they are fatal.
- Map<String, String>? environment,
- StringBuffer? stderr, // if not null, the stderr will be written here.
+ Map<String, String> environment,
+ StringBuffer stderr, // if not null, the stderr will be written here.
}) {
final List<String> args = flutterCommandArgs(command, options);
return eval(path.join(flutterDirectory.path, 'bin', 'flutter'), args,
@@ -518,7 +521,7 @@
/// Returns a future that completes with a path suitable for JAVA_HOME
/// or with null, if Java cannot be found.
-Future<String?> findJavaHome() async {
+Future<String> findJavaHome() async {
if (_javaHome == null) {
final Iterable<String> hits = grep(
'Java binary at: ',
@@ -534,7 +537,7 @@
}
return _javaHome;
}
-String? _javaHome;
+String _javaHome;
Future<T> inDirectory<T>(dynamic directory, Future<T> Function() action) async {
final String previousCwd = cwd;
@@ -565,12 +568,12 @@
Directory get flutterDirectory => Directory.current.parent.parent;
String requireEnvVar(String name) {
- final String? value = Platform.environment[name];
+ final String value = Platform.environment[name];
if (value == null)
fail('$name environment variable is missing. Quitting.');
- return value!;
+ return value;
}
T requireConfigProperty<T>(Map<String, dynamic> map, String propertyName) {
@@ -634,7 +637,7 @@
}
/// Splits [from] into lines and selects those that contain [pattern].
-Iterable<String> grep(Pattern pattern, {required String from}) {
+Iterable<String> grep(Pattern pattern, {@required String from}) {
return from.split('\n').where((String line) {
return line.contains(pattern);
});
@@ -672,8 +675,8 @@
///
/// The `prefix`, if specified, is a regular expression pattern and must not contain groups.
/// `prefix` defaults to the RegExp: `An Observatory debugger .* is available at: `.
-int? parseServicePort(String line, {
- Pattern? prefix,
+int parseServicePort(String line, {
+ Pattern prefix,
}) {
prefix ??= _obsRegExp;
final Iterable<Match> matchesIter = prefix.allMatches(line);
@@ -683,15 +686,15 @@
final Match prefixMatch = matchesIter.first;
final List<Match> matches =
_obsPortRegExp.allMatches(line, prefixMatch.end).toList();
- return matches.isEmpty ? null : int.parse(matches[0].group(2)!);
+ return matches.isEmpty ? null : int.parse(matches[0].group(2));
}
/// Tries to extract a URL from the string.
///
/// The `prefix`, if specified, is a regular expression pattern and must not contain groups.
/// `prefix` defaults to the RegExp: `An Observatory debugger .* is available at: `.
-Uri? parseServiceUri(String line, {
- Pattern? prefix,
+Uri parseServiceUri(String line, {
+ Pattern prefix,
}) {
prefix ??= _obsRegExp;
final Iterable<Match> matchesIter = prefix.allMatches(line);
@@ -701,7 +704,7 @@
final Match prefixMatch = matchesIter.first;
final List<Match> matches =
_obsUriRegExp.allMatches(line, prefixMatch.end).toList();
- return matches.isEmpty ? null : Uri.parse(matches[0].group(0)!);
+ return matches.isEmpty ? null : Uri.parse(matches[0].group(0));
}
/// Checks that the file exists, otherwise throws a [FileSystemException].
@@ -768,7 +771,7 @@
///
/// Removes the directory [path], then clones the git repository
/// specified by [repo] to the directory [path].
-Future<int> gitClone({required String path, required String repo}) async {
+Future<int> gitClone({String path, String repo}) async {
rmTree(Directory(path));
await Directory(path).create(recursive: true);
@@ -789,7 +792,7 @@
/// Waits a constant duration of [delayDuration] between every retry attempt.
Future<T> retry<T>(
FutureOr<T> Function() fn, {
- FutureOr<bool> Function(Exception)? retryIf,
+ FutureOr<bool> Function(Exception) retryIf,
int maxAttempts = 5,
Duration delayDuration = const Duration(seconds: 3),
}) async {
diff --git a/dev/devicelab/lib/microbenchmarks.dart b/dev/devicelab/lib/microbenchmarks.dart
index 008cc60..4a0ebf2 100644
--- a/dev/devicelab/lib/microbenchmarks.dart
+++ b/dev/devicelab/lib/microbenchmarks.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert';
import 'dart:io';
diff --git a/dev/devicelab/lib/tasks/analysis.dart b/dev/devicelab/lib/tasks/analysis.dart
index 30fa74e..9bcd1a5 100644
--- a/dev/devicelab/lib/tasks/analysis.dart
+++ b/dev/devicelab/lib/tasks/analysis.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:io';
import 'package:path/path.dart' as path;
diff --git a/dev/devicelab/lib/tasks/build_test_task.dart b/dev/devicelab/lib/tasks/build_test_task.dart
index 1484007..81bdf3f 100644
--- a/dev/devicelab/lib/tasks/build_test_task.dart
+++ b/dev/devicelab/lib/tasks/build_test_task.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:io';
import 'package:args/args.dart';
@@ -16,9 +18,10 @@
abstract class BuildTestTask {
BuildTestTask(this.args, {this.workingDirectory, this.runFlutterClean = true,}) {
final ArgResults argResults = argParser.parse(args);
- applicationBinaryPath = argResults[kApplicationBinaryPathOption] as String?;
+ applicationBinaryPath = argResults[kApplicationBinaryPathOption] as String;
buildOnly = argResults[kBuildOnlyFlag] as bool;
testOnly = argResults[kTestOnlyFlag] as bool;
+
}
static const String kApplicationBinaryPathOption = 'application-binary-path';
@@ -45,10 +48,10 @@
/// Path to a built application to use in [test].
///
/// If not given, will default to child's expected location.
- String? applicationBinaryPath;
+ String applicationBinaryPath;
/// Where the test artifacts are stored, such as performance results.
- final Directory? workingDirectory;
+ final Directory workingDirectory;
/// Run Flutter build to create [applicationBinaryPath].
Future<void> build() async {
@@ -90,7 +93,7 @@
///
/// Tasks can override to support default values. Otherwise, it will default
/// to needing to be passed as an argument in the test runner.
- String? getApplicationBinaryPath() => applicationBinaryPath;
+ String getApplicationBinaryPath() => applicationBinaryPath;
/// Run this task.
///
diff --git a/dev/devicelab/lib/tasks/dart_plugin_registry_tests.dart b/dev/devicelab/lib/tasks/dart_plugin_registry_tests.dart
index c3ee1a8..253cff5 100644
--- a/dev/devicelab/lib/tasks/dart_plugin_registry_tests.dart
+++ b/dev/devicelab/lib/tasks/dart_plugin_registry_tests.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@@ -13,8 +15,8 @@
import 'package:path/path.dart' as path;
TaskFunction dartPluginRegistryTest({
- String? deviceIdOverride,
- Map<String, String>? environment,
+ String deviceIdOverride,
+ Map<String, String> environment,
}) {
final Directory tempDir = Directory.systemTemp
.createTempSync('flutter_devicelab_dart_plugin_test.');
diff --git a/dev/devicelab/lib/tasks/gallery.dart b/dev/devicelab/lib/tasks/gallery.dart
index 08d0851..0be7bd4 100644
--- a/dev/devicelab/lib/tasks/gallery.dart
+++ b/dev/devicelab/lib/tasks/gallery.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:convert';
import 'dart:io';
import 'dart:math' as math;
@@ -53,9 +55,9 @@
final bool needFullTimeline;
final String testFile;
final String timelineSummaryFile;
- final String? timelineTraceFile;
- final String? transitionDurationFile;
- final String? driverFile;
+ final String timelineTraceFile;
+ final String transitionDurationFile;
+ final String driverFile;
Future<TaskResult> call() async {
final Device device = await devices.workingDevice;
@@ -63,7 +65,7 @@
final String deviceId = device.deviceId;
final Directory galleryDirectory = dir('${flutterDirectory.path}/dev/integration_tests/flutter_gallery');
await inDirectory<void>(galleryDirectory, () async {
- String? applicationBinaryPath;
+ String applicationBinaryPath;
if (deviceOperatingSystem == DeviceOperatingSystem.android) {
section('BUILDING APPLICATION');
await flutter(
diff --git a/dev/devicelab/lib/tasks/hot_mode_tests.dart b/dev/devicelab/lib/tasks/hot_mode_tests.dart
index 21fb730..ca9eb43 100644
--- a/dev/devicelab/lib/tasks/hot_mode_tests.dart
+++ b/dev/devicelab/lib/tasks/hot_mode_tests.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@@ -18,7 +20,7 @@
const String kSourceLine = 'fontSize: (orientation == Orientation.portrait) ? 32.0 : 24.0';
const String kReplacementLine = 'fontSize: (orientation == Orientation.portrait) ? 34.0 : 24.0';
-TaskFunction createHotModeTest({String? deviceIdOverride, Map<String, String>? environment}) {
+TaskFunction createHotModeTest({String deviceIdOverride, Map<String, String> environment}) {
// This file is modified during the test and needs to be restored at the end.
final File flutterFrameworkSource = file(path.join(
flutterDirectory.path, 'packages/flutter/lib/src/widgets/framework.dart',
@@ -33,13 +35,13 @@
final File benchmarkFile = file(path.join(_editedFlutterGalleryDir.path, 'hot_benchmark.json'));
rm(benchmarkFile);
final List<String> options = <String>[
- '--hot', '-d', deviceIdOverride!, '--benchmark', '--resident', '--no-android-gradle-daemon', '--no-publish-port', '--verbose',
+ '--hot', '-d', deviceIdOverride, '--benchmark', '--resident', '--no-android-gradle-daemon', '--no-publish-port', '--verbose',
];
int hotReloadCount = 0;
- late Map<String, dynamic> smallReloadData;
- late Map<String, dynamic> mediumReloadData;
- late Map<String, dynamic> largeReloadData;
- late Map<String, dynamic> freshRestartReloadsData;
+ Map<String, dynamic> smallReloadData;
+ Map<String, dynamic> mediumReloadData;
+ Map<String, dynamic> largeReloadData;
+ Map<String, dynamic> freshRestartReloadsData;
await inDirectory<void>(flutterDirectory, () async {
@@ -215,7 +217,7 @@
Future<Map<String, Object>> captureReloadData(
List<String> options,
- Map<String, String>? environment,
+ Map<String, String> environment,
File benchmarkFile,
void Function(String, Process) onLine,
) async {
@@ -245,7 +247,7 @@
await Future.wait<void>(<Future<void>>[stdoutDone.future, stderrDone.future]);
await process.exitCode;
- final Map<String, Object> result = json.decode(benchmarkFile.readAsStringSync()) as Map<String, Object>;
+ final Map<String, dynamic> result = json.decode(benchmarkFile.readAsStringSync()) as Map<String, dynamic>;
benchmarkFile.deleteSync();
return result;
}
diff --git a/dev/devicelab/lib/tasks/integration_tests.dart b/dev/devicelab/lib/tasks/integration_tests.dart
index 7a8f783..7408538 100644
--- a/dev/devicelab/lib/tasks/integration_tests.dart
+++ b/dev/devicelab/lib/tasks/integration_tests.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import '../framework/devices.dart';
import '../framework/framework.dart';
import '../framework/task_result.dart';
diff --git a/dev/devicelab/lib/tasks/microbenchmarks.dart b/dev/devicelab/lib/tasks/microbenchmarks.dart
index 957ab4c..91a6a0a 100644
--- a/dev/devicelab/lib/tasks/microbenchmarks.dart
+++ b/dev/devicelab/lib/tasks/microbenchmarks.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:io';
diff --git a/dev/devicelab/lib/tasks/new_gallery.dart b/dev/devicelab/lib/tasks/new_gallery.dart
index ee53732..afe69a1 100644
--- a/dev/devicelab/lib/tasks/new_gallery.dart
+++ b/dev/devicelab/lib/tasks/new_gallery.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:io';
import 'package:flutter_devicelab/tasks/perf_tests.dart';
diff --git a/dev/devicelab/lib/tasks/perf_tests.dart b/dev/devicelab/lib/tasks/perf_tests.dart
index 7fd1840..e7235ed 100644
--- a/dev/devicelab/lib/tasks/perf_tests.dart
+++ b/dev/devicelab/lib/tasks/perf_tests.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert' show LineSplitter, json, utf8;
import 'dart:io';
@@ -514,7 +516,7 @@
final List<Map<String, dynamic>> results = <Map<String, dynamic>>[];
section('Building application');
- String? applicationBinaryPath;
+ String applicationBinaryPath;
switch (deviceOperatingSystem) {
case DeviceOperatingSystem.android:
await flutter('build', options: <String>[
@@ -584,7 +586,7 @@
'-d',
device.deviceId,
'--out',
- hostAgent.dumpDirectory!
+ hostAgent.dumpDirectory
.childFile('screenshot_startup_failure_$currentFailures.png')
.path,
],
@@ -628,7 +630,7 @@
final Device device = await devices.workingDevice;
section('Building application');
- String? applicationBinaryPath;
+ String applicationBinaryPath;
switch (deviceOperatingSystem) {
case DeviceOperatingSystem.android:
await flutter('build', options: <String>[
@@ -731,7 +733,7 @@
this.needsFullTimeline = true,
this.benchmarkScoreKeys,
this.dartDefine = '',
- String? resultFilename,
+ String resultFilename,
}): _resultFilename = resultFilename;
const PerfTest.e2e(
@@ -751,12 +753,12 @@
/// The main entry-point file of the application, as run on the device.
final String testTarget;
// The prefix name of the filename such as `<timelineFileName>.timeline_summary.json`.
- final String? timelineFileName;
+ final String timelineFileName;
String get traceFilename => '$timelineFileName.timeline';
String get resultFilename => _resultFilename ?? '$timelineFileName.timeline_summary';
- final String? _resultFilename;
+ final String _resultFilename;
/// The test file to run on the host.
- final String? testDriver;
+ final String testDriver;
/// Whether to collect CPU and GPU metrics.
final bool measureCpuGpu;
/// Whether to collect memory metrics.
@@ -786,7 +788,7 @@
/// if (measureCpuGpu) 'average_gpu_usage',
/// ]
/// ```
- final List<String>? benchmarkScoreKeys;
+ final List<String> benchmarkScoreKeys;
/// Additional flags for `--dart-define` to control the test
final String dartDefine;
@@ -798,8 +800,8 @@
@protected
Future<TaskResult> internalRun({
bool cacheSkSL = false,
- String? existingApp,
- String? writeSkslFileName,
+ String existingApp,
+ String writeSkslFileName,
}) {
return inDirectory<TaskResult>(testDirectory, () async {
final Device device = await devices.workingDevice;
@@ -816,7 +818,7 @@
'--trace-startup', // Enables "endless" timeline event buffering.
'-t', testTarget,
if (testDriver != null)
- ...<String>['--driver', testDriver!],
+ ...<String>['--driver', testDriver],
if (existingApp != null)
...<String>['--use-existing-app', existingApp],
if (writeSkslFileName != null)
@@ -888,9 +890,9 @@
String testTarget,
String timelineFileName, {
bool measureCpuGpu = false,
- String? testDriver,
+ String testDriver,
bool needsFullTimeline = true,
- List<String>? benchmarkScoreKeys,
+ List<String> benchmarkScoreKeys,
}) : super(
testDirectory,
testTarget,
@@ -962,7 +964,7 @@
);
}
- Future<String> _runApp({String? appBinary, bool cacheSkSL = false, String? skslPath}) async {
+ Future<String> _runApp({String appBinary, bool cacheSkSL = false, String skslPath}) async {
if (File(_vmserviceFileName).existsSync()) {
File(_vmserviceFileName).deleteSync();
}
@@ -1025,9 +1027,9 @@
});
}
- late String _flutterPath;
- late Device _device;
- late Process _runProcess;
+ String _flutterPath;
+ Device _device;
+ Process _runProcess;
static const String _kVmserviceOutFileName = 'vmservice.out';
}
@@ -1071,16 +1073,12 @@
///
/// Run a single web compile test for the app under [directory], and store
/// its metrics with prefix [metric].
- static Future<Map<String, int>> runSingleBuildTest({
- required String directory,
- required String metric,
- bool measureBuildTime = false,
- }) {
+ static Future<Map<String, int>> runSingleBuildTest({String directory, String metric, bool measureBuildTime = false}) {
return inDirectory<Map<String, int>>(directory, () async {
final Map<String, int> metrics = <String, int>{};
await flutter('packages', options: <String>['get']);
- final Stopwatch? watch = measureBuildTime ? Stopwatch() : null;
+ final Stopwatch watch = measureBuildTime ? Stopwatch() : null;
watch?.start();
await evalFlutter('build', options: <String>[
'web',
@@ -1093,7 +1091,7 @@
metrics.addAll(await getSize(outputFileName, metric: metric));
if (measureBuildTime) {
- metrics['${metric}_dart2js_millis'] = watch!.elapsedMilliseconds;
+ metrics['${metric}_dart2js_millis'] = watch.elapsedMilliseconds;
}
return metrics;
@@ -1101,7 +1099,7 @@
}
/// Obtains the size and gzipped size of a file given by [fileName].
- static Future<Map<String, int>> getSize(String fileName, {required String metric}) async {
+ static Future<Map<String, int>> getSize(String fileName, {String metric}) async {
final Map<String, int> sizeMetrics = <String, int>{};
final ProcessResult result = await Process.run('du', <String>['-k', fileName]);
@@ -1170,12 +1168,10 @@
await flutter('build', options: options);
watch.stop();
final Directory appBuildDirectory = dir(path.join(cwd, 'build/ios/Release-iphoneos'));
- final Directory? appBundle = appBuildDirectory
+ final Directory appBundle = appBuildDirectory
.listSync()
- .whereType<Directory?>()
- .singleWhere((Directory? directory) =>
- directory != null && path.extension(directory.path) == '.app',
- orElse: () => null);
+ .whereType<Directory>()
+ .singleWhere((Directory directory) => path.extension(directory.path) == '.app', orElse: () => null);
if (appBundle == null) {
throw 'Failed to find app bundle in ${appBuildDirectory.path}';
}
@@ -1230,8 +1226,8 @@
}
static Future<Map<String, dynamic>> _compileDebug({
- required bool clean,
- required String metricKey,
+ @required bool clean,
+ @required String metricKey,
}) async {
if (clean) {
await flutter('clean');
@@ -1294,9 +1290,9 @@
fileToMetadata[entry.path] = entry;
}
- final _UnzipListEntry libflutter = fileToMetadata['lib/armeabi-v7a/libflutter.so']!;
- final _UnzipListEntry libapp = fileToMetadata['lib/armeabi-v7a/libapp.so']!;
- final _UnzipListEntry license = fileToMetadata['assets/flutter_assets/NOTICES.Z']!;
+ final _UnzipListEntry libflutter = fileToMetadata['lib/armeabi-v7a/libflutter.so'];
+ final _UnzipListEntry libapp = fileToMetadata['lib/armeabi-v7a/libapp.so'];
+ final _UnzipListEntry license = fileToMetadata['assets/flutter_assets/NOTICES.Z'];
return <String, dynamic>{
'libflutter_uncompressed_bytes': libflutter.uncompressedSize,
@@ -1319,9 +1315,9 @@
/// Completes when the log line specified in the last call to
/// [prepareForNextMessage] is seen by `adb logcat`.
- Future<void>? get receivedNextMessage => _receivedNextMessage?.future;
- Completer<void>? _receivedNextMessage;
- String? _nextMessage;
+ Future<void> get receivedNextMessage => _receivedNextMessage?.future;
+ Completer<void> _receivedNextMessage;
+ String _nextMessage;
/// Prepares the [receivedNextMessage] future such that it will complete
/// when `adb logcat` sees a log line with the given `message`.
@@ -1332,8 +1328,8 @@
int get iterationCount => 10;
- Device? get device => _device;
- Device? _device;
+ Device get device => _device;
+ Device _device;
Future<TaskResult> run() {
return inDirectory<TaskResult>(project, () async {
@@ -1341,13 +1337,13 @@
// device.getMemoryStats, etc, aren't implemented for iOS.
_device = await devices.workingDevice;
- await device!.unlock();
+ await device.unlock();
await flutter('packages', options: <String>['get']);
- final StreamSubscription<String> adb = device!.logcat.listen(
+ final StreamSubscription<String> adb = device.logcat.listen(
(String data) {
if (data.contains('==== MEMORY BENCHMARK ==== $_nextMessage ===='))
- _receivedNextMessage?.complete();
+ _receivedNextMessage.complete();
},
);
@@ -1360,12 +1356,12 @@
assert(_endMemory.length == iteration + 1);
assert(_diffMemory.length == iteration + 1);
print('terminating...');
- await device!.stop(package);
+ await device.stop(package);
await Future<void>.delayed(const Duration(milliseconds: 10));
}
await adb.cancel();
- await flutter('install', options: <String>['--uninstall-only', '-d', device!.deviceId]);
+ await flutter('install', options: <String>['--uninstall-only', '-d', device.deviceId]);
final ListStatistics startMemoryStatistics = ListStatistics(_startMemory);
final ListStatistics endMemoryStatistics = ListStatistics(_endMemory);
@@ -1396,7 +1392,7 @@
'--verbose',
'--release',
'--no-resident',
- '-d', device!.deviceId,
+ '-d', device.deviceId,
test,
]);
print('awaiting "ready" message...');
@@ -1415,7 +1411,7 @@
prepareForNextMessage('DONE');
print('tapping device...');
- await device!.tap(100, 100);
+ await device.tap(100, 100);
print('awaiting "done" message...');
await receivedNextMessage;
@@ -1426,23 +1422,23 @@
final List<int> _endMemory = <int>[];
final List<int> _diffMemory = <int>[];
- Map<String, dynamic>? _startMemoryUsage;
+ Map<String, dynamic> _startMemoryUsage;
@protected
Future<void> recordStart() async {
assert(_startMemoryUsage == null);
print('snapshotting memory usage...');
- _startMemoryUsage = await device!.getMemoryStats(package);
+ _startMemoryUsage = await device.getMemoryStats(package);
}
@protected
Future<void> recordEnd() async {
assert(_startMemoryUsage != null);
print('snapshotting memory usage...');
- final Map<String, dynamic> endMemoryUsage = await device!.getMemoryStats(package);
- _startMemory.add(_startMemoryUsage!['total_kb'] as int);
+ final Map<String, dynamic> endMemoryUsage = await device.getMemoryStats(package);
+ _startMemory.add(_startMemoryUsage['total_kb'] as int);
_endMemory.add(endMemoryUsage['total_kb'] as int);
- _diffMemory.add((endMemoryUsage['total_kb'] as int) - (_startMemoryUsage!['total_kb'] as int));
+ _diffMemory.add((endMemoryUsage['total_kb'] as int) - (_startMemoryUsage['total_kb'] as int));
}
}
@@ -1491,7 +1487,7 @@
});
}
- late Device _device;
+ Device _device;
static const String _kJsonFileName = 'devtools_memory.json';
}
@@ -1509,6 +1505,7 @@
case ReportedDurationTestFlavor.release:
return 'release';
}
+ throw ArgumentError('Unexpected value for enum $flavor');
}
class ReportedDurationTest {
@@ -1524,8 +1521,8 @@
int get iterationCount => 10;
- Device? get device => _device;
- Device? _device;
+ Device get device => _device;
+ Device _device;
Future<TaskResult> run() {
return inDirectory<TaskResult>(project, () async {
@@ -1533,13 +1530,13 @@
// device.getMemoryStats, etc, aren't implemented for iOS.
_device = await devices.workingDevice;
- await device!.unlock();
+ await device.unlock();
await flutter('packages', options: <String>['get']);
- final StreamSubscription<String> adb = device!.logcat.listen(
+ final StreamSubscription<String> adb = device.logcat.listen(
(String data) {
if (durationPattern.hasMatch(data))
- durationCompleter.complete(int.parse(durationPattern.firstMatch(data)!.group(1)!));
+ durationCompleter.complete(int.parse(durationPattern.firstMatch(data).group(1)));
},
);
print('launching $project$test on device...');
@@ -1549,13 +1546,13 @@
'--no-fast-start',
'--${_reportedDurationTestToString(flavor)}',
'--no-resident',
- '-d', device!.deviceId,
+ '-d', device.deviceId,
test,
]);
final int duration = await durationCompleter.future;
print('terminating...');
- await device!.stop(package);
+ await device.stop(package);
await adb.cancel();
_device = null;
@@ -1610,9 +1607,9 @@
}
_UnzipListEntry._({
- required this.uncompressedSize,
- required this.compressedSize,
- required this.path,
+ @required this.uncompressedSize,
+ @required this.compressedSize,
+ @required this.path,
}) : assert(uncompressedSize != null),
assert(compressedSize != null),
assert(compressedSize <= uncompressedSize),
@@ -1636,7 +1633,7 @@
throw StateError('Did not find vmservice out file after 400 seconds');
}
-String? _findIosAppInBuildDirectory(String searchDirectory) {
+String _findIosAppInBuildDirectory(String searchDirectory) {
for (final FileSystemEntity entity in Directory(searchDirectory).listSync()) {
if (entity.path.endsWith('.app')) {
return entity.path;
diff --git a/dev/devicelab/lib/tasks/platform_channels_benchmarks.dart b/dev/devicelab/lib/tasks/platform_channels_benchmarks.dart
index 767e888..361d050 100644
--- a/dev/devicelab/lib/tasks/platform_channels_benchmarks.dart
+++ b/dev/devicelab/lib/tasks/platform_channels_benchmarks.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:io' show Process, Directory;
import 'package:flutter_devicelab/framework/devices.dart' as adb;
diff --git a/dev/devicelab/lib/tasks/plugin_tests.dart b/dev/devicelab/lib/tasks/plugin_tests.dart
index 445b40f..47875f8 100644
--- a/dev/devicelab/lib/tasks/plugin_tests.dart
+++ b/dev/devicelab/lib/tasks/plugin_tests.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:io';
import 'package:flutter_devicelab/framework/framework.dart';
@@ -29,8 +31,8 @@
final String buildTarget;
final List<String> options;
- final Map<String, String>? pluginCreateEnvironment;
- final Map<String, String>? appCreateEnvironment;
+ final Map<String, String> pluginCreateEnvironment;
+ final Map<String, String> appCreateEnvironment;
Future<TaskResult> call() async {
final Directory tempDir =
@@ -75,7 +77,7 @@
String get rootPath => path.join(parent.path, name);
- Future<void> addPlugin(String plugin, {String? pluginPath}) async {
+ Future<void> addPlugin(String plugin, {String pluginPath}) async {
final File pubspec = File(path.join(rootPath, 'pubspec.yaml'));
String content = await pubspec.readAsString();
final String dependency =
@@ -98,9 +100,9 @@
List<String> options,
String target,
{
- required String name,
- required String template,
- Map<String, String>? environment,
+ String name,
+ String template,
+ Map<String, String> environment,
}) async {
await inDirectory(directory, () async {
await flutter(
diff --git a/dev/devicelab/lib/tasks/web_benchmarks.dart b/dev/devicelab/lib/tasks/web_benchmarks.dart
index cdafead..77af15d 100644
--- a/dev/devicelab/lib/tasks/web_benchmarks.dart
+++ b/dev/devicelab/lib/tasks/web_benchmarks.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert' show json;
import 'dart:io' as io;
@@ -11,6 +13,7 @@
import 'package:flutter_devicelab/framework/task_result.dart';
import 'package:flutter_devicelab/framework/utils.dart';
import 'package:logging/logging.dart';
+import 'package:meta/meta.dart';
import 'package:path/path.dart' as path;
import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
@@ -20,7 +23,7 @@
const int benchmarkServerPort = 9999;
const int chromeDebugPort = 10000;
-Future<TaskResult> runWebBenchmark({ required bool useCanvasKit }) async {
+Future<TaskResult> runWebBenchmark({ @required bool useCanvasKit }) async {
// Reduce logging level. Otherwise, package:webkit_inspection_protocol is way too spammy.
Logger.root.level = Level.INFO;
final String macrobenchmarksDirectory = path.join(flutterDirectory.path, 'dev', 'benchmarks', 'macrobenchmarks');
@@ -35,17 +38,17 @@
]);
final Completer<List<Map<String, dynamic>>> profileData = Completer<List<Map<String, dynamic>>>();
final List<Map<String, dynamic>> collectedProfiles = <Map<String, dynamic>>[];
- List<String>? benchmarks;
- late Iterator<String> benchmarkIterator;
+ List<String> benchmarks;
+ Iterator<String> benchmarkIterator;
// This future fixes a race condition between the web-page loading and
// asking to run a benchmark, and us connecting to Chrome's DevTools port.
// Sometime one wins. Other times, the other wins.
- Future<Chrome>? whenChromeIsReady;
- Chrome? chrome;
- late io.HttpServer server;
+ Future<Chrome> whenChromeIsReady;
+ Chrome chrome;
+ io.HttpServer server;
Cascade cascade = Cascade();
- List<Map<String, dynamic>>? latestPerformanceTrace;
+ List<Map<String, dynamic>> latestPerformanceTrace;
cascade = cascade.add((Request request) async {
try {
chrome ??= await whenChromeIsReady;
@@ -63,7 +66,7 @@
// Trace data is null when the benchmark is not frame-based, such as RawRecorder.
if (latestPerformanceTrace != null) {
- final BlinkTraceSummary traceSummary = BlinkTraceSummary.fromJson(latestPerformanceTrace!)!;
+ final BlinkTraceSummary traceSummary = BlinkTraceSummary.fromJson(latestPerformanceTrace);
profile['totalUiFrame.average'] = traceSummary.averageTotalUIFrameTime.inMicroseconds;
profile['scoreKeys'] ??= <dynamic>[]; // using dynamic for consistency with JSON
(profile['scoreKeys'] as List<dynamic>).add('totalUiFrame.average');
@@ -73,10 +76,10 @@
return Response.ok('Profile received');
} else if (request.requestedUri.path.endsWith('/start-performance-tracing')) {
latestPerformanceTrace = null;
- await chrome!.beginRecordingPerformance(request.requestedUri.queryParameters['label']!);
+ await chrome.beginRecordingPerformance(request.requestedUri.queryParameters['label']);
return Response.ok('Started performance tracing');
} else if (request.requestedUri.path.endsWith('/stop-performance-tracing')) {
- latestPerformanceTrace = await chrome!.endRecordingPerformance();
+ latestPerformanceTrace = await chrome.endRecordingPerformance();
return Response.ok('Stopped performance tracing');
} else if (request.requestedUri.path.endsWith('/on-error')) {
final Map<String, dynamic> errorDetails = json.decode(await request.readAsString()) as Map<String, dynamic>;
@@ -87,7 +90,7 @@
} else if (request.requestedUri.path.endsWith('/next-benchmark')) {
if (benchmarks == null) {
benchmarks = (json.decode(await request.readAsString()) as List<dynamic>).cast<String>();
- benchmarkIterator = benchmarks!.iterator;
+ benchmarkIterator = benchmarks.iterator;
}
if (benchmarkIterator.moveNext()) {
final String nextBenchmark = benchmarkIterator.current;
@@ -183,7 +186,7 @@
}
return TaskResult.success(taskResult, benchmarkScoreKeys: benchmarkScoreKeys);
} finally {
- unawaited(server.close());
+ unawaited(server?.close());
chrome?.stop();
}
});
diff --git a/dev/devicelab/lib/tasks/web_dev_mode_tests.dart b/dev/devicelab/lib/tasks/web_dev_mode_tests.dart
index 22aa5ad..6164328 100644
--- a/dev/devicelab/lib/tasks/web_dev_mode_tests.dart
+++ b/dev/devicelab/lib/tasks/web_dev_mode_tests.dart
@@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// @dart = 2.8
+
import 'dart:async';
import 'dart:convert';
import 'dart:io';