Back out "Update adbkit and logcat to maintained librarys"
Summary: Original commit changeset: 2a23c0eaa12f Original Phabricator Diff: D45569652 The new lib causes weird log parsing https://fb.workplace.com/groups/flippersupport/permalink/1629943924152926/ Reviewed By: LukeDefeo, passy Differential Revision: D46390961 fbshipit-source-id: 7c9d0ca7fff2d9cb1ac1a309710f2348233a3471
This commit is contained in:
committed by
Facebook GitHub Bot
parent
bb9793019c
commit
e8e1a32e48
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import CertificateProvider from '../../utils/CertificateProvider';
|
||||
import {Client} from '@u4/adbkit';
|
||||
import {Client} from 'adbkit';
|
||||
import * as androidUtil from './androidContainerUtility';
|
||||
import {csrFileName, extractAppNameFromCSR} from '../../utils/certificateUtils';
|
||||
|
||||
@@ -98,7 +98,7 @@ export default class AndroidCertificateProvider extends CertificateProvider {
|
||||
const appName = await extractAppNameFromCSR(csr);
|
||||
const deviceId = await this.getTargetDeviceId(appName, destination, csr);
|
||||
await androidUtil.push(
|
||||
this.adb.getDevice(deviceId),
|
||||
this.adb,
|
||||
deviceId,
|
||||
appName,
|
||||
destination + filename,
|
||||
@@ -113,7 +113,7 @@ export default class AndroidCertificateProvider extends CertificateProvider {
|
||||
csr: string,
|
||||
): Promise<{isMatch: boolean; foundCsr: string}> {
|
||||
const deviceCsr = await androidUtil.pull(
|
||||
this.adb.getDevice(deviceId),
|
||||
this.adb,
|
||||
deviceId,
|
||||
processName,
|
||||
directory + csrFileName,
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import adb, {DeviceClient as ADBDeviceClient, PullTransfer} from '@u4/adbkit';
|
||||
import adb, {util, Client as ADBClient, PullTransfer} from 'adbkit';
|
||||
import {Reader} from 'adbkit-logcat';
|
||||
import {createWriteStream} from 'fs';
|
||||
import type {DeviceDebugData, DeviceType} from 'flipper-common';
|
||||
import {spawn} from 'child_process';
|
||||
@@ -26,8 +27,10 @@ export default class AndroidDevice
|
||||
extends ServerDevice
|
||||
implements DebuggableDevice
|
||||
{
|
||||
private adbClient: ADBDeviceClient;
|
||||
adb: ADBClient;
|
||||
pidAppMapping: {[key: number]: string} = {};
|
||||
private recordingProcess?: Promise<string>;
|
||||
reader?: Reader;
|
||||
readonly logListener: AndroidLogListener;
|
||||
readonly crashWatcher: AndroidCrashWatcher;
|
||||
|
||||
@@ -36,7 +39,7 @@ export default class AndroidDevice
|
||||
serial: string,
|
||||
deviceType: DeviceType,
|
||||
title: string,
|
||||
adb: ADBDeviceClient,
|
||||
adb: ADBClient,
|
||||
abiList: Array<string>,
|
||||
sdkVersion: string,
|
||||
specs: DeviceSpec[] = [],
|
||||
@@ -55,12 +58,13 @@ export default class AndroidDevice
|
||||
screenshotAvailable: false,
|
||||
},
|
||||
});
|
||||
this.adbClient = adb;
|
||||
this.adb = adb;
|
||||
|
||||
this.logListener = new AndroidLogListener(
|
||||
() => this.connected,
|
||||
(logEntry) => this.addLogEntry(logEntry),
|
||||
this.adbClient,
|
||||
this.adb,
|
||||
this.serial,
|
||||
);
|
||||
// It is OK not to await the start of the log listener. We just spawn it and handle errors internally.
|
||||
this.logListener
|
||||
@@ -83,7 +87,9 @@ export default class AndroidDevice
|
||||
|
||||
reverse(ports: number[]): Promise<void> {
|
||||
return Promise.all(
|
||||
ports.map((port) => this.adbClient.reverse(`tcp:${port}`, `tcp:${port}`)),
|
||||
ports.map((port) =>
|
||||
this.adb.reverse(this.serial, `tcp:${port}`, `tcp:${port}`),
|
||||
),
|
||||
).then(() => {
|
||||
return;
|
||||
});
|
||||
@@ -97,13 +103,13 @@ export default class AndroidDevice
|
||||
|
||||
async navigateToLocation(location: string) {
|
||||
const shellCommand = `am start ${encodeURI(location)}`;
|
||||
this.adbClient.shell(shellCommand);
|
||||
this.adb.shell(this.serial, shellCommand);
|
||||
}
|
||||
|
||||
async screenshot(): Promise<Buffer> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.adbClient
|
||||
.screencap()
|
||||
this.adb
|
||||
.screencap(this.serial)
|
||||
.then((stream) => {
|
||||
const chunks: Array<Buffer> = [];
|
||||
stream
|
||||
@@ -123,7 +129,7 @@ export default class AndroidDevice
|
||||
console.debug('AndroidDevice.setIntoPermissiveMode', this.serial);
|
||||
try {
|
||||
try {
|
||||
await this.adbClient.root();
|
||||
await this.adb.root(this.serial);
|
||||
} catch (e) {
|
||||
if (
|
||||
!(e instanceof Error) ||
|
||||
@@ -173,15 +179,15 @@ export default class AndroidDevice
|
||||
}
|
||||
|
||||
async executeShell(command: string): Promise<string> {
|
||||
return await this.adbClient
|
||||
.shell(command)
|
||||
return await this.adb
|
||||
.shell(this.serial, command)
|
||||
.then(adb.util.readAll)
|
||||
.then((output: Buffer) => output.toString().trim());
|
||||
}
|
||||
|
||||
private async executeShellOrDie(command: string | string[]): Promise<void> {
|
||||
const output = await this.adbClient
|
||||
.shell(command)
|
||||
const output = await this.adb
|
||||
.shell(this.serial, command)
|
||||
.then(adb.util.readAll)
|
||||
.then((output: Buffer) => output.toString().trim());
|
||||
if (output) {
|
||||
@@ -190,16 +196,16 @@ export default class AndroidDevice
|
||||
}
|
||||
|
||||
private async getSdkVersion(): Promise<number> {
|
||||
return await this.adbClient
|
||||
.shell('getprop ro.build.version.sdk')
|
||||
return await this.adb
|
||||
.shell(this.serial, 'getprop ro.build.version.sdk')
|
||||
.then(adb.util.readAll)
|
||||
.then((output) => Number(output.toString().trim()));
|
||||
}
|
||||
|
||||
private async isValidFile(filePath: string): Promise<boolean> {
|
||||
const sdkVersion = await this.getSdkVersion();
|
||||
const fileSize = await this.adbClient
|
||||
.shell(`ls -l "${filePath}"`)
|
||||
const fileSize = await this.adb
|
||||
.shell(this.serial, `ls -l "${filePath}"`)
|
||||
.then(adb.util.readAll)
|
||||
.then((output: Buffer) => output.toString().trim().split(' '))
|
||||
.then((x) => x.filter(Boolean))
|
||||
@@ -216,7 +222,7 @@ export default class AndroidDevice
|
||||
let newSize: string | undefined;
|
||||
try {
|
||||
const sizeString = (
|
||||
await adb.util.readAll(await this.adbClient.shell('wm size'))
|
||||
await adb.util.readAll(await this.adb.shell(this.serial, 'wm size'))
|
||||
).toString();
|
||||
const size = sizeString.split(' ').slice(-1).pop()?.split('x');
|
||||
if (size && size.length === 2) {
|
||||
@@ -233,8 +239,8 @@ export default class AndroidDevice
|
||||
}
|
||||
const sizeArg = newSize ? `--size ${newSize}` : '';
|
||||
const cmd = `screenrecord ${sizeArg} "${recordingLocation}"`;
|
||||
this.recordingProcess = this.adbClient
|
||||
.shell(cmd)
|
||||
this.recordingProcess = this.adb
|
||||
.shell(this.serial, cmd)
|
||||
.then(adb.util.readAll)
|
||||
.then(async (output) => {
|
||||
const isValid = await this.isValidFile(recordingLocation);
|
||||
@@ -248,7 +254,8 @@ export default class AndroidDevice
|
||||
.then(
|
||||
(_) =>
|
||||
new Promise(async (resolve, reject) => {
|
||||
const stream: PullTransfer = await this.adbClient.pull(
|
||||
const stream: PullTransfer = await this.adb.pull(
|
||||
this.serial,
|
||||
recordingLocation,
|
||||
);
|
||||
stream.on('end', resolve as () => void);
|
||||
@@ -267,14 +274,14 @@ export default class AndroidDevice
|
||||
if (!recordingProcess) {
|
||||
return Promise.reject(new Error('Recording was not properly started'));
|
||||
}
|
||||
await this.adbClient.shell(`pkill -l2 screenrecord`);
|
||||
await this.adb.shell(this.serial, `pkill -l2 screenrecord`);
|
||||
const destination = await recordingProcess;
|
||||
this.recordingProcess = undefined;
|
||||
return destination;
|
||||
}
|
||||
|
||||
async forwardPort(local: string, remote: string): Promise<boolean> {
|
||||
return this.adbClient.forward(local, remote);
|
||||
return this.adb.forward(this.serial, local, remote);
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
@@ -286,7 +293,7 @@ export default class AndroidDevice
|
||||
|
||||
async installApp(apkPath: string) {
|
||||
console.log(`Installing app with adb ${apkPath}`);
|
||||
await this.adbClient.install(apkPath);
|
||||
await this.adb.install(this.serial, apkPath);
|
||||
}
|
||||
|
||||
async readFlipperFolderForAllApps(): Promise<DeviceDebugData[]> {
|
||||
@@ -294,9 +301,9 @@ export default class AndroidDevice
|
||||
'AndroidDevice.readFlipperFolderForAllApps',
|
||||
this.info.serial,
|
||||
);
|
||||
const output = await this.adbClient
|
||||
.shell('pm list packages -3 -e')
|
||||
.then(adb.util.readAll)
|
||||
const output = await this.adb
|
||||
.shell(this.info.serial, 'pm list packages -3 -e')
|
||||
.then(util.readAll)
|
||||
.then((buffer) => buffer.toString());
|
||||
|
||||
const appIds = output
|
||||
@@ -315,7 +322,7 @@ export default class AndroidDevice
|
||||
const appsCommandsResults = await Promise.all(
|
||||
appIds.map(async (appId): Promise<DeviceDebugData | undefined> => {
|
||||
const sonarDirFilePaths = await executeCommandAsApp(
|
||||
this.adbClient,
|
||||
this.adb,
|
||||
this.info.serial,
|
||||
appId,
|
||||
`find /data/data/${appId}/files/sonar -type f`,
|
||||
@@ -362,7 +369,7 @@ export default class AndroidDevice
|
||||
return {
|
||||
path: filePath,
|
||||
data: await pull(
|
||||
this.adbClient,
|
||||
this.adb,
|
||||
this.info.serial,
|
||||
appId,
|
||||
filePath,
|
||||
@@ -372,7 +379,7 @@ export default class AndroidDevice
|
||||
);
|
||||
|
||||
const sonarDirContentWithStatsCommandPromise = executeCommandAsApp(
|
||||
this.adbClient,
|
||||
this.adb,
|
||||
this.info.serial,
|
||||
appId,
|
||||
`ls -al /data/data/${appId}/files/sonar`,
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {DeviceClient as ADBClient} from '@u4/adbkit';
|
||||
import {Priority, Reader} from '@u4/adbkit-logcat';
|
||||
import type {Client as ADBClient} from 'adbkit';
|
||||
import {Priority} from 'adbkit-logcat';
|
||||
import {DeviceLogEntry, DeviceLogLevel} from 'flipper-common';
|
||||
import {DeviceListener} from '../../utils/DeviceListener';
|
||||
|
||||
@@ -17,13 +17,14 @@ export class AndroidLogListener extends DeviceListener {
|
||||
isDeviceConnected: () => boolean,
|
||||
private onNewLogEntry: (logEntry: DeviceLogEntry) => void,
|
||||
private readonly adb: ADBClient,
|
||||
private readonly serial: string,
|
||||
) {
|
||||
super(isDeviceConnected);
|
||||
}
|
||||
protected async startListener() {
|
||||
const reader = (await this.adb.openLogcat({
|
||||
const reader = await this.adb.openLogcat(this.serial, {
|
||||
clear: true,
|
||||
})) as Reader;
|
||||
});
|
||||
|
||||
let gracefulShutdown = false;
|
||||
let lastKnownError: Error | undefined;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import {DeviceType} from 'flipper-common';
|
||||
import AndroidDevice from './AndroidDevice';
|
||||
import {DeviceClient} from '@u4/adbkit';
|
||||
import {Client as ADBClient} from 'adbkit';
|
||||
import {FlipperServerImpl} from '../../FlipperServerImpl';
|
||||
|
||||
export default class KaiOSDevice extends AndroidDevice {
|
||||
@@ -18,7 +18,7 @@ export default class KaiOSDevice extends AndroidDevice {
|
||||
serial: string,
|
||||
deviceType: DeviceType,
|
||||
title: string,
|
||||
adb: DeviceClient,
|
||||
adb: ADBClient,
|
||||
abiList: Array<string>,
|
||||
sdkVersion: string,
|
||||
) {
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
|
||||
import {reportPlatformFailures} from 'flipper-common';
|
||||
import {execFile} from 'promisify-child-process';
|
||||
import adbkit, {Client as ADBClient} from '@u4/adbkit';
|
||||
import path from 'path';
|
||||
import adbConfig from './adbConfig';
|
||||
import adbkit, {Client} from 'adbkit';
|
||||
import path from 'path';
|
||||
|
||||
type Config = {
|
||||
androidHome: string;
|
||||
@@ -23,7 +23,7 @@ type Config = {
|
||||
|
||||
export async function initializeAdbClient(
|
||||
config: Config,
|
||||
): Promise<ADBClient | void> {
|
||||
): Promise<Client | void> {
|
||||
const adbClient = await reportPlatformFailures(
|
||||
createClient(config),
|
||||
'createADBClient',
|
||||
@@ -39,8 +39,8 @@ export async function initializeAdbClient(
|
||||
/* Adbkit will attempt to start the adb server if it's not already running,
|
||||
however, it sometimes fails with ENOENT errors. So instead, we start it
|
||||
manually before requesting a client. */
|
||||
async function createClient(config: Config): Promise<ADBClient> {
|
||||
return reportPlatformFailures<ADBClient>(
|
||||
async function createClient(config: Config): Promise<Client> {
|
||||
return reportPlatformFailures<Client>(
|
||||
startAdbServer(config.androidHome).then(() =>
|
||||
adbkit.createClient(adbConfig(config.adbKitSettings)),
|
||||
),
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
import {UnsupportedError} from 'flipper-common';
|
||||
import adbkit, {DeviceClient} from '@u4/adbkit';
|
||||
import adbkit, {Client} from 'adbkit';
|
||||
|
||||
const allowedAppNameRegex = /^[\w.-]+$/;
|
||||
const appNotApplicationRegex = /not an application/;
|
||||
@@ -23,7 +23,7 @@ export type FilePath = string;
|
||||
export type FileContent = string;
|
||||
|
||||
export async function push(
|
||||
client: DeviceClient,
|
||||
client: Client,
|
||||
deviceId: string,
|
||||
app: string,
|
||||
filepath: string,
|
||||
@@ -36,7 +36,7 @@ export async function push(
|
||||
}
|
||||
|
||||
export async function pull(
|
||||
client: DeviceClient,
|
||||
client: Client,
|
||||
deviceId: string,
|
||||
app: string,
|
||||
path: string,
|
||||
@@ -81,7 +81,7 @@ class RunAsError extends Error {
|
||||
}
|
||||
|
||||
function _push(
|
||||
deviceClient: DeviceClient,
|
||||
client: Client,
|
||||
deviceId: string,
|
||||
app: AppName,
|
||||
filename: FilePath,
|
||||
@@ -91,12 +91,12 @@ function _push(
|
||||
// TODO: this is sensitive to escaping issues, can we leverage client.push instead?
|
||||
// https://www.npmjs.com/package/adbkit#pushing-a-file-to-all-connected-devices
|
||||
const command = `echo "${contents}" > '${filename}' && chmod 644 '${filename}'`;
|
||||
return executeCommandAsApp(deviceClient, deviceId, app, command)
|
||||
return executeCommandAsApp(client, deviceId, app, command)
|
||||
.then((_) => undefined)
|
||||
.catch((error) => {
|
||||
if (error instanceof RunAsError) {
|
||||
// Fall back to running the command directly. This will work if adb is running as root.
|
||||
executeCommandWithSu(deviceClient, deviceId, app, command, error);
|
||||
executeCommandWithSu(client, deviceId, app, command, error);
|
||||
return undefined;
|
||||
}
|
||||
throw error;
|
||||
@@ -104,32 +104,24 @@ function _push(
|
||||
}
|
||||
|
||||
function _pull(
|
||||
deviceClient: DeviceClient,
|
||||
client: Client,
|
||||
deviceId: string,
|
||||
app: AppName,
|
||||
path: FilePath,
|
||||
): Promise<string> {
|
||||
const command = `cat '${path}'`;
|
||||
return executeCommandAsApp(deviceClient, deviceId, app, command).catch(
|
||||
(error) => {
|
||||
if (error instanceof RunAsError) {
|
||||
// Fall back to running the command directly. This will work if adb is running as root.
|
||||
return executeCommandWithSu(
|
||||
deviceClient,
|
||||
deviceId,
|
||||
app,
|
||||
command,
|
||||
error,
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
},
|
||||
);
|
||||
return executeCommandAsApp(client, deviceId, app, command).catch((error) => {
|
||||
if (error instanceof RunAsError) {
|
||||
// Fall back to running the command directly. This will work if adb is running as root.
|
||||
return executeCommandWithSu(client, deviceId, app, command, error);
|
||||
}
|
||||
throw error;
|
||||
});
|
||||
}
|
||||
|
||||
// Keep this method private since it relies on pre-validated arguments
|
||||
export function executeCommandAsApp(
|
||||
client: DeviceClient,
|
||||
client: Client,
|
||||
deviceId: string,
|
||||
app: string,
|
||||
command: string,
|
||||
@@ -144,7 +136,7 @@ export function executeCommandAsApp(
|
||||
}
|
||||
|
||||
async function executeCommandWithSu(
|
||||
client: DeviceClient,
|
||||
client: Client,
|
||||
deviceId: string,
|
||||
app: string,
|
||||
command: string,
|
||||
@@ -159,14 +151,14 @@ async function executeCommandWithSu(
|
||||
}
|
||||
|
||||
function _executeCommandWithRunner(
|
||||
client: DeviceClient,
|
||||
client: Client,
|
||||
deviceId: string,
|
||||
app: string,
|
||||
command: string,
|
||||
runner: string,
|
||||
): Promise<string> {
|
||||
return client
|
||||
.shell(`echo '${command}' | ${runner}`)
|
||||
.shell(deviceId, `echo '${command}' | ${runner}`)
|
||||
.then(adbkit.util.readAll)
|
||||
.then((buffer) => buffer.toString())
|
||||
.then((output) => {
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
import AndroidDevice from './AndroidDevice';
|
||||
import KaiOSDevice from './KaiOSDevice';
|
||||
import child_process from 'child_process';
|
||||
import {Client as ADBClient, Device} from '@u4/adbkit';
|
||||
import {Client as ADBClient, Device} from 'adbkit';
|
||||
import {join} from 'path';
|
||||
import {FlipperServerImpl} from '../../FlipperServerImpl';
|
||||
import {notNull} from '../../utils/typeUtils';
|
||||
@@ -26,7 +26,10 @@ export class AndroidDeviceManager {
|
||||
this.certificateProvider = new AndroidCertificateProvider(this.adbClient);
|
||||
}
|
||||
|
||||
private createDevice(device: Device): Promise<AndroidDevice | undefined> {
|
||||
private createDevice(
|
||||
adbClient: ADBClient,
|
||||
device: Device,
|
||||
): Promise<AndroidDevice | undefined> {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const type =
|
||||
device.type !== 'device' || device.id.startsWith('emulator')
|
||||
@@ -34,9 +37,7 @@ export class AndroidDeviceManager {
|
||||
: 'physical';
|
||||
|
||||
try {
|
||||
const deviceClient = device.getClient();
|
||||
|
||||
const props = await deviceClient.getProperties();
|
||||
const props = await adbClient.getProperties(device.id);
|
||||
try {
|
||||
let name = props['ro.product.model'];
|
||||
const abiString = props['ro.product.cpu.abilist'] || '';
|
||||
@@ -55,7 +56,7 @@ export class AndroidDeviceManager {
|
||||
device.id,
|
||||
type,
|
||||
name,
|
||||
deviceClient,
|
||||
adbClient,
|
||||
abiList,
|
||||
sdkVersion,
|
||||
);
|
||||
@@ -194,7 +195,7 @@ export class AndroidDeviceManager {
|
||||
const devices = await this.adbClient.listDevices();
|
||||
for (const device of devices) {
|
||||
if (device.type !== 'offline') {
|
||||
this.registerDevice(device);
|
||||
this.registerDevice(this.adbClient, device);
|
||||
} else {
|
||||
this.handleOfflineDevice(device);
|
||||
}
|
||||
@@ -236,7 +237,7 @@ export class AndroidDeviceManager {
|
||||
return;
|
||||
}
|
||||
if (device.type !== 'offline') {
|
||||
this.registerDevice(device);
|
||||
this.registerDevice(this.adbClient, device);
|
||||
} else {
|
||||
this.handleOfflineDevice(device);
|
||||
}
|
||||
@@ -246,7 +247,7 @@ export class AndroidDeviceManager {
|
||||
if (device.type === 'offline') {
|
||||
this.flipperServer.unregisterDevice(device.id);
|
||||
} else {
|
||||
this.registerDevice(device);
|
||||
this.registerDevice(this.adbClient, device);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -272,8 +273,8 @@ export class AndroidDeviceManager {
|
||||
);
|
||||
}
|
||||
|
||||
private async registerDevice(deviceData: Device) {
|
||||
const androidDevice = await this.createDevice(deviceData);
|
||||
private async registerDevice(adbClient: ADBClient, deviceData: Device) {
|
||||
const androidDevice = await this.createDevice(adbClient, deviceData);
|
||||
if (!androidDevice) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user