Summary: The log plugin subscribed to the device logs, when it was mounted. Then, the device replayed all log messages that happened in before the plugin became active. While this works, this was not the most performant way to handle this, because it caused multiple rerenders. In this diff, a method is added to `BaseDevice` to get all buffered logs. This method is called once the logs plugin becomes active. The processing of the logs is split into a couple smaller functions. Reviewed By: jknoxville Differential Revision: D13376393 fbshipit-source-id: bb151659c3335e10f647ae2dbf66e93b32d22913
103 lines
2.0 KiB
JavaScript
103 lines
2.0 KiB
JavaScript
/**
|
|
* Copyright 2018-present Facebook.
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
* @format
|
|
*/
|
|
|
|
import type stream from 'stream';
|
|
|
|
export type LogLevel =
|
|
| 'unknown'
|
|
| 'verbose'
|
|
| 'debug'
|
|
| 'info'
|
|
| 'warn'
|
|
| 'error'
|
|
| 'fatal';
|
|
|
|
export type DeviceLogEntry = {|
|
|
date: Date,
|
|
pid: number,
|
|
tid: number,
|
|
app?: string,
|
|
type: LogLevel,
|
|
tag: string,
|
|
message: string,
|
|
|};
|
|
|
|
export type DeviceShell = {
|
|
stdout: stream.Readable,
|
|
stderr: stream.Readable,
|
|
stdin: stream.Writable,
|
|
};
|
|
|
|
export type DeviceLogListener = (entry: DeviceLogEntry) => void;
|
|
|
|
export type DeviceType = 'emulator' | 'physical';
|
|
|
|
export default class BaseDevice {
|
|
constructor(serial: string, deviceType: DeviceType, title: string) {
|
|
this.serial = serial;
|
|
this.title = title;
|
|
this.deviceType = deviceType;
|
|
}
|
|
|
|
// operating system of this device
|
|
os: string;
|
|
|
|
// human readable name for this device
|
|
title: string;
|
|
|
|
// type of this device
|
|
deviceType: DeviceType;
|
|
|
|
// serial number for this device
|
|
serial: string;
|
|
|
|
// possible src of icon to display next to the device title
|
|
icon: ?string;
|
|
|
|
logListeners: Map<Symbol, DeviceLogListener> = new Map();
|
|
logEntries: Array<DeviceLogEntry> = [];
|
|
|
|
supportsOS(os: string) {
|
|
return os.toLowerCase() === this.os.toLowerCase();
|
|
}
|
|
|
|
toJSON() {
|
|
return `<${this.constructor.name}#${this.title}#${this.serial}>`;
|
|
}
|
|
|
|
teardown() {}
|
|
|
|
supportedColumns(): Array<string> {
|
|
throw new Error('unimplemented');
|
|
}
|
|
|
|
addLogListener(callback: DeviceLogListener): Symbol {
|
|
const id = Symbol();
|
|
this.logListeners.set(id, callback);
|
|
return id;
|
|
}
|
|
|
|
notifyLogListeners(entry: DeviceLogEntry) {
|
|
this.logEntries.push(entry);
|
|
if (this.logListeners.size > 0) {
|
|
this.logListeners.forEach(listener => listener(entry));
|
|
}
|
|
}
|
|
|
|
getLogs() {
|
|
return this.logEntries;
|
|
}
|
|
|
|
removeLogListener(id: Symbol) {
|
|
this.logListeners.delete(id);
|
|
}
|
|
|
|
spawnShell(): DeviceShell {
|
|
throw new Error('unimplemented');
|
|
}
|
|
}
|