Finish converting CPU plugin to Sandy
Summary: Finishes off by converting the rest of the UI. Reviewed By: mweststrate Differential Revision: D28061468 fbshipit-source-id: 8d87d3344fe3937470e566d8c425efc97f38333c
This commit is contained in:
committed by
Facebook GitHub Bot
parent
92f51485c9
commit
303e42535c
@@ -15,23 +15,16 @@ import {
|
|||||||
Panel,
|
Panel,
|
||||||
theme,
|
theme,
|
||||||
Layout,
|
Layout,
|
||||||
|
DetailSidebar,
|
||||||
|
DataTable,
|
||||||
|
DataTableColumn,
|
||||||
} from 'flipper-plugin';
|
} 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 {Button, Typography, Switch} from 'antd';
|
||||||
import {PlayCircleOutlined, PauseCircleOutlined} from '@ant-design/icons';
|
import {PlayCircleOutlined, PauseCircleOutlined} from '@ant-design/icons';
|
||||||
|
|
||||||
import {
|
import React, {useCallback, useState} from 'react';
|
||||||
Toolbar,
|
|
||||||
ManagedTable,
|
|
||||||
colors,
|
|
||||||
styled,
|
|
||||||
DetailSidebar,
|
|
||||||
ToggleButton,
|
|
||||||
} from 'flipper';
|
|
||||||
import React, {useState} from 'react';
|
|
||||||
|
|
||||||
type TableRows = any;
|
|
||||||
|
|
||||||
// we keep vairable name with underline for to physical path mappings on device
|
// we keep vairable name with underline for to physical path mappings on device
|
||||||
type CPUFrequency = {
|
type CPUFrequency = {
|
||||||
@@ -60,56 +53,6 @@ type CPUState = {
|
|||||||
|
|
||||||
type ShellCallBack = (output: string) => any;
|
type ShellCallBack = (output: string) => any;
|
||||||
|
|
||||||
const ColumnSizes = {
|
|
||||||
cpu_id: '10%',
|
|
||||||
scaling_cur_freq: 'flex',
|
|
||||||
scaling_min_freq: 'flex',
|
|
||||||
scaling_max_freq: 'flex',
|
|
||||||
cpuinfo_min_freq: 'flex',
|
|
||||||
cpuinfo_max_freq: 'flex',
|
|
||||||
};
|
|
||||||
|
|
||||||
const Columns = {
|
|
||||||
cpu_id: {
|
|
||||||
value: 'CPU ID',
|
|
||||||
resizable: true,
|
|
||||||
},
|
|
||||||
scaling_cur_freq: {
|
|
||||||
value: 'Scaling Current',
|
|
||||||
resizable: true,
|
|
||||||
},
|
|
||||||
scaling_min_freq: {
|
|
||||||
value: 'Scaling MIN',
|
|
||||||
resizable: true,
|
|
||||||
},
|
|
||||||
scaling_max_freq: {
|
|
||||||
value: 'Scaling MAX',
|
|
||||||
resizable: true,
|
|
||||||
},
|
|
||||||
cpuinfo_min_freq: {
|
|
||||||
value: 'MIN Frequency',
|
|
||||||
resizable: true,
|
|
||||||
},
|
|
||||||
cpuinfo_max_freq: {
|
|
||||||
value: 'MAX Frequency',
|
|
||||||
resizable: true,
|
|
||||||
},
|
|
||||||
scaling_governor: {
|
|
||||||
value: 'Scaling Governor',
|
|
||||||
resizable: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const Heading = styled.div({
|
|
||||||
fontWeight: 'bold',
|
|
||||||
fontSize: 13,
|
|
||||||
display: 'block',
|
|
||||||
marginBottom: 10,
|
|
||||||
'&:not(:first-child)': {
|
|
||||||
marginTop: 20,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// check if str is a number
|
// check if str is a number
|
||||||
function isNormalInteger(str: string) {
|
function isNormalInteger(str: string) {
|
||||||
const n = Math.floor(Number(str));
|
const n = Math.floor(Number(str));
|
||||||
@@ -328,10 +271,14 @@ export function devicePlugin(client: PluginClient<{}, {}>) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onStartMonitor = () => {
|
const onStartMonitor = () => {
|
||||||
if (intervalID) {
|
if (cpuState.get().monitoring) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpuState.update((draft) => {
|
||||||
|
draft.monitoring = true;
|
||||||
|
});
|
||||||
|
|
||||||
for (let i = 0; i < cpuState.get().cpuCount; ++i) {
|
for (let i = 0; i < cpuState.get().cpuCount; ++i) {
|
||||||
readAvailableGovernors(i).then((output) => {
|
readAvailableGovernors(i).then((output) => {
|
||||||
cpuState.update((draft) => {
|
cpuState.update((draft) => {
|
||||||
@@ -341,6 +288,9 @@ export function devicePlugin(client: PluginClient<{}, {}>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const update = async () => {
|
const update = async () => {
|
||||||
|
if (!cpuState.get().monitoring) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const promises = [];
|
const promises = [];
|
||||||
for (let i = 0; i < cpuState.get().cpuCount; ++i) {
|
for (let i = 0; i < cpuState.get().cpuCount; ++i) {
|
||||||
promises.push(readCoreFrequency(i));
|
promises.push(readCoreFrequency(i));
|
||||||
@@ -352,23 +302,15 @@ export function devicePlugin(client: PluginClient<{}, {}>) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
intervalID = setTimeout(update, 500);
|
intervalID = setTimeout(update, 500);
|
||||||
cpuState.update((draft) => {
|
|
||||||
draft.monitoring = true;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onStopMonitor = () => {
|
const onStopMonitor = () => {
|
||||||
if (!intervalID) {
|
intervalID && clearInterval(intervalID);
|
||||||
return;
|
intervalID = null;
|
||||||
} else {
|
cpuState.update((draft) => {
|
||||||
clearInterval(intervalID);
|
draft.monitoring = false;
|
||||||
intervalID = null;
|
return draft;
|
||||||
cpuState.update((draft) => {
|
});
|
||||||
draft.monitoring = false;
|
|
||||||
return draft;
|
|
||||||
});
|
|
||||||
cleanup();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const cleanup = () => {
|
const cleanup = () => {
|
||||||
@@ -450,6 +392,59 @@ export function devicePlugin(client: PluginClient<{}, {}>) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const columns: DataTableColumn[] = [
|
||||||
|
{key: 'cpu_id', title: 'CPU ID'},
|
||||||
|
{key: 'scaling_cur_freq', title: 'Current Frequency'},
|
||||||
|
{key: 'scaling_min_freq', title: 'Scaling min'},
|
||||||
|
{key: 'scaling_max_freq', title: 'Scaling max'},
|
||||||
|
{key: 'cpuinfo_min_freq', title: 'CPU min'},
|
||||||
|
{key: 'cpuinfo_max_freq', title: 'CPU max'},
|
||||||
|
{key: 'scaling_governor', title: 'Scaling governor'},
|
||||||
|
];
|
||||||
|
|
||||||
|
const cpuSidebarColumns: DataTableColumn[] = [
|
||||||
|
{
|
||||||
|
key: 'key',
|
||||||
|
title: 'key',
|
||||||
|
wrap: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'value',
|
||||||
|
title: 'value',
|
||||||
|
wrap: true,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const getRowStyle = (freq: CPUFrequency) => {
|
||||||
|
if (freq.scaling_cur_freq == -2) {
|
||||||
|
return {
|
||||||
|
backgroundColor: theme.backgroundWash,
|
||||||
|
color: theme.textColorPrimary,
|
||||||
|
fontWeight: 700,
|
||||||
|
};
|
||||||
|
} else if (
|
||||||
|
freq.scaling_min_freq != freq.cpuinfo_min_freq &&
|
||||||
|
freq.scaling_min_freq > 0 &&
|
||||||
|
freq.cpuinfo_min_freq > 0
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
backgroundColor: theme.warningColor,
|
||||||
|
color: theme.textColorPrimary,
|
||||||
|
fontWeight: 700,
|
||||||
|
};
|
||||||
|
} else if (
|
||||||
|
freq.scaling_max_freq != freq.cpuinfo_max_freq &&
|
||||||
|
freq.scaling_max_freq > 0 &&
|
||||||
|
freq.cpuinfo_max_freq > 0
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
backgroundColor: theme.backgroundWash,
|
||||||
|
color: theme.textColorSecondary,
|
||||||
|
fontWeight: 700,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export function Component() {
|
export function Component() {
|
||||||
const instance = usePlugin(devicePlugin);
|
const instance = usePlugin(devicePlugin);
|
||||||
const {
|
const {
|
||||||
@@ -463,92 +458,20 @@ export function Component() {
|
|||||||
|
|
||||||
const [selectedIds, setSelectedIds] = useState<number[]>([]);
|
const [selectedIds, setSelectedIds] = useState<number[]>([]);
|
||||||
|
|
||||||
const buildRow = (freq: CPUFrequency, idx: number) => {
|
const buildRow = (freq: CPUFrequency) => {
|
||||||
const selected = selectedIds.indexOf(idx) >= 0;
|
|
||||||
let style = {};
|
|
||||||
if (freq.scaling_cur_freq == -2) {
|
|
||||||
style = {
|
|
||||||
style: {
|
|
||||||
backgroundColor: colors.blueTint30,
|
|
||||||
color: colors.white,
|
|
||||||
fontWeight: 700,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} else if (
|
|
||||||
freq.scaling_min_freq != freq.cpuinfo_min_freq &&
|
|
||||||
freq.scaling_min_freq > 0 &&
|
|
||||||
freq.cpuinfo_min_freq > 0
|
|
||||||
) {
|
|
||||||
style = {
|
|
||||||
style: {
|
|
||||||
backgroundColor: selected ? colors.red : colors.redTint,
|
|
||||||
color: colors.red,
|
|
||||||
fontWeight: 700,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
} else if (
|
|
||||||
freq.scaling_max_freq != freq.cpuinfo_max_freq &&
|
|
||||||
freq.scaling_max_freq > 0 &&
|
|
||||||
freq.cpuinfo_max_freq > 0
|
|
||||||
) {
|
|
||||||
style = {
|
|
||||||
style: {
|
|
||||||
backgroundColor: colors.yellowTint,
|
|
||||||
color: colors.yellow,
|
|
||||||
fontWeight: 700,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
columns: {
|
core: freq.cpu_id,
|
||||||
cpu_id: {value: <Typography.Text>CPU_{freq.cpu_id}</Typography.Text>},
|
cpu_id: `CPU_${freq.cpu_id}`,
|
||||||
scaling_cur_freq: {
|
scaling_cur_freq: formatFrequency(freq.scaling_cur_freq),
|
||||||
value: (
|
scaling_min_freq: formatFrequency(freq.scaling_min_freq),
|
||||||
<Typography.Text>
|
scaling_max_freq: formatFrequency(freq.scaling_max_freq),
|
||||||
{formatFrequency(freq.scaling_cur_freq)}
|
cpuinfo_min_freq: formatFrequency(freq.cpuinfo_min_freq),
|
||||||
</Typography.Text>
|
cpuinfo_max_freq: formatFrequency(freq.cpuinfo_max_freq),
|
||||||
),
|
scaling_governor: freq.scaling_governor,
|
||||||
},
|
|
||||||
scaling_min_freq: {
|
|
||||||
value: (
|
|
||||||
<Typography.Text>
|
|
||||||
{formatFrequency(freq.scaling_min_freq)}
|
|
||||||
</Typography.Text>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
scaling_max_freq: {
|
|
||||||
value: (
|
|
||||||
<Typography.Text>
|
|
||||||
{formatFrequency(freq.scaling_max_freq)}
|
|
||||||
</Typography.Text>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
cpuinfo_min_freq: {
|
|
||||||
value: (
|
|
||||||
<Typography.Text>
|
|
||||||
{formatFrequency(freq.cpuinfo_min_freq)}
|
|
||||||
</Typography.Text>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
cpuinfo_max_freq: {
|
|
||||||
value: (
|
|
||||||
<Typography.Text>
|
|
||||||
{formatFrequency(freq.cpuinfo_max_freq)}
|
|
||||||
</Typography.Text>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
scaling_governor: {
|
|
||||||
value: <Typography.Text>{freq.scaling_governor}</Typography.Text>,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
key: freq.cpu_id,
|
|
||||||
|
|
||||||
style,
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const frequencyRows = (cpuFreqs: Array<CPUFrequency>): TableRows => {
|
const frequencyRows = (cpuFreqs: Array<CPUFrequency>) => {
|
||||||
return cpuFreqs.map(buildRow);
|
return cpuFreqs.map(buildRow);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -560,28 +483,24 @@ export function Component() {
|
|||||||
return (
|
return (
|
||||||
<Typography.Text>
|
<Typography.Text>
|
||||||
{freq.scaling_available_freqs.map((freq, idx) => {
|
{freq.scaling_available_freqs.map((freq, idx) => {
|
||||||
const style: React.CSSProperties = {};
|
const bold =
|
||||||
if (
|
|
||||||
freq == info.scaling_cur_freq ||
|
freq == info.scaling_cur_freq ||
|
||||||
freq == info.scaling_min_freq ||
|
freq == info.scaling_min_freq ||
|
||||||
freq == info.scaling_max_freq
|
freq == info.scaling_max_freq;
|
||||||
) {
|
|
||||||
style.fontWeight = 'bold';
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<Typography.Text key={idx} style={style}>
|
<Typography.Text key={idx} strong={bold}>
|
||||||
{formatFrequency(freq)}
|
{formatFrequency(freq)}
|
||||||
{freq == info.scaling_cur_freq && (
|
{freq == info.scaling_cur_freq && (
|
||||||
<Typography.Text style={style}>
|
<Typography.Text strong={bold}>
|
||||||
{' '}
|
{' '}
|
||||||
(scaling current)
|
(scaling current)
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
)}
|
)}
|
||||||
{freq == info.scaling_min_freq && (
|
{freq == info.scaling_min_freq && (
|
||||||
<Typography.Text style={style}> (scaling min)</Typography.Text>
|
<Typography.Text strong={bold}> (scaling min)</Typography.Text>
|
||||||
)}
|
)}
|
||||||
{freq == info.scaling_max_freq && (
|
{freq == info.scaling_max_freq && (
|
||||||
<Typography.Text style={style}> (scaling max)</Typography.Text>
|
<Typography.Text strong={bold}> (scaling max)</Typography.Text>
|
||||||
)}
|
)}
|
||||||
<br />
|
<br />
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
@@ -600,13 +519,8 @@ export function Component() {
|
|||||||
|
|
||||||
const buildSidebarRow = (key: string, val: any) => {
|
const buildSidebarRow = (key: string, val: any) => {
|
||||||
return {
|
return {
|
||||||
columns: {
|
|
||||||
key: {value: <Typography.Text>{key}</Typography.Text>},
|
|
||||||
value: {
|
|
||||||
value: val,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
key: key,
|
key: key,
|
||||||
|
value: val,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -634,34 +548,14 @@ export function Component() {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const id = selectedIds[0];
|
const id = selectedIds[0];
|
||||||
const cols = {
|
|
||||||
key: {
|
|
||||||
value: 'key',
|
|
||||||
resizable: true,
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
value: 'value',
|
|
||||||
resizable: true,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const colSizes = {
|
|
||||||
key: '35%',
|
|
||||||
value: 'flex',
|
|
||||||
};
|
|
||||||
return (
|
return (
|
||||||
<DetailSidebar width={500}>
|
<DetailSidebar width={500}>
|
||||||
<Panel pad={theme.space.small} title="CPU details">
|
<Typography.Title>CPU Details: CPU_{id}</Typography.Title>
|
||||||
<Heading>CPU_{id}</Heading>
|
<DataTable
|
||||||
<ManagedTable
|
records={sidebarRows(id)}
|
||||||
columnSizes={colSizes}
|
columns={cpuSidebarColumns}
|
||||||
multiline={true}
|
scrollable={false}
|
||||||
columns={cols}
|
/>
|
||||||
autoHeight={true}
|
|
||||||
floating={false}
|
|
||||||
zebra={true}
|
|
||||||
rows={sidebarRows(id)}
|
|
||||||
/>
|
|
||||||
</Panel>
|
|
||||||
</DetailSidebar>
|
</DetailSidebar>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -672,7 +566,10 @@ export function Component() {
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<DetailSidebar width={500}>
|
<DetailSidebar width={500}>
|
||||||
<Panel pad={theme.space.small} title="Thermal Information">
|
<Panel
|
||||||
|
pad={theme.space.small}
|
||||||
|
title="Thermal Information"
|
||||||
|
collapsible={false}>
|
||||||
{cpuState.thermalAccessible ? (
|
{cpuState.thermalAccessible ? (
|
||||||
<TemperatureTable temperatureMap={cpuState.temperatureMap} />
|
<TemperatureTable temperatureMap={cpuState.temperatureMap} />
|
||||||
) : (
|
) : (
|
||||||
@@ -683,9 +580,14 @@ export function Component() {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const setSelected = useCallback((selected: any) => {
|
||||||
|
setSelectedIds(selected ? [selected.core] : []);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Panel pad={theme.space.small} title="CPU info">
|
<Layout.Container pad={theme.space.medium}>
|
||||||
<Toolbar position="top">
|
<Typography.Title>CPU Info</Typography.Title>
|
||||||
|
<Layout.Horizontal gap={theme.space.small} center>
|
||||||
{cpuState.monitoring ? (
|
{cpuState.monitoring ? (
|
||||||
<Button onClick={onStopMonitor} icon={<PauseCircleOutlined />}>
|
<Button onClick={onStopMonitor} icon={<PauseCircleOutlined />}>
|
||||||
Pause
|
Pause
|
||||||
@@ -696,37 +598,30 @@ export function Component() {
|
|||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{cpuState.hardwareInfo}
|
{cpuState.hardwareInfo}
|
||||||
<ToggleButton
|
<Switch
|
||||||
toggled={cpuState.displayThermalInfo}
|
checked={cpuState.displayThermalInfo}
|
||||||
onClick={toggleThermalSidebar}
|
onClick={toggleThermalSidebar}
|
||||||
/>
|
/>
|
||||||
Thermal Information
|
Thermal Information
|
||||||
<ToggleButton
|
<Switch
|
||||||
onClick={toggleCPUSidebar}
|
onClick={toggleCPUSidebar}
|
||||||
toggled={cpuState.displayCPUDetail}
|
checked={cpuState.displayCPUDetail}
|
||||||
/>
|
/>
|
||||||
CPU Details
|
CPU Details
|
||||||
{cpuState.displayCPUDetail &&
|
{cpuState.displayCPUDetail &&
|
||||||
selectedIds.length == 0 &&
|
selectedIds.length == 0 &&
|
||||||
' (Please select a core in the table below)'}
|
' (Please select a core in the table below)'}
|
||||||
</Toolbar>
|
</Layout.Horizontal>
|
||||||
|
|
||||||
<Layout.Container grow={true}>
|
<DataTable
|
||||||
<ManagedTable
|
records={frequencyRows(cpuState.cpuFreq)}
|
||||||
multiline={true}
|
columns={columns}
|
||||||
columnSizes={ColumnSizes}
|
scrollable={false}
|
||||||
columns={Columns}
|
onSelect={setSelected}
|
||||||
autoHeight={true}
|
onRowStyle={getRowStyle}
|
||||||
floating={false}
|
/>
|
||||||
zebra={true}
|
{renderCPUSidebar()}
|
||||||
rows={frequencyRows(cpuState.cpuFreq)}
|
{renderThermalSidebar()}
|
||||||
onRowHighlighted={(selectedIds) => {
|
</Layout.Container>
|
||||||
setSelectedIds(selectedIds.map(parseInt));
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{renderCPUSidebar()}
|
|
||||||
{renderThermalSidebar()}
|
|
||||||
</Layout.Container>
|
|
||||||
</Panel>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user