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:
committed by
Facebook GitHub Bot
parent
480a3d26f0
commit
3c8ebf105a
@@ -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)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user