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:
John Knox
2021-04-29 07:38:31 -07:00
committed by Facebook GitHub Bot
parent 92f51485c9
commit 303e42535c

View File

@@ -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>
)} )}
&nbsp; {cpuState.hardwareInfo} &nbsp; {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>
); );
} }