Flipper CPU Plugin: Thermal Information
Summary: display thermal information of connected device in the CPU plugin on a sidebar Reviewed By: charles011 Differential Revision: D15715680 fbshipit-source-id: 1216da7bf8e0e6277d06aa02f40e6278f8e7fa07
This commit is contained in:
committed by
Facebook Github Bot
parent
b0f44d9a9b
commit
b41c4967a8
73
src/plugins/cpu/TemperatureTable.js
Normal file
73
src/plugins/cpu/TemperatureTable.js
Normal file
@@ -0,0 +1,73 @@
|
||||
/**
|
||||
* 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 {Component, Text, SearchableTable} from 'flipper';
|
||||
|
||||
const ColumnSizes = {
|
||||
thermal_zone: 'flex',
|
||||
temperature: 'flex',
|
||||
path: 'flex',
|
||||
};
|
||||
|
||||
const Columns = {
|
||||
thermal_zone: {
|
||||
value: 'Thermal Zone',
|
||||
resizable: true,
|
||||
},
|
||||
temperature: {
|
||||
value: 'Temperature',
|
||||
resizable: true,
|
||||
},
|
||||
path: {
|
||||
value: 'Path',
|
||||
resizable: true,
|
||||
},
|
||||
};
|
||||
|
||||
type TemperatureTableProps = {
|
||||
temperatureMap: any,
|
||||
};
|
||||
|
||||
export default class TemperatureTable extends Component<TemperatureTableProps> {
|
||||
buildRow = (tz: string, tempInfo: any) => {
|
||||
return {
|
||||
columns: {
|
||||
thermal_zone: {value: <Text>{tz}</Text>},
|
||||
temperature: {
|
||||
value: <Text>{tempInfo.temp.toString()}</Text>,
|
||||
},
|
||||
path: {
|
||||
value: <Text>{tempInfo.path}</Text>,
|
||||
},
|
||||
},
|
||||
key: tz,
|
||||
};
|
||||
};
|
||||
|
||||
buildRows = () => {
|
||||
let rows = [];
|
||||
for (const tz of Object.keys(this.props.temperatureMap).sort()) {
|
||||
rows.push(this.buildRow(tz, this.props.temperatureMap[tz]));
|
||||
}
|
||||
return rows;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SearchableTable
|
||||
multiline={true}
|
||||
autoHeight={true}
|
||||
floating={false}
|
||||
zebra={true}
|
||||
columnSizes={ColumnSizes}
|
||||
columns={Columns}
|
||||
rows={this.buildRows()}
|
||||
grow={true}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,10 +7,10 @@
|
||||
|
||||
import {FlipperDevicePlugin, Device} from 'flipper';
|
||||
var adb = require('adbkit-fb');
|
||||
import TemperatureTable from './TemperatureTable.js';
|
||||
|
||||
import {
|
||||
FlexColumn,
|
||||
FlexRow,
|
||||
Button,
|
||||
Toolbar,
|
||||
Text,
|
||||
@@ -19,6 +19,7 @@ import {
|
||||
styled,
|
||||
Panel,
|
||||
DetailSidebar,
|
||||
ToggleButton,
|
||||
} from 'flipper';
|
||||
|
||||
type ADBClient = any;
|
||||
@@ -46,9 +47,13 @@ type CPUState = {|
|
||||
monitoring: boolean,
|
||||
hardwareInfo: string,
|
||||
selectedIds: Array<number>,
|
||||
temperatureMap: any,
|
||||
thermalAccessible: boolean,
|
||||
displayThermalInfo: boolean,
|
||||
displayCPUDetail: boolean,
|
||||
|};
|
||||
|
||||
type ShellCallBack = (output: string) => void;
|
||||
type ShellCallBack = (output: string) => any;
|
||||
|
||||
const ColumnSizes = {
|
||||
cpu_id: '10%',
|
||||
@@ -129,6 +134,10 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
monitoring: false,
|
||||
hardwareInfo: '',
|
||||
selectedIds: [],
|
||||
temperatureMap: {},
|
||||
thermalAccessible: true,
|
||||
displayThermalInfo: false,
|
||||
displayCPUDetail: true,
|
||||
};
|
||||
|
||||
static supportsDevice(device: Device) {
|
||||
@@ -140,6 +149,7 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
this.adbClient = device.adb;
|
||||
|
||||
this.updateHardwareInfo();
|
||||
this.readThermalZones();
|
||||
|
||||
// check how many cores we have on this device
|
||||
this.executeShell((output: string) => {
|
||||
@@ -167,7 +177,7 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
}
|
||||
|
||||
executeShell = (callback: ShellCallBack, command: string) => {
|
||||
this.adbClient
|
||||
return this.adbClient
|
||||
.shell(this.device.serial, command)
|
||||
.then(adb.util.readAll)
|
||||
.then(function(output) {
|
||||
@@ -215,7 +225,11 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
updateCoreGovernor = (core: number) => {
|
||||
this.executeShell((output: string) => {
|
||||
let cpuFreq = this.state.cpuFreq;
|
||||
cpuFreq[core].scaling_governor = output;
|
||||
if (output.toLowerCase().includes('no such file')) {
|
||||
cpuFreq[core].scaling_governor = 'N/A';
|
||||
} else {
|
||||
cpuFreq[core].scaling_governor = output;
|
||||
}
|
||||
this.setState({
|
||||
cpuFreq: cpuFreq,
|
||||
});
|
||||
@@ -281,10 +295,54 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
}, 'getprop ro.board.platform');
|
||||
};
|
||||
|
||||
readThermalZones = () => {
|
||||
let thermal_dir = '/sys/class/thermal/';
|
||||
let map = {};
|
||||
this.executeShell(async (output: string) => {
|
||||
if (output.toLowerCase().includes('permission denied')) {
|
||||
this.setState({thermalAccessible: false});
|
||||
return;
|
||||
}
|
||||
let dirs = output.split(/\s/);
|
||||
let promises = [];
|
||||
for (let d of dirs) {
|
||||
d = d.trim();
|
||||
if (d.length == 0) {
|
||||
continue;
|
||||
}
|
||||
let path = thermal_dir + d;
|
||||
promises.push(this.readThermalZone(path, d, map));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
this.setState({temperatureMap: map, thermalAccessible: true});
|
||||
if (this.state.displayThermalInfo) {
|
||||
setTimeout(this.readThermalZones, 1000);
|
||||
}
|
||||
}, 'ls ' + thermal_dir);
|
||||
};
|
||||
|
||||
readThermalZone = (path: string, dir: string, map: any) => {
|
||||
return this.executeShell((type: string) => {
|
||||
if (type.length == 0) {
|
||||
return;
|
||||
}
|
||||
return this.executeShell((temp: string) => {
|
||||
if (isNaN(temp)) {
|
||||
return;
|
||||
}
|
||||
map[type] = {
|
||||
path: dir,
|
||||
temp: parseInt(temp, 10),
|
||||
};
|
||||
}, 'cat ' + path + '/temp');
|
||||
}, 'cat ' + path + '/type');
|
||||
};
|
||||
|
||||
onStartMonitor = () => {
|
||||
if (this.intervalID) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.state.cpuCount; ++i) {
|
||||
this.readAvailableGovernors(i);
|
||||
}
|
||||
@@ -354,7 +412,6 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
style = {
|
||||
style: {
|
||||
backgroundColor: selected ? colors.red : colors.redTint,
|
||||
// better visibility when highlighted
|
||||
color: colors.red,
|
||||
fontWeight: 700,
|
||||
},
|
||||
@@ -479,8 +536,8 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
});
|
||||
};
|
||||
|
||||
renderSidebar = () => {
|
||||
if (this.state.selectedIds.length == 0) {
|
||||
renderCPUSidebar = () => {
|
||||
if (!this.state.displayCPUDetail || this.state.selectedIds.length == 0) {
|
||||
return null;
|
||||
}
|
||||
let id = this.state.selectedIds[0];
|
||||
@@ -504,7 +561,8 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
padded={true}
|
||||
heading="CPU details"
|
||||
floating={false}
|
||||
collapsable={true}>
|
||||
collapsable={true}
|
||||
grow={true}>
|
||||
<Heading>CPU_{id}</Heading>
|
||||
<ManagedTable
|
||||
columnSizes={colSizes}
|
||||
@@ -520,22 +578,81 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
);
|
||||
};
|
||||
|
||||
renderThermalSidebar = () => {
|
||||
if (!this.state.displayThermalInfo) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<DetailSidebar width={500}>
|
||||
<Panel
|
||||
padded={true}
|
||||
heading="Thermal Information"
|
||||
floating={false}
|
||||
collapsable={true}
|
||||
grow={false}>
|
||||
{this.state.thermalAccessible ? (
|
||||
<TemperatureTable temperatureMap={this.state.temperatureMap} />
|
||||
) : (
|
||||
'Temperature information not accessible on this device.'
|
||||
)}
|
||||
</Panel>
|
||||
</DetailSidebar>
|
||||
);
|
||||
};
|
||||
|
||||
toggleThermalSidebar = () => {
|
||||
if (!this.state.displayThermalInfo) {
|
||||
this.readThermalZones();
|
||||
}
|
||||
this.setState({
|
||||
displayThermalInfo: !this.state.displayThermalInfo,
|
||||
displayCPUDetail: false,
|
||||
});
|
||||
};
|
||||
|
||||
toggleCPUSidebar = () => {
|
||||
this.setState({
|
||||
displayCPUDetail: !this.state.displayCPUDetail,
|
||||
displayThermalInfo: false,
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<FlexRow>
|
||||
<Panel
|
||||
padded={false}
|
||||
heading="CPU info"
|
||||
floating={false}
|
||||
collapsable={false}
|
||||
grow={true}>
|
||||
<Toolbar position="top">
|
||||
{this.state.monitoring ? (
|
||||
<Button onClick={this.onStopMonitor} icon="pause">
|
||||
Pause
|
||||
</Button>
|
||||
) : (
|
||||
<Button onClick={this.onStartMonitor} icon="play">
|
||||
Start
|
||||
</Button>
|
||||
)}
|
||||
{this.state.hardwareInfo}
|
||||
<ToggleButton
|
||||
position="right"
|
||||
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}>
|
||||
<Toolbar position="top">
|
||||
{this.state.monitoring ? (
|
||||
<Button onClick={this.onStopMonitor} icon="pause">
|
||||
Pause
|
||||
</Button>
|
||||
) : (
|
||||
<Button onClick={this.onStartMonitor} icon="play">
|
||||
Start
|
||||
</Button>
|
||||
)}
|
||||
{this.state.hardwareInfo}
|
||||
</Toolbar>
|
||||
<ManagedTable
|
||||
multiline={true}
|
||||
columnSizes={ColumnSizes}
|
||||
@@ -550,10 +667,10 @@ export default class CPUFrequencyTable extends FlipperDevicePlugin<CPUState> {
|
||||
});
|
||||
}}
|
||||
/>
|
||||
|
||||
{this.renderSidebar()}
|
||||
{this.renderCPUSidebar()}
|
||||
{this.renderThermalSidebar()}
|
||||
</FlexColumn>
|
||||
</FlexRow>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user