feat: add thermal states to powerMonitor (#37935)
* feat: add thermal states to powerMonitor * update docs
This commit is contained in:
parent
b2411e05a8
commit
ba835ddac1
5 changed files with 93 additions and 2 deletions
|
@ -24,6 +24,30 @@ Emitted when the system changes to AC power.
|
||||||
|
|
||||||
Emitted when system changes to battery power.
|
Emitted when system changes to battery power.
|
||||||
|
|
||||||
|
### Event: 'thermal-state-change' _macOS_
|
||||||
|
|
||||||
|
* `state` string - The system's new thermal state. Can be `unknown`, `nominal`, `fair`, `serious`, `critical`.
|
||||||
|
|
||||||
|
Emitted when the thermal state of the system changes. Notification of a change
|
||||||
|
in the thermal status of the system, such as entering a critical temperature
|
||||||
|
range. Depending on the severity, the system might take steps to reduce said
|
||||||
|
temperature, for example, throttling the CPU or switching on the fans if
|
||||||
|
available.
|
||||||
|
|
||||||
|
Apps may react to the new state by reducing expensive computing tasks (e.g.
|
||||||
|
video encoding), or notifying the user. The same state might be received
|
||||||
|
repeatedly.
|
||||||
|
|
||||||
|
See https://developer.apple.com/library/archive/documentation/Performance/Conceptual/power_efficiency_guidelines_osx/RespondToThermalStateChanges.html
|
||||||
|
|
||||||
|
### Event: 'speed-limit-change' _macOS_ _Windows_
|
||||||
|
|
||||||
|
* `limit` number - The operating system's advertised speed limit for CPUs, in percent.
|
||||||
|
|
||||||
|
Notification of a change in the operating system's advertised speed limit for
|
||||||
|
CPUs, in percent. Values below 100 indicate that the system is impairing
|
||||||
|
processing power due to thermal management.
|
||||||
|
|
||||||
### Event: 'shutdown' _Linux_ _macOS_
|
### Event: 'shutdown' _Linux_ _macOS_
|
||||||
|
|
||||||
Emitted when the system is about to reboot or shut down. If the event handler
|
Emitted when the system is about to reboot or shut down. If the event handler
|
||||||
|
@ -55,7 +79,7 @@ The `powerMonitor` module has the following methods:
|
||||||
|
|
||||||
* `idleThreshold` Integer
|
* `idleThreshold` Integer
|
||||||
|
|
||||||
Returns `string` - The system's current state. Can be `active`, `idle`, `locked` or `unknown`.
|
Returns `string` - The system's current idle state. Can be `active`, `idle`, `locked` or `unknown`.
|
||||||
|
|
||||||
Calculate the system idle state. `idleThreshold` is the amount of time (in seconds)
|
Calculate the system idle state. `idleThreshold` is the amount of time (in seconds)
|
||||||
before considered idle. `locked` is available on supported systems only.
|
before considered idle. `locked` is available on supported systems only.
|
||||||
|
@ -66,6 +90,10 @@ Returns `Integer` - Idle time in seconds
|
||||||
|
|
||||||
Calculate system idle time in seconds.
|
Calculate system idle time in seconds.
|
||||||
|
|
||||||
|
### `powerMonitor.getCurrentThermalState()` _macOS_
|
||||||
|
|
||||||
|
Returns `string` - The system's current thermal state. Can be `unknown`, `nominal`, `fair`, `serious`, or `critical`.
|
||||||
|
|
||||||
### `powerMonitor.isOnBatteryPower()`
|
### `powerMonitor.isOnBatteryPower()`
|
||||||
|
|
||||||
Returns `boolean` - Whether the system is on battery power.
|
Returns `boolean` - Whether the system is on battery power.
|
||||||
|
|
|
@ -4,6 +4,7 @@ const {
|
||||||
createPowerMonitor,
|
createPowerMonitor,
|
||||||
getSystemIdleState,
|
getSystemIdleState,
|
||||||
getSystemIdleTime,
|
getSystemIdleTime,
|
||||||
|
getCurrentThermalState,
|
||||||
isOnBatteryPower
|
isOnBatteryPower
|
||||||
} = process._linkedBinding('electron_browser_power_monitor');
|
} = process._linkedBinding('electron_browser_power_monitor');
|
||||||
|
|
||||||
|
@ -40,6 +41,10 @@ class PowerMonitor extends EventEmitter {
|
||||||
return getSystemIdleState(idleThreshold);
|
return getSystemIdleState(idleThreshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getCurrentThermalState () {
|
||||||
|
return getCurrentThermalState();
|
||||||
|
}
|
||||||
|
|
||||||
getSystemIdleTime () {
|
getSystemIdleTime () {
|
||||||
return getSystemIdleTime();
|
return getSystemIdleTime();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,11 @@
|
||||||
|
|
||||||
#include "base/power_monitor/power_monitor.h"
|
#include "base/power_monitor/power_monitor.h"
|
||||||
#include "base/power_monitor/power_monitor_device_source.h"
|
#include "base/power_monitor/power_monitor_device_source.h"
|
||||||
|
#include "base/power_monitor/power_observer.h"
|
||||||
|
#include "gin/data_object_builder.h"
|
||||||
#include "gin/handle.h"
|
#include "gin/handle.h"
|
||||||
#include "shell/browser/browser.h"
|
#include "shell/browser/browser.h"
|
||||||
|
#include "shell/browser/javascript_environment.h"
|
||||||
#include "shell/common/gin_converters/callback_converter.h"
|
#include "shell/common/gin_converters/callback_converter.h"
|
||||||
#include "shell/common/gin_helper/dictionary.h"
|
#include "shell/common/gin_helper/dictionary.h"
|
||||||
#include "shell/common/gin_helper/object_template_builder.h"
|
#include "shell/common/gin_helper/object_template_builder.h"
|
||||||
|
@ -33,6 +36,26 @@ struct Converter<ui::IdleState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct Converter<base::PowerThermalObserver::DeviceThermalState> {
|
||||||
|
static v8::Local<v8::Value> ToV8(
|
||||||
|
v8::Isolate* isolate,
|
||||||
|
const base::PowerThermalObserver::DeviceThermalState& in) {
|
||||||
|
switch (in) {
|
||||||
|
case base::PowerThermalObserver::DeviceThermalState::kUnknown:
|
||||||
|
return StringToV8(isolate, "unknown");
|
||||||
|
case base::PowerThermalObserver::DeviceThermalState::kNominal:
|
||||||
|
return StringToV8(isolate, "nominal");
|
||||||
|
case base::PowerThermalObserver::DeviceThermalState::kFair:
|
||||||
|
return StringToV8(isolate, "fair");
|
||||||
|
case base::PowerThermalObserver::DeviceThermalState::kSerious:
|
||||||
|
return StringToV8(isolate, "serious");
|
||||||
|
case base::PowerThermalObserver::DeviceThermalState::kCritical:
|
||||||
|
return StringToV8(isolate, "critical");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace gin
|
} // namespace gin
|
||||||
|
|
||||||
namespace electron::api {
|
namespace electron::api {
|
||||||
|
@ -47,6 +70,7 @@ PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
|
||||||
|
|
||||||
base::PowerMonitor::AddPowerStateObserver(this);
|
base::PowerMonitor::AddPowerStateObserver(this);
|
||||||
base::PowerMonitor::AddPowerSuspendObserver(this);
|
base::PowerMonitor::AddPowerSuspendObserver(this);
|
||||||
|
base::PowerMonitor::AddPowerThermalObserver(this);
|
||||||
|
|
||||||
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN)
|
||||||
InitPlatformSpecificMonitors();
|
InitPlatformSpecificMonitors();
|
||||||
|
@ -56,6 +80,7 @@ PowerMonitor::PowerMonitor(v8::Isolate* isolate) {
|
||||||
PowerMonitor::~PowerMonitor() {
|
PowerMonitor::~PowerMonitor() {
|
||||||
base::PowerMonitor::RemovePowerStateObserver(this);
|
base::PowerMonitor::RemovePowerStateObserver(this);
|
||||||
base::PowerMonitor::RemovePowerSuspendObserver(this);
|
base::PowerMonitor::RemovePowerSuspendObserver(this);
|
||||||
|
base::PowerMonitor::RemovePowerThermalObserver(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PowerMonitor::ShouldShutdown() {
|
bool PowerMonitor::ShouldShutdown() {
|
||||||
|
@ -77,6 +102,22 @@ void PowerMonitor::OnResume() {
|
||||||
Emit("resume");
|
Emit("resume");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PowerMonitor::OnThermalStateChange(DeviceThermalState new_state) {
|
||||||
|
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||||
|
v8::HandleScope scope(isolate);
|
||||||
|
EmitWithoutEvent(
|
||||||
|
"thermal-state-change",
|
||||||
|
gin::DataObjectBuilder(isolate).Set("state", new_state).Build());
|
||||||
|
}
|
||||||
|
|
||||||
|
void PowerMonitor::OnSpeedLimitChange(int speed_limit) {
|
||||||
|
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
||||||
|
v8::HandleScope scope(isolate);
|
||||||
|
EmitWithoutEvent(
|
||||||
|
"speed-limit-change",
|
||||||
|
gin::DataObjectBuilder(isolate).Set("limit", speed_limit).Build());
|
||||||
|
}
|
||||||
|
|
||||||
#if BUILDFLAG(IS_LINUX)
|
#if BUILDFLAG(IS_LINUX)
|
||||||
void PowerMonitor::SetListeningForShutdown(bool is_listening) {
|
void PowerMonitor::SetListeningForShutdown(bool is_listening) {
|
||||||
if (is_listening) {
|
if (is_listening) {
|
||||||
|
@ -137,6 +178,10 @@ bool IsOnBatteryPower() {
|
||||||
return base::PowerMonitor::IsOnBatteryPower();
|
return base::PowerMonitor::IsOnBatteryPower();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
base::PowerThermalObserver::DeviceThermalState GetCurrentThermalState() {
|
||||||
|
return base::PowerMonitor::GetCurrentThermalState();
|
||||||
|
}
|
||||||
|
|
||||||
void Initialize(v8::Local<v8::Object> exports,
|
void Initialize(v8::Local<v8::Object> exports,
|
||||||
v8::Local<v8::Value> unused,
|
v8::Local<v8::Value> unused,
|
||||||
v8::Local<v8::Context> context,
|
v8::Local<v8::Context> context,
|
||||||
|
@ -147,6 +192,8 @@ void Initialize(v8::Local<v8::Object> exports,
|
||||||
base::BindRepeating(&PowerMonitor::Create));
|
base::BindRepeating(&PowerMonitor::Create));
|
||||||
dict.SetMethod("getSystemIdleState",
|
dict.SetMethod("getSystemIdleState",
|
||||||
base::BindRepeating(&GetSystemIdleState));
|
base::BindRepeating(&GetSystemIdleState));
|
||||||
|
dict.SetMethod("getCurrentThermalState",
|
||||||
|
base::BindRepeating(&GetCurrentThermalState));
|
||||||
dict.SetMethod("getSystemIdleTime", base::BindRepeating(&GetSystemIdleTime));
|
dict.SetMethod("getSystemIdleTime", base::BindRepeating(&GetSystemIdleTime));
|
||||||
dict.SetMethod("isOnBatteryPower", base::BindRepeating(&IsOnBatteryPower));
|
dict.SetMethod("isOnBatteryPower", base::BindRepeating(&IsOnBatteryPower));
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@ class PowerMonitor : public gin::Wrappable<PowerMonitor>,
|
||||||
public gin_helper::EventEmitterMixin<PowerMonitor>,
|
public gin_helper::EventEmitterMixin<PowerMonitor>,
|
||||||
public gin_helper::Pinnable<PowerMonitor>,
|
public gin_helper::Pinnable<PowerMonitor>,
|
||||||
public base::PowerStateObserver,
|
public base::PowerStateObserver,
|
||||||
public base::PowerSuspendObserver {
|
public base::PowerSuspendObserver,
|
||||||
|
public base::PowerThermalObserver {
|
||||||
public:
|
public:
|
||||||
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
static v8::Local<v8::Value> Create(v8::Isolate* isolate);
|
||||||
|
|
||||||
|
@ -57,6 +58,10 @@ class PowerMonitor : public gin::Wrappable<PowerMonitor>,
|
||||||
void OnSuspend() override;
|
void OnSuspend() override;
|
||||||
void OnResume() override;
|
void OnResume() override;
|
||||||
|
|
||||||
|
// base::PowerThermalObserver
|
||||||
|
void OnThermalStateChange(DeviceThermalState new_state) override;
|
||||||
|
void OnSpeedLimitChange(int speed_limit) override;
|
||||||
|
|
||||||
#if BUILDFLAG(IS_WIN)
|
#if BUILDFLAG(IS_WIN)
|
||||||
// Static callback invoked when a message comes in to our messaging window.
|
// Static callback invoked when a message comes in to our messaging window.
|
||||||
static LRESULT CALLBACK WndProcStatic(HWND hwnd,
|
static LRESULT CALLBACK WndProcStatic(HWND hwnd,
|
||||||
|
|
|
@ -178,6 +178,12 @@ describe('powerMonitor', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('powerMonitor.getCurrentThermalState', () => {
|
||||||
|
it('returns a valid state', () => {
|
||||||
|
expect(powerMonitor.getCurrentThermalState()).to.be.oneOf(['unknown', 'nominal', 'fair', 'serious', 'critical']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('powerMonitor.onBatteryPower', () => {
|
describe('powerMonitor.onBatteryPower', () => {
|
||||||
it('returns a boolean', () => {
|
it('returns a boolean', () => {
|
||||||
expect(powerMonitor.onBatteryPower).to.be.a('boolean');
|
expect(powerMonitor.onBatteryPower).to.be.a('boolean');
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue