Commit c426987d authored by Miguel Casas-Sanchez's avatar Miguel Casas-Sanchez Committed by Commit Bot

RELAND: base/power_monitor: Add method to query thermal state

This CL relands crrev.com/c/2248729 that got reverted due to breaking
Mac Builder (dbg) and others (power_monitor_device_source_unittest.cc
did not include logging.h and it couldn't find 'DVLOG'). The original
CL description only said "wip wip" o_O, which is sad.

Essentially this CL adds a GetCurrentThermalState() to PowerMonitor to
actively retrieve the current ThermalState. The ThermalState is sent to
PowerObservers, but newly created clients still need to query it at
least one time.

TBR=fdoray@chromium.org since the diff is just an include file.


Bug: 1071431
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2248729Reviewed-by: default avatarHenrik Boström <hbos@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Commit-Queue: Miguel Casas <mcasas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781322}

Change-Id: Ia62ddfd8afc167473f3456e4982f51eaa52a833f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2261363Reviewed-by: default avatarMiguel Casas <mcasas@chromium.org>
Commit-Queue: Miguel Casas <mcasas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781678}
parent 346f9e4f
......@@ -2744,6 +2744,7 @@ test("base_unittests") {
"parameter_pack_unittest.cc",
"path_service_unittest.cc",
"pickle_unittest.cc",
"power_monitor/power_monitor_device_source_unittest.cc",
"power_monitor/power_monitor_unittest.cc",
"process/environment_internal_unittest.cc",
"process/memory_unittest.cc",
......
......@@ -52,6 +52,11 @@ bool PowerMonitor::IsProcessSuspended() {
return g_is_process_suspended.load(std::memory_order_relaxed);
}
PowerObserver::DeviceThermalState PowerMonitor::GetCurrentThermalState() {
DCHECK(IsInitialized());
return GetInstance()->source_->GetCurrentThermalState();
}
void PowerMonitor::NotifyPowerStateChange(bool battery_in_use) {
DCHECK(IsInitialized());
DVLOG(1) << "PowerStateChange: " << (battery_in_use ? "On" : "Off")
......
......@@ -56,6 +56,10 @@ class BASE_EXPORT PowerMonitor {
// what is the real power state.
static bool IsProcessSuspended();
// Read the current DeviceThermalState if known. Can be called on any thread.
// May only be called if the PowerMonitor has been initialized.
static PowerObserver::DeviceThermalState GetCurrentThermalState();
// Uninitializes the PowerMonitor. Should be called at the end of any unit
// test that mocks out the PowerMonitor, to avoid affecting subsequent tests.
// There must be no live PowerObservers when invoked. Safe to call even if the
......
......@@ -47,6 +47,8 @@ class BASE_EXPORT PowerMonitorDeviceSource : public PowerMonitorSource {
#endif
private:
friend class PowerMonitorDeviceSourceTest;
#if defined(OS_WIN)
// Represents a message-only window for power message handling on Windows.
// Only allow PowerMonitor to create it.
......@@ -86,6 +88,9 @@ class BASE_EXPORT PowerMonitorDeviceSource : public PowerMonitorSource {
bool IsOnBatteryPowerImpl() override;
#if defined(OS_MACOSX) && !defined(OS_IOS)
// PowerMonitorSource:
PowerObserver::DeviceThermalState GetCurrentThermalState() override;
// Reference to the system IOPMrootDomain port.
io_connect_t power_manager_port_ = IO_OBJECT_NULL;
......
......@@ -51,6 +51,14 @@ bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
return true;
}
PowerObserver::DeviceThermalState
PowerMonitorDeviceSource::GetCurrentThermalState() {
if (@available(macOS 10.10.3, *)) {
return thermal_state_observer_->GetCurrentThermalState();
};
return PowerObserver::DeviceThermalState::kUnknown;
}
namespace {
void BatteryEventCallback(void*) {
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/power_monitor/power_monitor_device_source.h"
#include "base/logging.h"
#include "base/power_monitor/power_monitor.h"
#include "base/power_monitor/power_monitor_source.h"
#include "build/build_config.h"
#include "testing/gtest/include/gtest/gtest.h"
using DeviceThermalState = base::PowerObserver::DeviceThermalState;
namespace base {
class PowerMonitorDeviceSourceTest : public testing::Test {
public:
PowerMonitorDeviceSourceTest() = default;
~PowerMonitorDeviceSourceTest() override = default;
DeviceThermalState GetCurrentThermalState() {
return power_monitor_device_source_.GetCurrentThermalState();
}
PowerMonitorDeviceSource power_monitor_device_source_;
};
TEST_F(PowerMonitorDeviceSourceTest, GetCurrentThermalState) {
const DeviceThermalState current_state = GetCurrentThermalState();
#if defined(OS_MACOSX) && !defined(OS_IOS)
// We cannot make assumptions on |current_state|. Print it out to use the var.
DVLOG(1) << PowerMonitorSource::DeviceThermalStateToString(current_state);
#else
EXPECT_EQ(current_state, DeviceThermalState::kUnknown);
#endif
}
} // namespace base
......@@ -17,6 +17,10 @@ bool PowerMonitorSource::IsOnBatteryPower() {
return on_battery_power_;
}
PowerObserver::DeviceThermalState PowerMonitorSource::GetCurrentThermalState() {
return PowerObserver::DeviceThermalState::kUnknown;
}
// static
void PowerMonitorSource::ProcessPowerEvent(PowerEvent event_id) {
if (!PowerMonitor::IsInitialized())
......
......@@ -31,6 +31,10 @@ class BASE_EXPORT PowerMonitorSource {
// Is the computer currently on battery power. Can be called on any thread.
bool IsOnBatteryPower();
// Reads the current DeviceThermalState, if available on the platform.
// Otherwise, returns kUnknown.
virtual PowerObserver::DeviceThermalState GetCurrentThermalState();
static const char* DeviceThermalStateToString(
PowerObserver::DeviceThermalState state);
......
......@@ -102,6 +102,7 @@ TEST_F(PowerMonitorTest, ThermalThrottling) {
for (const auto state : kThermalStates) {
source()->GenerateThermalThrottlingEvent(state);
EXPECT_EQ(state, source()->GetCurrentThermalState());
EXPECT_EQ(observer.last_thermal_state(), state);
}
......
......@@ -14,9 +14,9 @@
namespace base {
// This class is used to listen for the thermal state change notification from
// NSProcessInfoThermalStateDidChangeNotification via a fully owned
// ThermalStateObserverDelegate, routing the notification to PowerMonitorSource.
// This class is used to listen for the thermal state change notification
// NSProcessInfoThermalStateDidChangeNotification, routing it to
// PowerMonitorSource.
class BASE_EXPORT ThermalStateObserverMac {
public:
using StateUpdateCallback =
......@@ -25,6 +25,8 @@ class BASE_EXPORT ThermalStateObserverMac {
explicit ThermalStateObserverMac(StateUpdateCallback state_update_callback);
~ThermalStateObserverMac();
PowerObserver::DeviceThermalState GetCurrentThermalState();
private:
FRIEND_TEST_ALL_PREFIXES(ThermalStateObserverMacTest, StateChange);
PowerObserver::DeviceThermalState state_for_testing_ =
......
......@@ -63,4 +63,13 @@ ThermalStateObserverMac::~ThermalStateObserverMac() {
[[NSNotificationCenter defaultCenter]
removeObserver:thermal_state_update_observer_];
}
PowerObserver::DeviceThermalState
ThermalStateObserverMac::GetCurrentThermalState() NS_AVAILABLE_MAC(10_10_3) {
if (state_for_testing_ != PowerObserver::DeviceThermalState::kUnknown)
return state_for_testing_;
NSProcessInfoThermalState nsinfo_state =
[[NSProcessInfo processInfo] thermalState];
return NSProcessInfoThermalStateToDeviceThermalState(nsinfo_state);
}
}
......@@ -11,14 +11,18 @@
namespace base {
PowerMonitorTestSource::PowerMonitorTestSource()
: test_on_battery_power_(false) {
PowerMonitorTestSource::PowerMonitorTestSource() {
DCHECK(MessageLoopCurrent::Get())
<< "PowerMonitorTestSource requires a MessageLoop.";
}
PowerMonitorTestSource::~PowerMonitorTestSource() = default;
PowerObserver::DeviceThermalState
PowerMonitorTestSource::GetCurrentThermalState() {
return current_thermal_state_;
}
void PowerMonitorTestSource::GeneratePowerStateEvent(bool on_battery_power) {
test_on_battery_power_ = on_battery_power;
ProcessPowerEvent(POWER_STATE_EVENT);
......@@ -42,6 +46,7 @@ bool PowerMonitorTestSource::IsOnBatteryPowerImpl() {
void PowerMonitorTestSource::GenerateThermalThrottlingEvent(
PowerObserver::DeviceThermalState new_thermal_state) {
ProcessThermalEvent(new_thermal_state);
current_thermal_state_ = new_thermal_state;
RunLoop().RunUntilIdle();
}
......
......@@ -14,6 +14,7 @@ class PowerMonitorTestSource : public PowerMonitorSource {
public:
PowerMonitorTestSource();
~PowerMonitorTestSource() override;
PowerObserver::DeviceThermalState GetCurrentThermalState() override;
void GeneratePowerStateEvent(bool on_battery_power);
void GenerateSuspendEvent();
......@@ -24,7 +25,9 @@ class PowerMonitorTestSource : public PowerMonitorSource {
protected:
bool IsOnBatteryPowerImpl() override;
bool test_on_battery_power_;
bool test_on_battery_power_ = false;
PowerObserver::DeviceThermalState current_thermal_state_ =
PowerObserver::DeviceThermalState::kUnknown;
};
class PowerMonitorTestObserver : public PowerObserver {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment