@@ -91,6 +91,7 @@ void main(List<String> args) async {
9191 ndkStack: options.ndkStack,
9292 forceSurfaceProducerSurfaceTexture: options.forceSurfaceProducerSurfaceTexture,
9393 prefixLogsPerRun: options.prefixLogsPerRun,
94+ recordScreen: options.recordScreen,
9495 );
9596 onSigint.cancel ();
9697 exit (0 );
@@ -135,6 +136,7 @@ Future<void> _run({
135136 required String ndkStack,
136137 required bool forceSurfaceProducerSurfaceTexture,
137138 required bool prefixLogsPerRun,
139+ required bool recordScreen,
138140}) async {
139141 const ProcessManager pm = LocalProcessManager ();
140142 final String scenarioAppPath = join (outDir.path, 'scenario_app' );
@@ -230,6 +232,7 @@ Future<void> _run({
230232 late Process logcatProcess;
231233 late Future <int > logcatProcessExitCode;
232234 _ImpellerBackend ? actualImpellerBackend;
235+ Process ? screenRecordProcess;
233236
234237 final IOSink logcat = File (logcatPath).openWrite ();
235238 try {
@@ -361,14 +364,44 @@ Future<void> _run({
361364 }
362365 });
363366
367+ if (recordScreen) {
368+ await step ('Recording screen...' , () async {
369+ // Create a /tmp directory on the device to store the screen recording.
370+ final int exitCode = await pm.runAndForward (< String > [
371+ adb.path,
372+ 'shell' ,
373+ 'mkdir' ,
374+ '-p' ,
375+ join (_emulatorStoragePath, 'tmp' ),
376+ ]);
377+ if (exitCode != 0 ) {
378+ panic (< String > ['could not create /tmp directory on device' ]);
379+ }
380+ final String screenRecordingPath = join (
381+ _emulatorStoragePath,
382+ 'tmp' ,
383+ 'screen.mp4' ,
384+ );
385+ screenRecordProcess = await pm.start (< String > [
386+ adb.path,
387+ 'shell' ,
388+ 'screenrecord' ,
389+ '--time-limit=0' ,
390+ '--bugreport' ,
391+ screenRecordingPath,
392+ ]);
393+ log ('writing screen recording to $screenRecordingPath ' );
394+ });
395+ }
396+
364397 await step ('Running instrumented tests...' , () async {
365398 final (int exitCode, StringBuffer out) = await pm.runAndCapture (< String > [
366399 adb.path,
367400 'shell' ,
368401 'am' ,
369402 'instrument' ,
370403 '-w' ,
371- '--no-window-animation' ,
404+ '--no-window-animation' ,
372405 if (smokeTestFullPath != null )
373406 '-e class $smokeTestFullPath ' ,
374407 if (enableImpeller)
@@ -447,6 +480,47 @@ Future<void> _run({
447480 }
448481 });
449482
483+ if (screenRecordProcess != null ) {
484+ await step ('Killing screen recording process...' , () async {
485+ // Kill the screen recording process.
486+ screenRecordProcess! .kill (ProcessSignal .sigkill);
487+ await screenRecordProcess! .exitCode;
488+
489+ // Pull the screen recording from the device.
490+ final String screenRecordingPath = join (
491+ _emulatorStoragePath,
492+ 'tmp' ,
493+ 'screen.mp4' ,
494+ );
495+ final String screenRecordingLocalPath = join (
496+ logsDir.path,
497+ 'screen.mp4' ,
498+ );
499+ final int exitCode = await pm.runAndForward (< String > [
500+ adb.path,
501+ 'pull' ,
502+ screenRecordingPath,
503+ screenRecordingLocalPath,
504+ ]);
505+ if (exitCode != 0 ) {
506+ logError ('could not pull screen recording from device' );
507+ }
508+
509+ log ('wrote screen recording to $screenRecordingLocalPath ' );
510+
511+ // Remove the screen recording from the device.
512+ final int removeExitCode = await pm.runAndForward (< String > [
513+ adb.path,
514+ 'shell' ,
515+ 'rm' ,
516+ screenRecordingPath,
517+ ]);
518+ if (removeExitCode != 0 ) {
519+ logError ('could not remove screen recording from device' );
520+ }
521+ });
522+ }
523+
450524 await step ('Killing logcat process...' , () async {
451525 final bool delivered = logcatProcess.kill (ProcessSignal .sigkill);
452526 assert (delivered);
@@ -536,6 +610,8 @@ Future<void> _run({
536610 }
537611}
538612
613+ const String _emulatorStoragePath = '/storage/emulated/0/Download' ;
614+
539615void _withTemporaryCwd (String path, void Function () callback) {
540616 final String originalCwd = Directory .current.path;
541617 Directory .current = Directory (path).path;
0 commit comments