@@ -47,48 +47,52 @@ void main(List<String> args) async {
47
47
..addOption (
48
48
'adb' ,
49
49
help: 'Path to the adb tool' ,
50
- defaultsTo: engine != null ? join (
51
- engine.srcDir.path,
52
- 'third_party' ,
53
- 'android_tools' ,
54
- 'sdk' ,
55
- 'platform-tools' ,
56
- 'adb' ,
57
- ) : null ,
50
+ defaultsTo: engine != null
51
+ ? join (
52
+ engine.srcDir.path,
53
+ 'third_party' ,
54
+ 'android_tools' ,
55
+ 'sdk' ,
56
+ 'platform-tools' ,
57
+ 'adb' ,
58
+ )
59
+ : null ,
58
60
)
59
61
..addOption (
60
62
'ndk-stack' ,
61
63
help: 'Path to the ndk-stack tool' ,
62
- defaultsTo: engine != null ? join (
63
- engine.srcDir.path,
64
- 'third_party' ,
65
- 'android_tools' ,
66
- 'ndk' ,
67
- 'prebuilt' ,
68
- () {
69
- if (Platform .isLinux) {
70
- return 'linux-x86_64' ;
71
- } else if (Platform .isMacOS) {
72
- return 'darwin-x86_64' ;
73
- } else if (Platform .isWindows) {
74
- return 'windows-x86_64' ;
75
- } else {
76
- throw UnsupportedError ('Unsupported platform: ${Platform .operatingSystem }' );
77
- }
78
- }(),
79
- 'bin' ,
80
- 'ndk-stack' ,
81
- ) : null ,
64
+ defaultsTo: engine != null
65
+ ? join (
66
+ engine.srcDir.path,
67
+ 'third_party' ,
68
+ 'android_tools' ,
69
+ 'ndk' ,
70
+ 'prebuilt' ,
71
+ () {
72
+ if (Platform .isLinux) {
73
+ return 'linux-x86_64' ;
74
+ } else if (Platform .isMacOS) {
75
+ return 'darwin-x86_64' ;
76
+ } else if (Platform .isWindows) {
77
+ return 'windows-x86_64' ;
78
+ } else {
79
+ throw UnsupportedError ('Unsupported platform: ${Platform .operatingSystem }' );
80
+ }
81
+ }(),
82
+ 'bin' ,
83
+ 'ndk-stack' ,
84
+ )
85
+ : null ,
82
86
)
83
87
..addOption (
84
88
'out-dir' ,
85
89
help: 'Out directory' ,
86
- defaultsTo:
87
- engine ? .
88
- outputs ().
89
- where (( Output o) => basename (o.path.path). startsWith ( 'android_' )).
90
- firstOrNull ? .
91
- path .path,
90
+ defaultsTo: engine
91
+ ? . outputs ()
92
+ . where (( Output o) => basename (o.path.path). startsWith ( 'android_' ))
93
+ .firstOrNull
94
+ ? .path
95
+ .path,
92
96
)
93
97
..addOption (
94
98
'smoke-test' ,
@@ -106,14 +110,16 @@ void main(List<String> args) async {
106
110
..addOption (
107
111
'output-contents-golden' ,
108
112
help: 'Path to a file that contains the expected filenames of golden files.' ,
109
- defaultsTo: engine != null ? join (
110
- engine.srcDir.path,
111
- 'flutter' ,
112
- 'testing' ,
113
- 'scenario_app' ,
114
- 'android' ,
115
- 'expected_golden_output.txt' ,
116
- ) : null ,
113
+ defaultsTo: engine != null
114
+ ? join (
115
+ engine.srcDir.path,
116
+ 'flutter' ,
117
+ 'testing' ,
118
+ 'scenario_app' ,
119
+ 'android' ,
120
+ 'expected_golden_output.txt' ,
121
+ )
122
+ : null ,
117
123
)
118
124
..addOption (
119
125
'impeller-backend' ,
@@ -124,8 +130,8 @@ void main(List<String> args) async {
124
130
..addOption (
125
131
'logs-dir' ,
126
132
help: 'The directory to store the logs and screenshots. Defaults to '
127
- 'the value of the FLUTTER_LOGS_DIR environment variable, if set, '
128
- 'otherwise it defaults to a path within out-dir.' ,
133
+ 'the value of the FLUTTER_LOGS_DIR environment variable, if set, '
134
+ 'otherwise it defaults to a path within out-dir.' ,
129
135
defaultsTo: Platform .environment['FLUTTER_LOGS_DIR' ],
130
136
);
131
137
@@ -153,7 +159,10 @@ void main(List<String> args) async {
153
159
final String ? contentsGolden = results['output-contents-golden' ] as String ? ;
154
160
final _ImpellerBackend ? impellerBackend = _ImpellerBackend .tryParse (results['impeller-backend' ] as String ? );
155
161
if (enableImpeller && impellerBackend == null ) {
156
- panic (< String > ['invalid graphics-backend' , results['impeller-backend' ] as String ? ?? '<null>' ]);
162
+ panic (< String > [
163
+ 'invalid graphics-backend' ,
164
+ results['impeller-backend' ] as String ? ?? '<null>'
165
+ ]);
157
166
}
158
167
final Directory logsDir = Directory (results['logs-dir' ] as String ? ?? join (outDir.path, 'scenario_app' , 'logs' ));
159
168
final String ? ndkStack = results['ndk-stack' ] as String ? ;
@@ -215,7 +224,10 @@ Future<void> _run({
215
224
const ProcessManager pm = LocalProcessManager ();
216
225
217
226
if (! outDir.existsSync ()) {
218
- panic (< String > ['out-dir does not exist: $outDir ' , 'make sure to build the selected engine variant' ]);
227
+ panic (< String > [
228
+ 'out-dir does not exist: $outDir ' ,
229
+ 'make sure to build the selected engine variant'
230
+ ]);
219
231
}
220
232
221
233
if (! adb.existsSync ()) {
@@ -236,19 +248,25 @@ Future<void> _run({
236
248
log ('writing logs and screenshots to ${logsDir .path }' );
237
249
238
250
if (! testApk.existsSync ()) {
239
- panic (< String > ['test apk does not exist: ${testApk .path }' , 'make sure to build the selected engine variant' ]);
251
+ panic (< String > [
252
+ 'test apk does not exist: ${testApk .path }' ,
253
+ 'make sure to build the selected engine variant'
254
+ ]);
240
255
}
241
256
242
257
if (! appApk.existsSync ()) {
243
- panic (< String > ['app apk does not exist: ${appApk .path }' , 'make sure to build the selected engine variant' ]);
258
+ panic (< String > [
259
+ 'app apk does not exist: ${appApk .path }' ,
260
+ 'make sure to build the selected engine variant'
261
+ ]);
244
262
}
245
263
246
264
// Start a TCP socket in the host, and forward it to the device that runs the tests.
247
265
// This allows the test process to start a connection with the host, and write the bytes
248
266
// for the screenshots.
249
267
// On LUCI, the host uploads the screenshots to Skia Gold.
250
268
SkiaGoldClient ? skiaGoldClient;
251
- late ServerSocket server;
269
+ late ServerSocket server;
252
270
final List <Future <void >> pendingComparisons = < Future <void >> [];
253
271
await step ('Starting server...' , () async {
254
272
server = await ServerSocket .bind (InternetAddress .anyIPv4, _tcpPort);
@@ -259,7 +277,8 @@ Future<void> _run({
259
277
if (verbose) {
260
278
stdout.writeln ('client connected ${client .remoteAddress .address }:${client .remotePort }' );
261
279
}
262
- client.transform (const ScreenshotBlobTransformer ()).listen ((Screenshot screenshot) {
280
+ client.transform (const ScreenshotBlobTransformer ()).listen (
281
+ (Screenshot screenshot) {
263
282
final String fileName = screenshot.filename;
264
283
final Uint8List fileContent = screenshot.fileContent;
265
284
if (verbose) {
@@ -277,18 +296,15 @@ Future<void> _run({
277
296
}
278
297
if (isSkiaGoldClientAvailable) {
279
298
final Future <void > comparison = skiaGoldClient!
280
- .addImg (fileName, goldenFile,
281
- screenshotSize: screenshot.pixelCount)
282
- .catchError ((dynamic err) {
283
- panic (< String > ['skia gold comparison failed: $err ' ]);
284
- });
299
+ .addImg (fileName, goldenFile, screenshotSize: screenshot.pixelCount)
300
+ .catchError ((dynamic err) {
301
+ panic (< String > ['skia gold comparison failed: $err ' ]);
302
+ });
285
303
pendingComparisons.add (comparison);
286
304
}
287
- },
288
- onError: (dynamic err) {
305
+ }, onError: (dynamic err) {
289
306
panic (< String > ['error while receiving bytes: $err ' ]);
290
- },
291
- cancelOnError: true );
307
+ }, cancelOnError: true );
292
308
});
293
309
});
294
310
@@ -311,27 +327,38 @@ Future<void> _run({
311
327
final (Future <int > logcatExitCode, Stream <String > logcatOutput) = getProcessStreams (logcatProcess);
312
328
313
329
logcatProcessExitCode = logcatExitCode;
330
+ String ? filterProcessId;
331
+
314
332
logcatOutput.listen ((String line) {
315
333
// Always write to the full log.
316
334
logcat.writeln (line);
317
335
318
336
// Conditionally parse and write to stderr.
319
337
final AdbLogLine ? adbLogLine = AdbLogLine .tryParse (line);
320
- switch (adbLogLine? .process) {
321
- case null :
322
- break ;
323
- case 'ActivityManager' :
324
- // These are mostly noise, i.e. "D ActivityManager: freezing 24632 com.blah".
325
- if (adbLogLine! .severity == 'D' ) {
326
- break ;
327
- }
328
- // TODO(matanlurey): Figure out why this isn't 'flutter.scenario' or similar.
329
- // Also, why is there two different names?
330
- case 'utter.scenario' :
331
- case 'utter.scenarios' :
332
- case 'flutter' :
333
- case 'FlutterJNI' :
334
- log ('[adb] $line ' );
338
+ if (verbose || adbLogLine == null ) {
339
+ log (line);
340
+ return ;
341
+ }
342
+
343
+ // If we haven't already found a process ID, try to find one.
344
+ // The process ID will help us filter out logs from other processes.
345
+ filterProcessId ?? = adbLogLine.tryParseProcess ();
346
+
347
+ // If this is a "verbose" log, possibly skip it.
348
+ final bool isVerbose = adbLogLine.isVerbose (filterProcessId: filterProcessId);
349
+ if (isVerbose || filterProcessId == null ) {
350
+ // We've requested verbose output, so print everything.
351
+ if (verbose) {
352
+ adbLogLine.printFormatted ();
353
+ }
354
+ return ;
355
+ }
356
+
357
+ // It's a non-verbose log, so print it.
358
+ adbLogLine.printFormatted ();
359
+ }, onError: (Object ? err) {
360
+ if (verbose) {
361
+ logWarning ('logcat stream error: $err ' );
335
362
}
336
363
});
337
364
});
@@ -364,10 +391,7 @@ Future<void> _run({
364
391
log ('using dimensions: ${json .encode (dimensions )}' );
365
392
skiaGoldClient = SkiaGoldClient (
366
393
outDir,
367
- dimensions: < String , String > {
368
- 'AndroidAPILevel' : connectedDeviceAPILevel,
369
- 'GraphicsBackend' : enableImpeller ? 'impeller-${impellerBackend !.name }' : 'skia' ,
370
- },
394
+ dimensions: dimensions,
371
395
);
372
396
});
373
397
@@ -412,11 +436,9 @@ Future<void> _run({
412
436
'am' ,
413
437
'instrument' ,
414
438
'-w' ,
415
- if (smokeTestFullPath != null )
416
- '-e class $smokeTestFullPath ' ,
439
+ if (smokeTestFullPath != null ) '-e class $smokeTestFullPath ' ,
417
440
'dev.flutter.scenarios.test/dev.flutter.TestRunner' ,
418
- if (enableImpeller)
419
- '-e enable-impeller' ,
441
+ if (enableImpeller) '-e enable-impeller' ,
420
442
if (impellerBackend != null )
421
443
'-e impeller-backend ${impellerBackend .name }' ,
422
444
]);
@@ -465,22 +487,25 @@ Future<void> _run({
465
487
final int exitCode = await pm.runAndForward (< String > [
466
488
adb.path,
467
489
'reverse' ,
468
- '--remove' , 'tcp:3000' ,
490
+ '--remove' ,
491
+ 'tcp:3000' ,
469
492
]);
470
493
if (exitCode != 0 ) {
471
494
panic (< String > ['could not unforward port' ]);
472
495
}
473
496
});
474
497
475
498
await step ('Uninstalling app APK...' , () async {
476
- final int exitCode = await pm.runAndForward (< String > [adb.path, 'uninstall' , 'dev.flutter.scenarios' ]);
499
+ final int exitCode = await pm.runAndForward (
500
+ < String > [adb.path, 'uninstall' , 'dev.flutter.scenarios' ]);
477
501
if (exitCode != 0 ) {
478
502
panic (< String > ['could not uninstall app apk' ]);
479
503
}
480
504
});
481
505
482
506
await step ('Uninstalling test APK...' , () async {
483
- final int exitCode = await pm.runAndForward (< String > [adb.path, 'uninstall' , 'dev.flutter.scenarios.test' ]);
507
+ final int exitCode = await pm.runAndForward (
508
+ < String > [adb.path, 'uninstall' , 'dev.flutter.scenarios.test' ]);
484
509
if (exitCode != 0 ) {
485
510
panic (< String > ['could not uninstall app apk' ]);
486
511
}
0 commit comments