Get files from Flipper folder for every app on an Android device

Summary:
Design doc: https://docs.google.com/document/d/1HLCFl46RfqG0o1mSt8SWrwf_HMfOCRg_oENioc1rkvQ/edit#

We'll make the fetching more resilient to errors in subsequent diffs

Reviewed By: passy

Differential Revision: D40512932

fbshipit-source-id: df3d2b14c033ec4434b2bf408f05734d71dee092
This commit is contained in:
Andrey Goncharov
2022-10-25 05:31:48 -07:00
committed by Facebook GitHub Bot
parent 480a3d26f0
commit 3c8ebf105a

View File

@@ -19,7 +19,7 @@ import {FlipperServerImpl} from '../../FlipperServerImpl';
import {AndroidCrashWatcher} from './AndroidCrashUtils'; import {AndroidCrashWatcher} from './AndroidCrashUtils';
import {AndroidLogListener} from './AndroidLogListener'; import {AndroidLogListener} from './AndroidLogListener';
import {DebuggableDevice} from '../DebuggableDevice'; import {DebuggableDevice} from '../DebuggableDevice';
import {executeCommandAsApp} from './androidContainerUtility'; import {executeCommandAsApp, pull} from './androidContainerUtility';
const DEVICE_RECORDING_DIR = '/sdcard/flipper_recorder'; const DEVICE_RECORDING_DIR = '/sdcard/flipper_recorder';
@@ -297,7 +297,7 @@ export default class AndroidDevice
const appIds = output const appIds = output
.split('\n') .split('\n')
// Last each appId has \n at the end. The last appId also has it. // Each appId has \n at the end. The last appId also has it.
// As a result, there is an "" (empty string) item at the end after the split. // As a result, there is an "" (empty string) item at the end after the split.
.filter((appId) => appId !== '') .filter((appId) => appId !== '')
// Cut off the "package:" prefix // Cut off the "package:" prefix
@@ -309,9 +309,52 @@ export default class AndroidDevice
); );
const appsCommandsResults = await Promise.all( const appsCommandsResults = await Promise.all(
appIds.map(async (appId): Promise<DeviceDebugData> => { appIds.map(async (appId): Promise<DeviceDebugData | undefined> => {
const singleAppCommandResults = await Promise.all([ const sonarDirFileNames = await executeCommandAsApp(
executeCommandAsApp( this.adb,
this.info.serial,
appId,
`find /data/data/${appId}/files/sonar -type f -printf "%f\n"`,
).then((output) => {
if (output.includes('No such file or directory')) {
console.debug(
'AndroidDevice.readFlipperFolderForAllApps -> skipping app because sonar dir does not exist',
this.info.serial,
appId,
);
return;
}
return (
output
.split('\n')
// Each entry has \n at the end. The last one also has it.
// As a result, there is an "" (empty string) item at the end after the split.
.filter((appId) => appId !== '')
);
});
if (!sonarDirFileNames) {
return;
}
const sonarDirContentPromises = sonarDirFileNames.map(
async (fileName) => {
const filePath = `/data/data/${appId}/files/sonar/${fileName}`;
if (fileName.endsWith('pem')) {
return {
path: filePath,
data: '===SECURE_CONTENT===',
};
}
return {
path: filePath,
data: await pull(this.adb, this.info.serial, appId, filePath),
};
},
);
const sonarDirContentWithStatsCommandPromise = executeCommandAsApp(
this.adb, this.adb,
this.info.serial, this.info.serial,
appId, appId,
@@ -319,8 +362,13 @@ export default class AndroidDevice
).then((output): DeviceDebugData['data'][0] => ({ ).then((output): DeviceDebugData['data'][0] => ({
command: `ls -al /data/data/${appId}/files/sonar`, command: `ls -al /data/data/${appId}/files/sonar`,
result: output, result: output,
})), }));
const singleAppCommandResults = await Promise.all([
sonarDirContentWithStatsCommandPromise,
...sonarDirContentPromises,
]); ]);
return { return {
serial: this.info.serial, serial: this.info.serial,
appId, appId,
@@ -329,7 +377,11 @@ export default class AndroidDevice
}), }),
); );
return appsCommandsResults; return (
appsCommandsResults
// Filter out apps without Flipper integration
.filter((res): res is DeviceDebugData => !!res)
);
} }
} }