Fix screen recording on Android

Summary:
There were two issues with the previous approach:

1) We didn't block the shell process, so we would immediately
    start pulling the video from the device as soon as we **started**
    recording it. This meant, you'd usually get the previous recording
    or just an empty file.
2) The stop side doesn't know when it's actually safe to start displaying
    the video as pulling takes time. So we need access to the process
    promise there.

Reviewed By: jknoxville

Differential Revision: D17687827

fbshipit-source-id: 6ad5da52442f1888dd491b2a4c7f7a6b5a7885dd
This commit is contained in:
Pascal Hartig
2019-10-01 10:41:42 -07:00
committed by Facebook Github Bot
parent 25cdca1d6f
commit c6d5b8ccb5

View File

@@ -59,7 +59,7 @@ export default class AndroidDevice extends BaseDevice {
adb: ADBClient;
pidAppMapping: {[key: number]: string} = {};
private recordingDestination?: string;
private recordingProcess?: Promise<string>;
supportedColumns(): Array<string> {
return ['date', 'pid', 'tid', 'tag', 'message', 'type', 'time'];
@@ -134,12 +134,12 @@ export default class AndroidDevice extends BaseDevice {
await this.executeShell(
`mkdir -p "${DEVICE_RECORDING_DIR}" && echo -n > "${DEVICE_RECORDING_DIR}/.nomedia"`,
);
this.recordingDestination = destination;
const recordingLocation = `${DEVICE_RECORDING_DIR}/video.mp4`;
this.adb
this.recordingProcess = this.adb
.shell(this.serial, `screenrecord --bugreport "${recordingLocation}"`)
.then(adb.util.readAll)
.then(
() =>
_ =>
new Promise((resolve, reject) =>
this.adb.pull(this.serial, recordingLocation).then(stream => {
stream.on('end', resolve);
@@ -147,16 +147,18 @@ export default class AndroidDevice extends BaseDevice {
stream.pipe(createWriteStream(destination));
}),
),
);
)
.then(_ => destination);
}
async stopScreenCapture(): Promise<string> {
const {recordingDestination} = this;
if (!recordingDestination) {
const {recordingProcess} = this;
if (!recordingProcess) {
return Promise.reject(new Error('Recording was not properly started'));
}
this.recordingDestination = undefined;
await this.adb.shell(this.serial, `pgrep 'screenrecord' -L 2`);
return recordingDestination;
const destination = await recordingProcess;
this.recordingProcess = undefined;
return destination;
}
}