From 3c8ebf105a8f1e9b369b75f8106c71c70c532645 Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Tue, 25 Oct 2022 05:31:48 -0700 Subject: [PATCH] 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 --- .../src/devices/android/AndroidDevice.tsx | 78 +++++++++++++++---- 1 file changed, 65 insertions(+), 13 deletions(-) diff --git a/desktop/flipper-server-core/src/devices/android/AndroidDevice.tsx b/desktop/flipper-server-core/src/devices/android/AndroidDevice.tsx index e5283dd9a..ba8a681cd 100644 --- a/desktop/flipper-server-core/src/devices/android/AndroidDevice.tsx +++ b/desktop/flipper-server-core/src/devices/android/AndroidDevice.tsx @@ -19,7 +19,7 @@ import {FlipperServerImpl} from '../../FlipperServerImpl'; import {AndroidCrashWatcher} from './AndroidCrashUtils'; import {AndroidLogListener} from './AndroidLogListener'; import {DebuggableDevice} from '../DebuggableDevice'; -import {executeCommandAsApp} from './androidContainerUtility'; +import {executeCommandAsApp, pull} from './androidContainerUtility'; const DEVICE_RECORDING_DIR = '/sdcard/flipper_recorder'; @@ -297,7 +297,7 @@ export default class AndroidDevice const appIds = output .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. .filter((appId) => appId !== '') // Cut off the "package:" prefix @@ -309,18 +309,66 @@ export default class AndroidDevice ); const appsCommandsResults = await Promise.all( - appIds.map(async (appId): Promise => { + appIds.map(async (appId): Promise => { + const sonarDirFileNames = await 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.info.serial, + appId, + `ls -al /data/data/${appId}/files/sonar`, + ).then((output): DeviceDebugData['data'][0] => ({ + command: `ls -al /data/data/${appId}/files/sonar`, + result: output, + })); + const singleAppCommandResults = await Promise.all([ - executeCommandAsApp( - this.adb, - this.info.serial, - appId, - `ls -al /data/data/${appId}/files/sonar`, - ).then((output): DeviceDebugData['data'][0] => ({ - command: `ls -al /data/data/${appId}/files/sonar`, - result: output, - })), + sonarDirContentWithStatsCommandPromise, + ...sonarDirContentPromises, ]); + return { serial: this.info.serial, 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) + ); } }