Support physical device logging

Summary:
Changelog: Logs plugin now supports physical iOS devices

As reported in https://github.com/facebook/flipper/issues/262 and linked papercut.

This diff adds support for iOS device logs through idb. Since idb doesn't respect `--json` flag at the moment, we perform the parsing in Flipper itself.

Reviewed By: passy

Differential Revision: D27346262

fbshipit-source-id: 3b314716f48bb9a7fe709370303396a51893359c
This commit is contained in:
Michel Weststrate
2021-03-29 06:59:15 -07:00
committed by Facebook GitHub Bot
parent d22e893169
commit d5fbe9a5b9
9 changed files with 170 additions and 45 deletions

View File

@@ -9,10 +9,13 @@
import fs from 'fs';
import child_process from 'child_process';
import {DeviceType} from 'flipper-plugin-lib';
export interface IOSBridge {
idbAvailable: boolean;
startLogListener?: (
udid: string,
deviceType: DeviceType,
) => child_process.ChildProcessWithoutNullStreams;
}
@@ -26,27 +29,36 @@ async function isAvailable(idbPath: string): Promise<boolean> {
.catch((_) => false);
}
const LOG_EXTRA_ARGS = [
'--style',
'json',
'--predicate',
'senderImagePath contains "Containers"',
'--debug',
'--info',
];
function getLogExtraArgs(deviceType: DeviceType) {
if (deviceType === 'physical') {
return [
// idb has a --json option, but that doesn't actually work!
];
} else {
return [
'--style',
'json',
'--predicate',
'senderImagePath contains "Containers"',
'--debug',
'--info',
];
}
}
export function idbStartLogListener(
idbPath: string,
udid: string,
deviceType: DeviceType,
): child_process.ChildProcessWithoutNullStreams {
return child_process.spawn(
idbPath,
['log', '--udid', udid, '--', ...LOG_EXTRA_ARGS],
['log', '--udid', udid, '--', ...getLogExtraArgs(deviceType)],
{},
);
}
export function xcrunStartLogListener(udid: string) {
export function xcrunStartLogListener(udid: string, deviceType: DeviceType) {
const deviceSetPath = process.env.DEVICE_SET_PATH
? ['--set', process.env.DEVICE_SET_PATH]
: [];
@@ -59,7 +71,7 @@ export function xcrunStartLogListener(udid: string) {
udid,
'log',
'stream',
...LOG_EXTRA_ARGS,
...getLogExtraArgs(deviceType),
],
{},
);
@@ -70,18 +82,23 @@ export async function makeIOSBridge(
isXcodeDetected: boolean,
isAvailableFn: (idbPath: string) => Promise<boolean> = isAvailable,
): Promise<IOSBridge> {
if (!isXcodeDetected) {
// iOS Physical Device can still get detected without Xcode. In this case there is no way to setup log listener yet.
// This will not be the case, idb team is working on making idb log work without XCode atleast for physical device.
return {};
}
// prefer idb
if (await isAvailableFn(idbPath)) {
return {
idbAvailable: true,
startLogListener: idbStartLogListener.bind(null, idbPath),
};
}
// no idb, if it's a simulator and xcode is available, we can use xcrun
if (isXcodeDetected) {
return {
idbAvailable: false,
startLogListener: xcrunStartLogListener,
};
}
// no idb, and not a simulator, we can't log this device
return {
startLogListener: xcrunStartLogListener,
idbAvailable: false,
};
}