Convert CPU plugin to Sandy
Summary: Starts converting the plugin by moving to new model and switching some of the UI components. No logic changes here, it's just shifting everything over. Reviewed By: mweststrate Differential Revision: D28028052 fbshipit-source-id: 7444eab77d9dba49261a70887ee26b8d120e97a6
This commit is contained in:
committed by
Facebook GitHub Bot
parent
923d44ef40
commit
a53f1b8f8d
@@ -7,23 +7,29 @@
|
|||||||
* @format
|
* @format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {FlipperDevicePlugin, Device, AndroidDevice} from 'flipper';
|
import {
|
||||||
|
createState,
|
||||||
|
PluginClient,
|
||||||
|
usePlugin,
|
||||||
|
useValue,
|
||||||
|
Panel,
|
||||||
|
theme,
|
||||||
|
Layout,
|
||||||
|
} from 'flipper-plugin';
|
||||||
import adb from 'adbkit';
|
import adb from 'adbkit';
|
||||||
import TemperatureTable from './TemperatureTable';
|
import TemperatureTable from './TemperatureTable';
|
||||||
|
import {Button, Typography} from 'antd';
|
||||||
|
import {PlayCircleOutlined, PauseCircleOutlined} from '@ant-design/icons';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
FlexColumn,
|
|
||||||
Button,
|
|
||||||
Toolbar,
|
Toolbar,
|
||||||
Text,
|
|
||||||
ManagedTable,
|
ManagedTable,
|
||||||
colors,
|
colors,
|
||||||
styled,
|
styled,
|
||||||
Panel,
|
|
||||||
DetailSidebar,
|
DetailSidebar,
|
||||||
ToggleButton,
|
ToggleButton,
|
||||||
} from 'flipper';
|
} from 'flipper';
|
||||||
import React from 'react';
|
import React, {useState} from 'react';
|
||||||
|
|
||||||
type TableRows = any;
|
type TableRows = any;
|
||||||
|
|
||||||
@@ -46,7 +52,6 @@ type CPUState = {
|
|||||||
cpuCount: number;
|
cpuCount: number;
|
||||||
monitoring: boolean;
|
monitoring: boolean;
|
||||||
hardwareInfo: string;
|
hardwareInfo: string;
|
||||||
selectedIds: Array<number>;
|
|
||||||
temperatureMap: any;
|
temperatureMap: any;
|
||||||
thermalAccessible: boolean;
|
thermalAccessible: boolean;
|
||||||
displayThermalInfo: boolean;
|
displayThermalInfo: boolean;
|
||||||
@@ -124,152 +129,100 @@ function formatFrequency(freq: number) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
export function devicePlugin(client: PluginClient<{}, {}>) {
|
||||||
CPUState,
|
const device = client.device;
|
||||||
any,
|
|
||||||
any
|
|
||||||
> {
|
|
||||||
intervalID: NodeJS.Timer | null = null;
|
|
||||||
state: CPUState = {
|
|
||||||
cpuCount: 0,
|
|
||||||
cpuFreq: [],
|
|
||||||
monitoring: false,
|
|
||||||
hardwareInfo: '',
|
|
||||||
selectedIds: [],
|
|
||||||
temperatureMap: {},
|
|
||||||
thermalAccessible: true,
|
|
||||||
displayThermalInfo: false,
|
|
||||||
displayCPUDetail: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
static supportsDevice(device: Device) {
|
const executeShell = (callback: ShellCallBack, command: string) => {
|
||||||
return (
|
return (device.realDevice as any).adb
|
||||||
device.os === 'Android' &&
|
.shell(device.serial, command)
|
||||||
device.deviceType === 'physical' &&
|
|
||||||
!device.isArchived
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this.updateHardwareInfo();
|
|
||||||
this.readThermalZones();
|
|
||||||
|
|
||||||
// check how many cores we have on this device
|
|
||||||
this.executeShell((output: string) => {
|
|
||||||
const idx = output.indexOf('-');
|
|
||||||
const cpuFreq = [];
|
|
||||||
const count = parseInt(output.substring(idx + 1), 10) + 1;
|
|
||||||
for (let i = 0; i < count; ++i) {
|
|
||||||
cpuFreq[i] = {
|
|
||||||
cpu_id: i,
|
|
||||||
scaling_cur_freq: -1,
|
|
||||||
scaling_min_freq: -1,
|
|
||||||
scaling_max_freq: -1,
|
|
||||||
cpuinfo_min_freq: -1,
|
|
||||||
cpuinfo_max_freq: -1,
|
|
||||||
scaling_available_freqs: [],
|
|
||||||
scaling_governor: 'N/A',
|
|
||||||
scaling_available_governors: [],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
this.setState({
|
|
||||||
cpuCount: count,
|
|
||||||
cpuFreq: cpuFreq,
|
|
||||||
monitoring: false,
|
|
||||||
hardwareInfo: '',
|
|
||||||
selectedIds: [],
|
|
||||||
temperatureMap: {},
|
|
||||||
thermalAccessible: true,
|
|
||||||
displayThermalInfo: false,
|
|
||||||
displayCPUDetail: true,
|
|
||||||
});
|
|
||||||
}, 'cat /sys/devices/system/cpu/possible');
|
|
||||||
}
|
|
||||||
executeShell = (callback: ShellCallBack, command: string) => {
|
|
||||||
return (this.device as AndroidDevice).adb
|
|
||||||
.shell(this.device.serial, command)
|
|
||||||
.then(adb.util.readAll)
|
.then(adb.util.readAll)
|
||||||
.then(function (output: {toString: () => {trim: () => string}}) {
|
.then(function (output: {toString: () => {trim: () => string}}) {
|
||||||
return callback(output.toString().trim());
|
return callback(output.toString().trim());
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
updateCoreFrequency = (core: number, type: string) => {
|
let intervalID: NodeJS.Timer | null = null;
|
||||||
this.executeShell((output: string) => {
|
const cpuState = createState<CPUState>({
|
||||||
const cpuFreq = this.state.cpuFreq;
|
cpuCount: 0,
|
||||||
const newFreq = isNormalInteger(output) ? parseInt(output, 10) : -1;
|
cpuFreq: [],
|
||||||
// update table only if frequency changed
|
monitoring: false,
|
||||||
if (cpuFreq[core][type] != newFreq) {
|
hardwareInfo: '',
|
||||||
cpuFreq[core][type] = newFreq;
|
temperatureMap: {},
|
||||||
if (type == 'scaling_cur_freq' && cpuFreq[core][type] < 0) {
|
thermalAccessible: true,
|
||||||
// cannot find current freq means offline
|
displayThermalInfo: false,
|
||||||
cpuFreq[core][type] = -2;
|
displayCPUDetail: true,
|
||||||
}
|
});
|
||||||
|
|
||||||
this.setState({
|
const updateCoreFrequency = (core: number, type: string) => {
|
||||||
cpuFreq: cpuFreq,
|
executeShell((output: string) => {
|
||||||
});
|
cpuState.update((draft) => {
|
||||||
}
|
const newFreq = isNormalInteger(output) ? parseInt(output, 10) : -1;
|
||||||
|
// update table only if frequency changed
|
||||||
|
if (draft.cpuFreq[core][type] != newFreq) {
|
||||||
|
draft.cpuFreq[core][type] = newFreq;
|
||||||
|
if (type == 'scaling_cur_freq' && draft.cpuFreq[core][type] < 0) {
|
||||||
|
// cannot find current freq means offline
|
||||||
|
draft.cpuFreq[core][type] = -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return draft;
|
||||||
|
});
|
||||||
}, 'cat /sys/devices/system/cpu/cpu' + core + '/cpufreq/' + type);
|
}, 'cat /sys/devices/system/cpu/cpu' + core + '/cpufreq/' + type);
|
||||||
};
|
};
|
||||||
|
|
||||||
updateAvailableFrequencies = (core: number) => {
|
const updateAvailableFrequencies = (core: number) => {
|
||||||
this.executeShell((output: string) => {
|
executeShell((output: string) => {
|
||||||
const cpuFreq = this.state.cpuFreq;
|
cpuState.update((draft) => {
|
||||||
const freqs = output.split(' ').map((num: string) => {
|
const freqs = output.split(' ').map((num: string) => {
|
||||||
return parseInt(num, 10);
|
return parseInt(num, 10);
|
||||||
});
|
});
|
||||||
cpuFreq[core].scaling_available_freqs = freqs;
|
draft.cpuFreq[core].scaling_available_freqs = freqs;
|
||||||
const maxFreq = cpuFreq[core].scaling_max_freq;
|
const maxFreq = draft.cpuFreq[core].scaling_max_freq;
|
||||||
if (maxFreq > 0 && freqs.indexOf(maxFreq) == -1) {
|
if (maxFreq > 0 && freqs.indexOf(maxFreq) == -1) {
|
||||||
freqs.push(maxFreq); // always add scaling max to available frequencies
|
freqs.push(maxFreq); // always add scaling max to available frequencies
|
||||||
}
|
}
|
||||||
this.setState({
|
return draft;
|
||||||
cpuFreq: cpuFreq,
|
|
||||||
});
|
});
|
||||||
}, 'cat /sys/devices/system/cpu/cpu' + core + '/cpufreq/scaling_available_frequencies');
|
}, 'cat /sys/devices/system/cpu/cpu' + core + '/cpufreq/scaling_available_frequencies');
|
||||||
};
|
};
|
||||||
|
|
||||||
updateCoreGovernor = (core: number) => {
|
const updateCoreGovernor = (core: number) => {
|
||||||
this.executeShell((output: string) => {
|
executeShell((output: string) => {
|
||||||
const cpuFreq = this.state.cpuFreq;
|
cpuState.update((draft) => {
|
||||||
if (output.toLowerCase().includes('no such file')) {
|
if (output.toLowerCase().includes('no such file')) {
|
||||||
cpuFreq[core].scaling_governor = 'N/A';
|
draft.cpuFreq[core].scaling_governor = 'N/A';
|
||||||
} else {
|
} else {
|
||||||
cpuFreq[core].scaling_governor = output;
|
draft.cpuFreq[core].scaling_governor = output;
|
||||||
}
|
}
|
||||||
this.setState({
|
return draft;
|
||||||
cpuFreq: cpuFreq,
|
|
||||||
});
|
});
|
||||||
}, 'cat /sys/devices/system/cpu/cpu' + core + '/cpufreq/scaling_governor');
|
}, 'cat /sys/devices/system/cpu/cpu' + core + '/cpufreq/scaling_governor');
|
||||||
};
|
};
|
||||||
|
|
||||||
readAvailableGovernors = (core: number) => {
|
const readAvailableGovernors = (core: number) => {
|
||||||
this.executeShell((output: string) => {
|
executeShell((output: string) => {
|
||||||
const cpuFreq = this.state.cpuFreq;
|
cpuState.update((draft) => {
|
||||||
cpuFreq[core].scaling_available_governors = output.split(' ');
|
draft.cpuFreq[core].scaling_available_governors = output.split(' ');
|
||||||
|
return draft;
|
||||||
this.setState({
|
|
||||||
cpuFreq: cpuFreq,
|
|
||||||
});
|
});
|
||||||
}, 'cat /sys/devices/system/cpu/cpu' + core + '/cpufreq/scaling_available_governors');
|
}, 'cat /sys/devices/system/cpu/cpu' + core + '/cpufreq/scaling_available_governors');
|
||||||
};
|
};
|
||||||
|
|
||||||
readCoreFrequency = (core: number) => {
|
const readCoreFrequency = (core: number) => {
|
||||||
const freq = this.state.cpuFreq[core];
|
const freq = cpuState.get().cpuFreq[core];
|
||||||
if (freq.cpuinfo_max_freq < 0) {
|
if (freq.cpuinfo_max_freq < 0) {
|
||||||
this.updateCoreFrequency(core, 'cpuinfo_max_freq');
|
updateCoreFrequency(core, 'cpuinfo_max_freq');
|
||||||
}
|
}
|
||||||
if (freq.cpuinfo_min_freq < 0) {
|
if (freq.cpuinfo_min_freq < 0) {
|
||||||
this.updateCoreFrequency(core, 'cpuinfo_min_freq');
|
updateCoreFrequency(core, 'cpuinfo_min_freq');
|
||||||
}
|
}
|
||||||
this.updateCoreFrequency(core, 'scaling_cur_freq');
|
updateCoreFrequency(core, 'scaling_cur_freq');
|
||||||
this.updateCoreFrequency(core, 'scaling_min_freq');
|
updateCoreFrequency(core, 'scaling_min_freq');
|
||||||
this.updateCoreFrequency(core, 'scaling_max_freq');
|
updateCoreFrequency(core, 'scaling_max_freq');
|
||||||
};
|
};
|
||||||
|
|
||||||
updateHardwareInfo = () => {
|
const updateHardwareInfo = () => {
|
||||||
this.executeShell((output: string) => {
|
executeShell((output: string) => {
|
||||||
let hwInfo = '';
|
let hwInfo = '';
|
||||||
if (
|
if (
|
||||||
output.startsWith('msm') ||
|
output.startsWith('msm') ||
|
||||||
@@ -278,10 +231,10 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
) {
|
) {
|
||||||
hwInfo = 'QUALCOMM ' + output.toUpperCase();
|
hwInfo = 'QUALCOMM ' + output.toUpperCase();
|
||||||
} else if (output.startsWith('exynos')) {
|
} else if (output.startsWith('exynos')) {
|
||||||
this.executeShell((output: string) => {
|
executeShell((output: string) => {
|
||||||
if (output != null) {
|
if (output != null) {
|
||||||
this.setState({
|
cpuState.update((draft) => {
|
||||||
hardwareInfo: 'SAMSUMG ' + output.toUpperCase(),
|
draft.hardwareInfo = 'SAMSUMG ' + output.toUpperCase();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, 'getprop ro.chipname');
|
}, 'getprop ro.chipname');
|
||||||
@@ -297,18 +250,22 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
} else if (output.startsWith('bcm')) {
|
} else if (output.startsWith('bcm')) {
|
||||||
hwInfo = 'BROADCOM ' + output.toUpperCase();
|
hwInfo = 'BROADCOM ' + output.toUpperCase();
|
||||||
}
|
}
|
||||||
this.setState({
|
cpuState.update((draft) => {
|
||||||
hardwareInfo: hwInfo,
|
draft.hardwareInfo = hwInfo;
|
||||||
|
return draft;
|
||||||
});
|
});
|
||||||
}, 'getprop ro.board.platform');
|
}, 'getprop ro.board.platform');
|
||||||
};
|
};
|
||||||
|
|
||||||
readThermalZones = () => {
|
const readThermalZones = () => {
|
||||||
const thermal_dir = '/sys/class/thermal/';
|
const thermal_dir = '/sys/class/thermal/';
|
||||||
const map = {};
|
const map = {};
|
||||||
this.executeShell(async (output: string) => {
|
executeShell(async (output: string) => {
|
||||||
if (output.toLowerCase().includes('permission denied')) {
|
if (output.toLowerCase().includes('permission denied')) {
|
||||||
this.setState({thermalAccessible: false});
|
cpuState.update((draft) => {
|
||||||
|
draft.thermalAccessible = false;
|
||||||
|
return draft;
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const dirs = output.split(/\s/);
|
const dirs = output.split(/\s/);
|
||||||
@@ -319,22 +276,26 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const path = thermal_dir + d;
|
const path = thermal_dir + d;
|
||||||
promises.push(this.readThermalZone(path, d, map));
|
promises.push(readThermalZone(path, d, map));
|
||||||
}
|
}
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
this.setState({temperatureMap: map, thermalAccessible: true});
|
cpuState.update((draft) => {
|
||||||
if (this.state.displayThermalInfo) {
|
draft.temperatureMap = map;
|
||||||
setTimeout(this.readThermalZones, 1000);
|
draft.thermalAccessible = true;
|
||||||
|
return draft;
|
||||||
|
});
|
||||||
|
if (cpuState.get().displayThermalInfo) {
|
||||||
|
setTimeout(readThermalZones, 1000);
|
||||||
}
|
}
|
||||||
}, 'ls ' + thermal_dir);
|
}, 'ls ' + thermal_dir);
|
||||||
};
|
};
|
||||||
|
|
||||||
readThermalZone = (path: string, dir: string, map: any) => {
|
const readThermalZone = (path: string, dir: string, map: any) => {
|
||||||
return this.executeShell((type: string) => {
|
return executeShell((type: string) => {
|
||||||
if (type.length == 0) {
|
if (type.length == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return this.executeShell((temp: string) => {
|
return executeShell((temp: string) => {
|
||||||
if (Number.isNaN(Number(temp))) {
|
if (Number.isNaN(Number(temp))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -346,63 +307,136 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
}, 'cat ' + path + '/type');
|
}, 'cat ' + path + '/type');
|
||||||
};
|
};
|
||||||
|
|
||||||
onStartMonitor = () => {
|
const onStartMonitor = () => {
|
||||||
if (this.intervalID) {
|
if (intervalID) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i < this.state.cpuCount; ++i) {
|
for (let i = 0; i < cpuState.get().cpuCount; ++i) {
|
||||||
this.readAvailableGovernors(i);
|
readAvailableGovernors(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.intervalID = setInterval(() => {
|
intervalID = setInterval(() => {
|
||||||
for (let i = 0; i < this.state.cpuCount; ++i) {
|
console.log('Starting task');
|
||||||
this.readCoreFrequency(i);
|
for (let i = 0; i < cpuState.get().cpuCount; ++i) {
|
||||||
this.updateCoreGovernor(i);
|
readCoreFrequency(i);
|
||||||
this.updateAvailableFrequencies(i); // scaling max might change, so we also update this
|
updateCoreGovernor(i);
|
||||||
|
updateAvailableFrequencies(i); // scaling max might change, so we also update this
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
|
cpuState.update((draft) => {
|
||||||
this.setState({
|
draft.monitoring = true;
|
||||||
monitoring: true,
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
onStopMonitor = () => {
|
const onStopMonitor = () => {
|
||||||
if (!this.intervalID) {
|
if (!intervalID) {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
clearInterval(this.intervalID);
|
clearInterval(intervalID);
|
||||||
this.intervalID = null;
|
intervalID = null;
|
||||||
this.setState({
|
cpuState.update((draft) => {
|
||||||
monitoring: false,
|
draft.monitoring = false;
|
||||||
|
return draft;
|
||||||
});
|
});
|
||||||
this.cleanup();
|
cleanup();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
cleanup = () => {
|
const cleanup = () => {
|
||||||
const cpuFreq = this.state.cpuFreq;
|
cpuState.update((draft) => {
|
||||||
for (let i = 0; i < this.state.cpuCount; ++i) {
|
for (let i = 0; i < draft.cpuCount; ++i) {
|
||||||
cpuFreq[i].scaling_cur_freq = -1;
|
draft.cpuFreq[i].scaling_cur_freq = -1;
|
||||||
cpuFreq[i].scaling_min_freq = -1;
|
draft.cpuFreq[i].scaling_min_freq = -1;
|
||||||
cpuFreq[i].scaling_max_freq = -1;
|
draft.cpuFreq[i].scaling_max_freq = -1;
|
||||||
cpuFreq[i].scaling_available_freqs = [];
|
draft.cpuFreq[i].scaling_available_freqs = [];
|
||||||
cpuFreq[i].scaling_governor = 'N/A';
|
draft.cpuFreq[i].scaling_governor = 'N/A';
|
||||||
// we don't cleanup cpuinfo_min_freq, cpuinfo_max_freq
|
// we don't cleanup cpuinfo_min_freq, cpuinfo_max_freq
|
||||||
// because usually they are fixed (hardware)
|
// because usually they are fixed (hardware)
|
||||||
}
|
}
|
||||||
this.setState({
|
|
||||||
cpuFreq: cpuFreq,
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
teardown() {
|
const toggleThermalSidebar = () => {
|
||||||
this.cleanup();
|
if (!cpuState.get().displayThermalInfo) {
|
||||||
}
|
readThermalZones();
|
||||||
|
}
|
||||||
|
cpuState.update((draft) => {
|
||||||
|
draft.displayThermalInfo = !draft.displayThermalInfo;
|
||||||
|
draft.displayCPUDetail = false;
|
||||||
|
return draft;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
buildRow = (freq: CPUFrequency, idx: number) => {
|
const toggleCPUSidebar = () => {
|
||||||
const selected = this.state.selectedIds.indexOf(idx) >= 0;
|
cpuState.update((draft) => {
|
||||||
|
draft.displayCPUDetail = !draft.displayCPUDetail;
|
||||||
|
draft.displayThermalInfo = false;
|
||||||
|
return draft;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// check how many cores we have on this device
|
||||||
|
executeShell((output: string) => {
|
||||||
|
const idx = output.indexOf('-');
|
||||||
|
const cpuFreq = [];
|
||||||
|
const count = parseInt(output.substring(idx + 1), 10) + 1;
|
||||||
|
for (let i = 0; i < count; ++i) {
|
||||||
|
cpuFreq[i] = {
|
||||||
|
cpu_id: i,
|
||||||
|
scaling_cur_freq: -1,
|
||||||
|
scaling_min_freq: -1,
|
||||||
|
scaling_max_freq: -1,
|
||||||
|
cpuinfo_min_freq: -1,
|
||||||
|
cpuinfo_max_freq: -1,
|
||||||
|
scaling_available_freqs: [],
|
||||||
|
scaling_governor: 'N/A',
|
||||||
|
scaling_available_governors: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
cpuState.set({
|
||||||
|
cpuCount: count,
|
||||||
|
cpuFreq: cpuFreq,
|
||||||
|
monitoring: false,
|
||||||
|
hardwareInfo: '',
|
||||||
|
temperatureMap: {},
|
||||||
|
thermalAccessible: true,
|
||||||
|
displayThermalInfo: false,
|
||||||
|
displayCPUDetail: true,
|
||||||
|
});
|
||||||
|
}, 'cat /sys/devices/system/cpu/possible');
|
||||||
|
|
||||||
|
client.onDeactivate(() => cleanup());
|
||||||
|
client.onActivate(() => {
|
||||||
|
updateHardwareInfo();
|
||||||
|
readThermalZones();
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
executeShell,
|
||||||
|
cpuState,
|
||||||
|
onStartMonitor,
|
||||||
|
onStopMonitor,
|
||||||
|
toggleCPUSidebar,
|
||||||
|
toggleThermalSidebar,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Component() {
|
||||||
|
const instance = usePlugin(devicePlugin);
|
||||||
|
const {
|
||||||
|
onStartMonitor,
|
||||||
|
onStopMonitor,
|
||||||
|
toggleCPUSidebar,
|
||||||
|
toggleThermalSidebar,
|
||||||
|
} = instance;
|
||||||
|
|
||||||
|
const cpuState = useValue(instance.cpuState);
|
||||||
|
|
||||||
|
const [selectedIds, setSelectedIds] = useState<number[]>([]);
|
||||||
|
|
||||||
|
const buildRow = (freq: CPUFrequency, idx: number) => {
|
||||||
|
const selected = selectedIds.indexOf(idx) >= 0;
|
||||||
let style = {};
|
let style = {};
|
||||||
if (freq.scaling_cur_freq == -2) {
|
if (freq.scaling_cur_freq == -2) {
|
||||||
style = {
|
style = {
|
||||||
@@ -440,24 +474,44 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
columns: {
|
columns: {
|
||||||
cpu_id: {value: <Text>CPU_{freq.cpu_id}</Text>},
|
cpu_id: {value: <Typography.Text>CPU_{freq.cpu_id}</Typography.Text>},
|
||||||
scaling_cur_freq: {
|
scaling_cur_freq: {
|
||||||
value: <Text>{formatFrequency(freq.scaling_cur_freq)}</Text>,
|
value: (
|
||||||
|
<Typography.Text>
|
||||||
|
{formatFrequency(freq.scaling_cur_freq)}
|
||||||
|
</Typography.Text>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
scaling_min_freq: {
|
scaling_min_freq: {
|
||||||
value: <Text>{formatFrequency(freq.scaling_min_freq)}</Text>,
|
value: (
|
||||||
|
<Typography.Text>
|
||||||
|
{formatFrequency(freq.scaling_min_freq)}
|
||||||
|
</Typography.Text>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
scaling_max_freq: {
|
scaling_max_freq: {
|
||||||
value: <Text>{formatFrequency(freq.scaling_max_freq)}</Text>,
|
value: (
|
||||||
|
<Typography.Text>
|
||||||
|
{formatFrequency(freq.scaling_max_freq)}
|
||||||
|
</Typography.Text>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
cpuinfo_min_freq: {
|
cpuinfo_min_freq: {
|
||||||
value: <Text>{formatFrequency(freq.cpuinfo_min_freq)}</Text>,
|
value: (
|
||||||
|
<Typography.Text>
|
||||||
|
{formatFrequency(freq.cpuinfo_min_freq)}
|
||||||
|
</Typography.Text>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
cpuinfo_max_freq: {
|
cpuinfo_max_freq: {
|
||||||
value: <Text>{formatFrequency(freq.cpuinfo_max_freq)}</Text>,
|
value: (
|
||||||
|
<Typography.Text>
|
||||||
|
{formatFrequency(freq.cpuinfo_max_freq)}
|
||||||
|
</Typography.Text>
|
||||||
|
),
|
||||||
},
|
},
|
||||||
scaling_governor: {
|
scaling_governor: {
|
||||||
value: <Text>{freq.scaling_governor}</Text>,
|
value: <Typography.Text>{freq.scaling_governor}</Typography.Text>,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
key: freq.cpu_id,
|
key: freq.cpu_id,
|
||||||
@@ -466,17 +520,17 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
frequencyRows = (cpuFreqs: Array<CPUFrequency>): TableRows => {
|
const frequencyRows = (cpuFreqs: Array<CPUFrequency>): TableRows => {
|
||||||
return cpuFreqs.map(this.buildRow);
|
return cpuFreqs.map(buildRow);
|
||||||
};
|
};
|
||||||
|
|
||||||
buildAvailableFreqList = (freq: CPUFrequency) => {
|
const buildAvailableFreqList = (freq: CPUFrequency) => {
|
||||||
if (freq.scaling_available_freqs.length == 0) {
|
if (freq.scaling_available_freqs.length == 0) {
|
||||||
return <Text>N/A</Text>;
|
return <Typography.Text>N/A</Typography.Text>;
|
||||||
}
|
}
|
||||||
const info = freq;
|
const info = freq;
|
||||||
return (
|
return (
|
||||||
<Text>
|
<Typography.Text>
|
||||||
{freq.scaling_available_freqs.map((freq, idx) => {
|
{freq.scaling_available_freqs.map((freq, idx) => {
|
||||||
const style: React.CSSProperties = {};
|
const style: React.CSSProperties = {};
|
||||||
if (
|
if (
|
||||||
@@ -487,36 +541,39 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
style.fontWeight = 'bold';
|
style.fontWeight = 'bold';
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Text key={idx} style={style}>
|
<Typography.Text key={idx} style={style}>
|
||||||
{formatFrequency(freq)}
|
{formatFrequency(freq)}
|
||||||
{freq == info.scaling_cur_freq && (
|
{freq == info.scaling_cur_freq && (
|
||||||
<Text style={style}> (scaling current)</Text>
|
<Typography.Text style={style}>
|
||||||
|
{' '}
|
||||||
|
(scaling current)
|
||||||
|
</Typography.Text>
|
||||||
)}
|
)}
|
||||||
{freq == info.scaling_min_freq && (
|
{freq == info.scaling_min_freq && (
|
||||||
<Text style={style}> (scaling min)</Text>
|
<Typography.Text style={style}> (scaling min)</Typography.Text>
|
||||||
)}
|
)}
|
||||||
{freq == info.scaling_max_freq && (
|
{freq == info.scaling_max_freq && (
|
||||||
<Text style={style}> (scaling max)</Text>
|
<Typography.Text style={style}> (scaling max)</Typography.Text>
|
||||||
)}
|
)}
|
||||||
<br />
|
<br />
|
||||||
</Text>
|
</Typography.Text>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
</Text>
|
</Typography.Text>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
buildAvailableGovList = (freq: CPUFrequency): string => {
|
const buildAvailableGovList = (freq: CPUFrequency): string => {
|
||||||
if (freq.scaling_available_governors.length == 0) {
|
if (freq.scaling_available_governors.length == 0) {
|
||||||
return 'N/A';
|
return 'N/A';
|
||||||
}
|
}
|
||||||
return freq.scaling_available_governors.join(', ');
|
return freq.scaling_available_governors.join(', ');
|
||||||
};
|
};
|
||||||
|
|
||||||
buildSidebarRow = (key: string, val: any) => {
|
const buildSidebarRow = (key: string, val: any) => {
|
||||||
return {
|
return {
|
||||||
columns: {
|
columns: {
|
||||||
key: {value: <Text>{key}</Text>},
|
key: {value: <Typography.Text>{key}</Typography.Text>},
|
||||||
value: {
|
value: {
|
||||||
value: val,
|
value: val,
|
||||||
},
|
},
|
||||||
@@ -525,9 +582,9 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
sidebarRows = (id: number) => {
|
const sidebarRows = (id: number) => {
|
||||||
let availableFreqTitle = 'Scaling Available Frequencies';
|
let availableFreqTitle = 'Scaling Available Frequencies';
|
||||||
const selected = this.state.cpuFreq[id];
|
const selected = cpuState.cpuFreq[id];
|
||||||
if (selected.scaling_available_freqs.length > 0) {
|
if (selected.scaling_available_freqs.length > 0) {
|
||||||
availableFreqTitle +=
|
availableFreqTitle +=
|
||||||
' (' + selected.scaling_available_freqs.length.toString() + ')';
|
' (' + selected.scaling_available_freqs.length.toString() + ')';
|
||||||
@@ -536,19 +593,19 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
const keys = [availableFreqTitle, 'Scaling Available Governors'];
|
const keys = [availableFreqTitle, 'Scaling Available Governors'];
|
||||||
|
|
||||||
const vals = [
|
const vals = [
|
||||||
this.buildAvailableFreqList(selected),
|
buildAvailableFreqList(selected),
|
||||||
this.buildAvailableGovList(selected),
|
buildAvailableGovList(selected),
|
||||||
];
|
];
|
||||||
return keys.map<any>((key, idx) => {
|
return keys.map<any>((key, idx) => {
|
||||||
return this.buildSidebarRow(key, vals[idx]);
|
return buildSidebarRow(key, vals[idx]);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
renderCPUSidebar = () => {
|
const renderCPUSidebar = () => {
|
||||||
if (!this.state.displayCPUDetail || this.state.selectedIds.length == 0) {
|
if (!cpuState.displayCPUDetail || selectedIds.length == 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const id = this.state.selectedIds[0];
|
const id = selectedIds[0];
|
||||||
const cols = {
|
const cols = {
|
||||||
key: {
|
key: {
|
||||||
value: 'key',
|
value: 'key',
|
||||||
@@ -565,12 +622,7 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<DetailSidebar width={500}>
|
<DetailSidebar width={500}>
|
||||||
<Panel
|
<Panel pad={theme.space.small} title="CPU details">
|
||||||
padded={true}
|
|
||||||
heading="CPU details"
|
|
||||||
floating={false}
|
|
||||||
collapsable={true}
|
|
||||||
grow={true}>
|
|
||||||
<Heading>CPU_{id}</Heading>
|
<Heading>CPU_{id}</Heading>
|
||||||
<ManagedTable
|
<ManagedTable
|
||||||
columnSizes={colSizes}
|
columnSizes={colSizes}
|
||||||
@@ -579,27 +631,22 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
autoHeight={true}
|
autoHeight={true}
|
||||||
floating={false}
|
floating={false}
|
||||||
zebra={true}
|
zebra={true}
|
||||||
rows={this.sidebarRows(id)}
|
rows={sidebarRows(id)}
|
||||||
/>
|
/>
|
||||||
</Panel>
|
</Panel>
|
||||||
</DetailSidebar>
|
</DetailSidebar>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderThermalSidebar = () => {
|
const renderThermalSidebar = () => {
|
||||||
if (!this.state.displayThermalInfo) {
|
if (!cpuState.displayThermalInfo) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<DetailSidebar width={500}>
|
<DetailSidebar width={500}>
|
||||||
<Panel
|
<Panel pad={theme.space.small} title="Thermal Information">
|
||||||
padded={true}
|
{cpuState.thermalAccessible ? (
|
||||||
heading="Thermal Information"
|
<TemperatureTable temperatureMap={cpuState.temperatureMap} />
|
||||||
floating={false}
|
|
||||||
collapsable={true}
|
|
||||||
grow={false}>
|
|
||||||
{this.state.thermalAccessible ? (
|
|
||||||
<TemperatureTable temperatureMap={this.state.temperatureMap} />
|
|
||||||
) : (
|
) : (
|
||||||
'Temperature information not accessible on this device.'
|
'Temperature information not accessible on this device.'
|
||||||
)}
|
)}
|
||||||
@@ -608,76 +655,50 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleThermalSidebar = () => {
|
return (
|
||||||
if (!this.state.displayThermalInfo) {
|
<Panel pad={theme.space.small} title="CPU info">
|
||||||
this.readThermalZones();
|
<Toolbar position="top">
|
||||||
}
|
{cpuState.monitoring ? (
|
||||||
this.setState({
|
<Button onClick={onStopMonitor} icon={<PauseCircleOutlined />}>
|
||||||
displayThermalInfo: !this.state.displayThermalInfo,
|
Pause
|
||||||
displayCPUDetail: false,
|
</Button>
|
||||||
});
|
) : (
|
||||||
};
|
<Button onClick={onStartMonitor} icon={<PlayCircleOutlined />}>
|
||||||
|
Start
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
{cpuState.hardwareInfo}
|
||||||
|
<ToggleButton
|
||||||
|
toggled={cpuState.displayThermalInfo}
|
||||||
|
onClick={toggleThermalSidebar}
|
||||||
|
/>
|
||||||
|
Thermal Information
|
||||||
|
<ToggleButton
|
||||||
|
onClick={toggleCPUSidebar}
|
||||||
|
toggled={cpuState.displayCPUDetail}
|
||||||
|
/>
|
||||||
|
CPU Details
|
||||||
|
{cpuState.displayCPUDetail &&
|
||||||
|
selectedIds.length == 0 &&
|
||||||
|
' (Please select a core in the table below)'}
|
||||||
|
</Toolbar>
|
||||||
|
|
||||||
toggleCPUSidebar = () => {
|
<Layout.Container grow={true}>
|
||||||
this.setState({
|
<ManagedTable
|
||||||
displayCPUDetail: !this.state.displayCPUDetail,
|
multiline={true}
|
||||||
displayThermalInfo: false,
|
columnSizes={ColumnSizes}
|
||||||
});
|
columns={Columns}
|
||||||
};
|
autoHeight={true}
|
||||||
|
floating={false}
|
||||||
render() {
|
zebra={true}
|
||||||
return (
|
rows={frequencyRows(cpuState.cpuFreq)}
|
||||||
<Panel
|
onRowHighlighted={(selectedIds) => {
|
||||||
padded={false}
|
setSelectedIds(selectedIds.map(parseInt));
|
||||||
heading="CPU info"
|
}}
|
||||||
floating={false}
|
/>
|
||||||
collapsable={false}
|
{renderCPUSidebar()}
|
||||||
grow={true}>
|
{renderThermalSidebar()}
|
||||||
<Toolbar position="top">
|
</Layout.Container>
|
||||||
{this.state.monitoring ? (
|
</Panel>
|
||||||
<Button onClick={this.onStopMonitor} icon="pause">
|
);
|
||||||
Pause
|
|
||||||
</Button>
|
|
||||||
) : (
|
|
||||||
<Button onClick={this.onStartMonitor} icon="play">
|
|
||||||
Start
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
{this.state.hardwareInfo}
|
|
||||||
<ToggleButton
|
|
||||||
toggled={this.state.displayThermalInfo}
|
|
||||||
onClick={this.toggleThermalSidebar}
|
|
||||||
/>
|
|
||||||
Thermal Information
|
|
||||||
<ToggleButton
|
|
||||||
onClick={this.toggleCPUSidebar}
|
|
||||||
toggled={this.state.displayCPUDetail}
|
|
||||||
/>
|
|
||||||
CPU Details
|
|
||||||
{this.state.displayCPUDetail &&
|
|
||||||
this.state.selectedIds.length == 0 &&
|
|
||||||
' (Please select a core in the table below)'}
|
|
||||||
</Toolbar>
|
|
||||||
|
|
||||||
<FlexColumn grow={true}>
|
|
||||||
<ManagedTable
|
|
||||||
multiline={true}
|
|
||||||
columnSizes={ColumnSizes}
|
|
||||||
columns={Columns}
|
|
||||||
autoHeight={true}
|
|
||||||
floating={false}
|
|
||||||
zebra={true}
|
|
||||||
rows={this.frequencyRows(this.state.cpuFreq)}
|
|
||||||
onRowHighlighted={(selectedIds) => {
|
|
||||||
this.setState({
|
|
||||||
selectedIds: selectedIds.map(parseInt),
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{this.renderCPUSidebar()}
|
|
||||||
{this.renderThermalSidebar()}
|
|
||||||
</FlexColumn>
|
|
||||||
</Panel>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,13 +10,16 @@
|
|||||||
"archived": false
|
"archived": false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": "0.0.0",
|
"version": "0.0.1",
|
||||||
"main": "dist/bundle.js",
|
"main": "dist/bundle.js",
|
||||||
"flipperBundlerEntry": "index.tsx",
|
"flipperBundlerEntry": "index.tsx",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"flipper-plugin"
|
"flipper-plugin"
|
||||||
],
|
],
|
||||||
|
"peerDependencies": {
|
||||||
|
"flipper-plugin": "*"
|
||||||
|
},
|
||||||
"title": "CPU",
|
"title": "CPU",
|
||||||
"icon": "underline",
|
"icon": "underline",
|
||||||
"bugs": {
|
"bugs": {
|
||||||
|
|||||||
Reference in New Issue
Block a user