Get files from Flipper folder for every app on an iOS device
Summary: Design doc: https://docs.google.com/document/d/1HLCFl46RfqG0o1mSt8SWrwf_HMfOCRg_oENioc1rkvQ/edit# Fetch list of files in the `/sonar` folder on iOS devices and fetch all the files Reviewed By: passy Differential Revision: D40548410 fbshipit-source-id: d38cbbb1e3b5579c13f30777233e3caf7b8c9b34
This commit is contained in:
committed by
Facebook GitHub Bot
parent
3c8ebf105a
commit
821bf2b5b7
@@ -7,15 +7,25 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {DeviceType, timeout} from 'flipper-common';
|
||||
import {DeviceDebugData, DeviceType, timeout} from 'flipper-common';
|
||||
import {ChildProcess} from 'child_process';
|
||||
import {IOSBridge} from './IOSBridge';
|
||||
import {ServerDevice} from '../ServerDevice';
|
||||
import {FlipperServerImpl} from '../../FlipperServerImpl';
|
||||
import {iOSCrashWatcher} from './iOSCrashUtils';
|
||||
import {iOSLogListener} from './iOSLogListener';
|
||||
import {DebuggableDevice} from '../DebuggableDevice';
|
||||
import tmp, {DirOptions} from 'tmp';
|
||||
import {promisify} from 'util';
|
||||
import path from 'path';
|
||||
import {readFile} from 'fs/promises';
|
||||
|
||||
export default class IOSDevice extends ServerDevice {
|
||||
const tmpDir = promisify(tmp.dir) as (options?: DirOptions) => Promise<string>;
|
||||
|
||||
export default class IOSDevice
|
||||
extends ServerDevice
|
||||
implements DebuggableDevice
|
||||
{
|
||||
private recording?: {process: ChildProcess; destination: string};
|
||||
private iOSBridge: IOSBridge;
|
||||
readonly logListener: iOSLogListener;
|
||||
@@ -128,6 +138,111 @@ export default class IOSDevice extends ServerDevice {
|
||||
);
|
||||
}
|
||||
|
||||
async readFlipperFolderForAllApps(): Promise<DeviceDebugData[]> {
|
||||
console.debug('IOSDevice.readFlipperFolderForAllApps', this.info.serial);
|
||||
const installedApps = await this.iOSBridge.getInstalledApps(
|
||||
this.info.serial,
|
||||
);
|
||||
const userApps = installedApps.filter(
|
||||
({installType}) =>
|
||||
installType === 'user' || installType === 'user_development',
|
||||
);
|
||||
console.debug(
|
||||
'IOSDevice.readFlipperFolderForAllApps -> found apps',
|
||||
this.info.serial,
|
||||
userApps,
|
||||
);
|
||||
|
||||
const appsCommandsResults = await Promise.all(
|
||||
userApps.map(async (userApp): Promise<DeviceDebugData | undefined> => {
|
||||
let sonarDirFileNames: string[];
|
||||
try {
|
||||
sonarDirFileNames = await this.iOSBridge.ls(
|
||||
this.info.serial,
|
||||
userApp.bundleID,
|
||||
'/Library/Application Support/sonar',
|
||||
);
|
||||
} catch (e) {
|
||||
console.debug(
|
||||
'IOSDevice.readFlipperFolderForAllApps -> ignoring app as it does not have sonar dir',
|
||||
this.info.serial,
|
||||
userApp.bundleID,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const dir = await tmpDir({unsafeCleanup: true});
|
||||
|
||||
const sonarDirContent = await Promise.all(
|
||||
sonarDirFileNames.map(async (fileName) => {
|
||||
const filePath = `/Library/Application Support/sonar/${fileName}`;
|
||||
|
||||
if (fileName.endsWith('pem')) {
|
||||
return {
|
||||
path: filePath,
|
||||
data: '===SECURE_CONTENT===',
|
||||
};
|
||||
}
|
||||
try {
|
||||
await this.iOSBridge.pull(
|
||||
this.info.serial,
|
||||
filePath,
|
||||
userApp.bundleID,
|
||||
dir,
|
||||
);
|
||||
} catch (e) {
|
||||
console.debug(
|
||||
'IOSDevice.readFlipperFolderForAllApps -> Original idb pull failed. Most likely it is a physical device that requires us to handle the dest path dirrently. Forcing a re-try with the updated dest path. See D32106952 for details. Original error:',
|
||||
this.info.serial,
|
||||
userApp.bundleID,
|
||||
fileName,
|
||||
filePath,
|
||||
e,
|
||||
);
|
||||
await this.iOSBridge.pull(
|
||||
this.info.serial,
|
||||
filePath,
|
||||
userApp.bundleID,
|
||||
path.join(dir, fileName),
|
||||
);
|
||||
console.debug(
|
||||
'IOSDevice.readFlipperFolderForAllApps -> Subsequent idb pull succeeded. Nevermind previous wranings.',
|
||||
this.info.serial,
|
||||
userApp.bundleID,
|
||||
fileName,
|
||||
filePath,
|
||||
);
|
||||
}
|
||||
return {
|
||||
path: filePath,
|
||||
data: await readFile(path.join(dir, fileName), {
|
||||
encoding: 'utf-8',
|
||||
}),
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
return {
|
||||
serial: this.info.serial,
|
||||
appId: userApp.bundleID,
|
||||
data: [
|
||||
{
|
||||
command: 'iOSBridge.ls /Library/Application Support/sonar',
|
||||
result: sonarDirFileNames.join('\n'),
|
||||
},
|
||||
...sonarDirContent,
|
||||
],
|
||||
};
|
||||
}),
|
||||
);
|
||||
|
||||
return (
|
||||
appsCommandsResults
|
||||
// Filter out apps without Flipper integration
|
||||
.filter((res): res is DeviceDebugData => !!res)
|
||||
);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.recording) {
|
||||
this.stopScreenCapture();
|
||||
|
||||
Reference in New Issue
Block a user