Commit 5f4d6dad authored by Puthikorn Voravootivat's avatar Puthikorn Voravootivat Committed by Commit Bot

chromeos/dbus: base/power_monitor: Add thermal hinting api

Add proto for power manager to provide thermal
hinting to Chrome.

Bug: 1081959
Test: See ThermalEvent in chrome://device-log
chromeos_unittest --gtest_filter=PowerManagerClientTest.ChangeThermalState

Change-Id: Ie7435852da01a5acf3580b5bb569ba117113f658
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2300983
Commit-Queue: Puthikorn Voravootivat <puthik@chromium.org>
Auto-Submit: Puthikorn Voravootivat <puthik@chromium.org>
Reviewed-by: default avatarSteven Bennetts <stevenjb@chromium.org>
Reviewed-by: default avatarFrançois Doray <fdoray@chromium.org>
Cr-Commit-Position: refs/heads/master@{#802880}
parent 43da5d9c
...@@ -5,6 +5,9 @@ ...@@ -5,6 +5,9 @@
#ifndef BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_ #ifndef BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_
#define BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_ #define BASE_POWER_MONITOR_POWER_MONITOR_DEVICE_SOURCE_H_
#include <memory>
#include <vector>
#include "base/base_export.h" #include "base/base_export.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/power_monitor/power_monitor_source.h" #include "base/power_monitor/power_monitor_source.h"
...@@ -44,6 +47,7 @@ class BASE_EXPORT PowerMonitorDeviceSource : public PowerMonitorSource { ...@@ -44,6 +47,7 @@ class BASE_EXPORT PowerMonitorDeviceSource : public PowerMonitorSource {
static void SetPowerSource(bool on_battery); static void SetPowerSource(bool on_battery);
static void HandleSystemSuspending(); static void HandleSystemSuspending();
static void HandleSystemResumed(); static void HandleSystemResumed();
static void ThermalEventReceived(PowerObserver::DeviceThermalState state);
#endif #endif
private: private:
......
...@@ -37,4 +37,10 @@ bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() { ...@@ -37,4 +37,10 @@ bool PowerMonitorDeviceSource::IsOnBatteryPowerImpl() {
return g_on_battery; return g_on_battery;
} }
// static
void PowerMonitorDeviceSource::ThermalEventReceived(
PowerObserver::DeviceThermalState state) {
ProcessThermalEvent(state);
}
} // namespace base } // namespace base
...@@ -58,6 +58,7 @@ proto_library("power_manager_proto") { ...@@ -58,6 +58,7 @@ proto_library("power_manager_proto") {
"//third_party/cros_system_api/dbus/power_manager/power_supply_properties.proto", "//third_party/cros_system_api/dbus/power_manager/power_supply_properties.proto",
"//third_party/cros_system_api/dbus/power_manager/suspend.proto", "//third_party/cros_system_api/dbus/power_manager/suspend.proto",
"//third_party/cros_system_api/dbus/power_manager/switch_states.proto", "//third_party/cros_system_api/dbus/power_manager/switch_states.proto",
"//third_party/cros_system_api/dbus/power_manager/thermal.proto",
] ]
proto_out_dir = "chromeos/dbus/power_manager" proto_out_dir = "chromeos/dbus/power_manager"
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/observer_list.h" #include "base/observer_list.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 "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h" #include "base/strings/string_split.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
...@@ -34,6 +35,7 @@ ...@@ -34,6 +35,7 @@
#include "chromeos/dbus/power_manager/input_event.pb.h" #include "chromeos/dbus/power_manager/input_event.pb.h"
#include "chromeos/dbus/power_manager/peripheral_battery_status.pb.h" #include "chromeos/dbus/power_manager/peripheral_battery_status.pb.h"
#include "chromeos/dbus/power_manager/switch_states.pb.h" #include "chromeos/dbus/power_manager/switch_states.pb.h"
#include "chromeos/dbus/power_manager/thermal.pb.h"
#include "components/device_event_log/device_event_log.h" #include "components/device_event_log/device_event_log.h"
#include "dbus/bus.h" #include "dbus/bus.h"
#include "dbus/message.h" #include "dbus/message.h"
...@@ -107,6 +109,26 @@ PowerManagerClient::TabletMode GetTabletModeFromProtoEnum( ...@@ -107,6 +109,26 @@ PowerManagerClient::TabletMode GetTabletModeFromProtoEnum(
return PowerManagerClient::TabletMode::UNSUPPORTED; return PowerManagerClient::TabletMode::UNSUPPORTED;
} }
// Converts a ThermalState value from a power_manager::ThermalEvent proto to the
// corresponding base::PowerObserver::DeviceThermalState value.
base::PowerObserver::DeviceThermalState GetThermalStateFromProtoEnum(
power_manager::ThermalEvent::ThermalState state) {
switch (state) {
case power_manager::ThermalEvent_ThermalState_UNKNOWN:
return base::PowerObserver::DeviceThermalState::kUnknown;
case power_manager::ThermalEvent_ThermalState_NOMINAL:
return base::PowerObserver::DeviceThermalState::kNominal;
case power_manager::ThermalEvent_ThermalState_FAIR:
return base::PowerObserver::DeviceThermalState::kFair;
case power_manager::ThermalEvent_ThermalState_SERIOUS:
return base::PowerObserver::DeviceThermalState::kSerious;
case power_manager::ThermalEvent_ThermalState_CRITICAL:
return base::PowerObserver::DeviceThermalState::kCritical;
}
NOTREACHED() << "Unhandled thermal state " << state;
return base::PowerObserver::DeviceThermalState::kUnknown;
}
// Callback for D-Bus call made in |CreateArcTimers|. // Callback for D-Bus call made in |CreateArcTimers|.
void OnCreateArcTimersDBusMethod( void OnCreateArcTimersDBusMethod(
DBusMethodCallback<std::vector<PowerManagerClient::TimerId>> callback, DBusMethodCallback<std::vector<PowerManagerClient::TimerId>> callback,
...@@ -175,7 +197,7 @@ class PowerManagerClientImpl : public PowerManagerClient { ...@@ -175,7 +197,7 @@ class PowerManagerClientImpl : public PowerManagerClient {
// Listen to D-Bus signals emitted by powerd. // Listen to D-Bus signals emitted by powerd.
typedef void (PowerManagerClientImpl::*SignalMethod)(dbus::Signal*); typedef void (PowerManagerClientImpl::*SignalMethod)(dbus::Signal*);
const std::map<const char*, SignalMethod> kSignalMethods = { const std::pair<const char*, SignalMethod> kSignalMethods[] = {
{power_manager::kScreenBrightnessChangedSignal, {power_manager::kScreenBrightnessChangedSignal,
&PowerManagerClientImpl::ScreenBrightnessChangedReceived}, &PowerManagerClientImpl::ScreenBrightnessChangedReceived},
{power_manager::kAmbientColorTemperatureChangedSignal, {power_manager::kAmbientColorTemperatureChangedSignal,
...@@ -202,13 +224,17 @@ class PowerManagerClientImpl : public PowerManagerClient { ...@@ -202,13 +224,17 @@ class PowerManagerClientImpl : public PowerManagerClient {
&PowerManagerClientImpl::IdleActionImminentReceived}, &PowerManagerClientImpl::IdleActionImminentReceived},
{power_manager::kIdleActionDeferredSignal, {power_manager::kIdleActionDeferredSignal,
&PowerManagerClientImpl::IdleActionDeferredReceived}, &PowerManagerClientImpl::IdleActionDeferredReceived},
{power_manager::kThermalEventSignal,
&PowerManagerClientImpl::ThermalEventReceived},
}; };
for (const auto& it : kSignalMethods) { auto on_connected_callback =
base::BindRepeating(&PowerManagerClientImpl::SignalConnected,
weak_ptr_factory_.GetWeakPtr());
for (const auto& p : kSignalMethods) {
power_manager_proxy_->ConnectToSignal( power_manager_proxy_->ConnectToSignal(
power_manager::kPowerManagerInterface, it.first, power_manager::kPowerManagerInterface, p.first,
base::BindRepeating(it.second, weak_ptr_factory_.GetWeakPtr()), base::BindRepeating(p.second, weak_ptr_factory_.GetWeakPtr()),
base::BindOnce(&PowerManagerClientImpl::SignalConnected, on_connected_callback);
weak_ptr_factory_.GetWeakPtr()));
} }
RegisterSuspendDelays(); RegisterSuspendDelays();
...@@ -1064,6 +1090,24 @@ class PowerManagerClientImpl : public PowerManagerClient { ...@@ -1064,6 +1090,24 @@ class PowerManagerClientImpl : public PowerManagerClient {
} }
} }
void ThermalEventReceived(dbus::Signal* signal) {
dbus::MessageReader reader(signal);
power_manager::ThermalEvent proto;
if (!reader.PopArrayOfBytesAsProto(&proto)) {
POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
<< power_manager::kThermalEventSignal << " signal";
return;
}
POWER_LOG(USER) << "Got " << power_manager::kThermalEventSignal
<< " signal:"
<< " thermal_state=" << proto.thermal_state()
<< " timestamp=" << proto.timestamp();
base::PowerMonitorDeviceSource::ThermalEventReceived(
GetThermalStateFromProtoEnum(proto.thermal_state()));
}
void RegisterSuspendDelayImpl( void RegisterSuspendDelayImpl(
const std::string& method_name, const std::string& method_name,
const power_manager::RegisterSuspendDelayRequest& protobuf_request, const power_manager::RegisterSuspendDelayRequest& protobuf_request,
......
...@@ -15,9 +15,12 @@ ...@@ -15,9 +15,12 @@
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/power_monitor_test_base.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "base/unguessable_token.h" #include "base/unguessable_token.h"
#include "chromeos/dbus/power_manager/suspend.pb.h" #include "chromeos/dbus/power_manager/suspend.pb.h"
#include "chromeos/dbus/power_manager/thermal.pb.h"
#include "dbus/mock_bus.h" #include "dbus/mock_bus.h"
#include "dbus/mock_object_proxy.h" #include "dbus/mock_object_proxy.h"
#include "dbus/object_path.h" #include "dbus/object_path.h"
...@@ -193,6 +196,29 @@ class TestDelegate : public PowerManagerClient::RenderProcessManagerDelegate { ...@@ -193,6 +196,29 @@ class TestDelegate : public PowerManagerClient::RenderProcessManagerDelegate {
DISALLOW_COPY_AND_ASSIGN(TestDelegate); DISALLOW_COPY_AND_ASSIGN(TestDelegate);
}; };
// Local implementation of base::PowerMonitorTestObserver to add callback to
// OnThermalStateChange.
class PowerMonitorTestObserverLocal : public base::PowerMonitorTestObserver {
public:
using base::PowerMonitorTestObserver::PowerMonitorTestObserver;
void OnThermalStateChange(
PowerObserver::DeviceThermalState new_state) override {
ASSERT_TRUE(cb);
base::PowerMonitorTestObserver::OnThermalStateChange(new_state);
std::move(cb).Run();
}
void set_cb_for_testing(base::OnceCallback<void()> cb) {
this->cb = std::move(cb);
}
private:
base::OnceCallback<void()> cb;
DISALLOW_COPY_AND_ASSIGN(PowerMonitorTestObserverLocal);
};
} // namespace } // namespace
class PowerManagerClientTest : public testing::Test { class PowerManagerClientTest : public testing::Test {
...@@ -613,4 +639,50 @@ TEST_F(PowerManagerClientTest, ChangeAmbientColorTemperature) { ...@@ -613,4 +639,50 @@ TEST_F(PowerManagerClientTest, ChangeAmbientColorTemperature) {
EXPECT_EQ(kTemperature, observer.ambient_color_temperature()); EXPECT_EQ(kTemperature, observer.ambient_color_temperature());
} }
// Tests that base::PowerMonitor observers are notified about thermal event.
TEST_F(PowerManagerClientTest, ChangeThermalState) {
PowerMonitorTestObserverLocal observer;
base::PowerMonitor::AddObserver(&observer);
base::PowerMonitor::Initialize(
std::make_unique<base::PowerMonitorTestSource>());
typedef struct {
power_manager::ThermalEvent::ThermalState dbus_state;
base::PowerObserver::DeviceThermalState expected_state;
} ThermalDBusTestType;
ThermalDBusTestType thermal_states[] = {
{.dbus_state = power_manager::ThermalEvent_ThermalState_UNKNOWN,
.expected_state = base::PowerObserver::DeviceThermalState::kUnknown},
{.dbus_state = power_manager::ThermalEvent_ThermalState_NOMINAL,
.expected_state = base::PowerObserver::DeviceThermalState::kNominal},
{.dbus_state = power_manager::ThermalEvent_ThermalState_FAIR,
.expected_state = base::PowerObserver::DeviceThermalState::kFair},
{.dbus_state = power_manager::ThermalEvent_ThermalState_SERIOUS,
.expected_state = base::PowerObserver::DeviceThermalState::kSerious},
{.dbus_state = power_manager::ThermalEvent_ThermalState_CRITICAL,
.expected_state = base::PowerObserver::DeviceThermalState::kCritical},
};
for (const auto& p : thermal_states) {
power_manager::ThermalEvent proto;
proto.set_thermal_state(p.dbus_state);
proto.set_timestamp(0);
dbus::Signal signal(kInterface, power_manager::kThermalEventSignal);
dbus::MessageWriter(&signal).AppendProtoAsArrayOfBytes(proto);
EmitSignal(&signal);
base::RunLoop run_loop;
observer.set_cb_for_testing(base::BindLambdaForTesting([&] {
run_loop.Quit();
EXPECT_EQ(observer.last_thermal_state(), p.expected_state);
}));
run_loop.Run();
}
base::PowerMonitor::RemoveObserver(&observer);
}
} // namespace chromeos } // namespace chromeos
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