power_manager_client.cc 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "chromeos/dbus/power/power_manager_client.h"
  5. #include <stdint.h>
  6. #include <algorithm>
  7. #include <memory>
  8. #include <unordered_map>
  9. #include <utility>
  10. #include "base/bind.h"
  11. #include "base/callback_helpers.h"
  12. #include "base/command_line.h"
  13. #include "base/format_macros.h"
  14. #include "base/logging.h"
  15. #include "base/observer_list.h"
  16. #include "base/power_monitor/power_monitor.h"
  17. #include "base/power_monitor/power_monitor_device_source.h"
  18. #include "base/strings/string_number_conversions.h"
  19. #include "base/strings/string_split.h"
  20. #include "base/threading/platform_thread.h"
  21. #include "base/time/time.h"
  22. #include "base/timer/timer.h"
  23. #include "base/unguessable_token.h"
  24. #include "chromeos/dbus/constants/dbus_switches.h"
  25. #include "chromeos/dbus/power/fake_power_manager_client.h"
  26. #include "chromeos/dbus/power_manager/backlight.pb.h"
  27. #include "chromeos/dbus/power_manager/idle.pb.h"
  28. #include "chromeos/dbus/power_manager/input_event.pb.h"
  29. #include "chromeos/dbus/power_manager/peripheral_battery_status.pb.h"
  30. #include "chromeos/dbus/power_manager/switch_states.pb.h"
  31. #include "chromeos/dbus/power_manager/thermal.pb.h"
  32. #include "components/device_event_log/device_event_log.h"
  33. #include "dbus/bus.h"
  34. #include "dbus/message.h"
  35. #include "dbus/object_path.h"
  36. #include "dbus/object_proxy.h"
  37. namespace chromeos {
  38. namespace {
  39. PowerManagerClient* g_instance = nullptr;
  40. // Maximum amount of time that the power manager will wait for Chrome to
  41. // say that it's ready for the system to be suspended, in milliseconds.
  42. const int kSuspendDelayTimeoutMs = 5000;
  43. // Human-readable description of Chrome's suspend delay.
  44. const char kSuspendDelayDescription[] = "chrome";
  45. // Returns a modified version of |proto| where fields are consistent.
  46. power_manager::PowerSupplyProperties SanitizePowerSupplyProperties(
  47. const power_manager::PowerSupplyProperties& proto) {
  48. power_manager::PowerSupplyProperties sanitized = proto;
  49. if (sanitized.battery_state() ==
  50. power_manager::PowerSupplyProperties_BatteryState_FULL) {
  51. sanitized.set_battery_percent(100.0);
  52. }
  53. if (!sanitized.is_calculating_battery_time()) {
  54. const bool on_line_power =
  55. sanitized.external_power() !=
  56. power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED;
  57. if ((on_line_power && sanitized.battery_time_to_full_sec() < 0) ||
  58. (!on_line_power && sanitized.battery_time_to_empty_sec() < 0)) {
  59. sanitized.set_is_calculating_battery_time(true);
  60. }
  61. }
  62. return sanitized;
  63. }
  64. // Converts a LidState value from a power_manager::SwitchStates proto to the
  65. // corresponding PowerManagerClient::LidState value.
  66. PowerManagerClient::LidState GetLidStateFromProtoEnum(
  67. power_manager::SwitchStates::LidState state) {
  68. switch (state) {
  69. case power_manager::SwitchStates_LidState_OPEN:
  70. return PowerManagerClient::LidState::OPEN;
  71. case power_manager::SwitchStates_LidState_CLOSED:
  72. return PowerManagerClient::LidState::CLOSED;
  73. case power_manager::SwitchStates_LidState_NOT_PRESENT:
  74. return PowerManagerClient::LidState::NOT_PRESENT;
  75. }
  76. NOTREACHED() << "Unhandled lid state " << state;
  77. return PowerManagerClient::LidState::NOT_PRESENT;
  78. }
  79. // Converts a TabletMode value from a power_manager::SwitchStates proto to the
  80. // corresponding PowerManagerClient::TabletMode value.
  81. PowerManagerClient::TabletMode GetTabletModeFromProtoEnum(
  82. power_manager::SwitchStates::TabletMode mode) {
  83. switch (mode) {
  84. case power_manager::SwitchStates_TabletMode_ON:
  85. return PowerManagerClient::TabletMode::ON;
  86. case power_manager::SwitchStates_TabletMode_OFF:
  87. return PowerManagerClient::TabletMode::OFF;
  88. case power_manager::SwitchStates_TabletMode_UNSUPPORTED:
  89. return PowerManagerClient::TabletMode::UNSUPPORTED;
  90. }
  91. NOTREACHED() << "Unhandled tablet mode " << mode;
  92. return PowerManagerClient::TabletMode::UNSUPPORTED;
  93. }
  94. // Converts a ThermalState value from a power_manager::ThermalEvent proto to the
  95. // corresponding base::PowerThermalObserver::DeviceThermalState value.
  96. base::PowerThermalObserver::DeviceThermalState GetThermalStateFromProtoEnum(
  97. power_manager::ThermalEvent::ThermalState state) {
  98. switch (state) {
  99. case power_manager::ThermalEvent_ThermalState_UNKNOWN:
  100. return base::PowerThermalObserver::DeviceThermalState::kUnknown;
  101. case power_manager::ThermalEvent_ThermalState_NOMINAL:
  102. return base::PowerThermalObserver::DeviceThermalState::kNominal;
  103. case power_manager::ThermalEvent_ThermalState_FAIR:
  104. return base::PowerThermalObserver::DeviceThermalState::kFair;
  105. case power_manager::ThermalEvent_ThermalState_SERIOUS:
  106. return base::PowerThermalObserver::DeviceThermalState::kSerious;
  107. case power_manager::ThermalEvent_ThermalState_CRITICAL:
  108. return base::PowerThermalObserver::DeviceThermalState::kCritical;
  109. }
  110. NOTREACHED() << "Unhandled thermal state " << state;
  111. return base::PowerThermalObserver::DeviceThermalState::kUnknown;
  112. }
  113. // Callback for D-Bus call made in |CreateArcTimers|.
  114. void OnCreateArcTimersDBusMethod(
  115. DBusMethodCallback<std::vector<PowerManagerClient::TimerId>> callback,
  116. dbus::Response* response) {
  117. if (response == nullptr) {
  118. std::move(callback).Run(absl::nullopt);
  119. return;
  120. }
  121. dbus::MessageReader reader(response);
  122. dbus::MessageReader array_reader(nullptr);
  123. if (!reader.PopArray(&array_reader)) {
  124. POWER_LOG(ERROR) << "No timer ids returned";
  125. std::move(callback).Run(absl::nullopt);
  126. return;
  127. }
  128. std::vector<PowerManagerClient::TimerId> timer_ids;
  129. while (array_reader.HasMoreData()) {
  130. int32_t timer_id;
  131. if (!array_reader.PopInt32(&timer_id)) {
  132. POWER_LOG(ERROR) << "Failed to pop timer id";
  133. std::move(callback).Run(absl::nullopt);
  134. return;
  135. }
  136. timer_ids.push_back(timer_id);
  137. }
  138. std::move(callback).Run(std::move(timer_ids));
  139. }
  140. // Callback for D-Bus call made in |StartArcTimer| and |DeleteArcTimers|.
  141. void OnVoidDBusMethod(VoidDBusMethodCallback callback,
  142. dbus::Response* response) {
  143. std::move(callback).Run(response != nullptr);
  144. }
  145. } // namespace
  146. // The PowerManagerClient implementation used in production.
  147. class PowerManagerClientImpl : public PowerManagerClient {
  148. public:
  149. PowerManagerClientImpl()
  150. : origin_thread_id_(base::PlatformThread::CurrentId()) {}
  151. PowerManagerClientImpl(const PowerManagerClientImpl&) = delete;
  152. PowerManagerClientImpl& operator=(const PowerManagerClientImpl&) = delete;
  153. ~PowerManagerClientImpl() override {
  154. // Here we should unregister suspend notifications from powerd,
  155. // however:
  156. // - The lifetime of the PowerManagerClientImpl can extend past that of
  157. // the objectproxy,
  158. // - power_manager can already detect that the client is gone and
  159. // unregister our suspend delay.
  160. }
  161. void Init(dbus::Bus* bus) {
  162. power_manager_proxy_ = bus->GetObjectProxy(
  163. power_manager::kPowerManagerServiceName,
  164. dbus::ObjectPath(power_manager::kPowerManagerServicePath));
  165. power_manager_proxy_->SetNameOwnerChangedCallback(
  166. base::BindRepeating(&PowerManagerClientImpl::NameOwnerChangedReceived,
  167. weak_ptr_factory_.GetWeakPtr()));
  168. power_manager_proxy_->WaitForServiceToBeAvailable(
  169. base::BindOnce(&PowerManagerClientImpl::NotifyServiceBecameAvailable,
  170. weak_ptr_factory_.GetWeakPtr()));
  171. // Listen to D-Bus signals emitted by powerd.
  172. typedef void (PowerManagerClientImpl::*SignalMethod)(dbus::Signal*);
  173. const std::pair<const char*, SignalMethod> kSignalMethods[] = {
  174. {power_manager::kScreenBrightnessChangedSignal,
  175. &PowerManagerClientImpl::ScreenBrightnessChangedReceived},
  176. {power_manager::kAmbientColorTemperatureChangedSignal,
  177. &PowerManagerClientImpl::AmbientColorTemperatureChangedReceived},
  178. {power_manager::kKeyboardBrightnessChangedSignal,
  179. &PowerManagerClientImpl::KeyboardBrightnessChangedReceived},
  180. {power_manager::kScreenIdleStateChangedSignal,
  181. &PowerManagerClientImpl::ScreenIdleStateChangedReceived},
  182. {power_manager::kInactivityDelaysChangedSignal,
  183. &PowerManagerClientImpl::InactivityDelaysChangedReceived},
  184. {power_manager::kPeripheralBatteryStatusSignal,
  185. &PowerManagerClientImpl::PeripheralBatteryStatusReceived},
  186. {power_manager::kPowerSupplyPollSignal,
  187. &PowerManagerClientImpl::PowerSupplyPollReceived},
  188. {power_manager::kInputEventSignal,
  189. &PowerManagerClientImpl::InputEventReceived},
  190. {power_manager::kSuspendImminentSignal,
  191. &PowerManagerClientImpl::SuspendImminentReceived},
  192. {power_manager::kSuspendDoneSignal,
  193. &PowerManagerClientImpl::SuspendDoneReceived},
  194. {power_manager::kDarkSuspendImminentSignal,
  195. &PowerManagerClientImpl::DarkSuspendImminentReceived},
  196. {power_manager::kIdleActionImminentSignal,
  197. &PowerManagerClientImpl::IdleActionImminentReceived},
  198. {power_manager::kIdleActionDeferredSignal,
  199. &PowerManagerClientImpl::IdleActionDeferredReceived},
  200. {power_manager::kThermalEventSignal,
  201. &PowerManagerClientImpl::ThermalEventReceived},
  202. };
  203. auto on_connected_callback =
  204. base::BindRepeating(&PowerManagerClientImpl::SignalConnected,
  205. weak_ptr_factory_.GetWeakPtr());
  206. for (const auto& p : kSignalMethods) {
  207. power_manager_proxy_->ConnectToSignal(
  208. power_manager::kPowerManagerInterface, p.first,
  209. base::BindRepeating(p.second, weak_ptr_factory_.GetWeakPtr()),
  210. on_connected_callback);
  211. }
  212. RegisterSuspendDelays();
  213. RequestStatusUpdate();
  214. RequestThermalState();
  215. CheckAmbientColorSupport();
  216. }
  217. // PowerManagerClient overrides:
  218. void AddObserver(Observer* observer) override {
  219. DCHECK(observer); // http://crbug.com/119976
  220. observers_.AddObserver(observer);
  221. if (service_available_)
  222. observer->PowerManagerBecameAvailable(*service_available_);
  223. }
  224. void RemoveObserver(Observer* observer) override {
  225. observers_.RemoveObserver(observer);
  226. }
  227. bool HasObserver(const Observer* observer) const override {
  228. return observers_.HasObserver(observer);
  229. }
  230. void SetRenderProcessManagerDelegate(
  231. base::WeakPtr<RenderProcessManagerDelegate> delegate) override {
  232. DCHECK(!render_process_manager_delegate_)
  233. << "There can be only one! ...RenderProcessManagerDelegate";
  234. render_process_manager_delegate_ = delegate;
  235. }
  236. void DecreaseScreenBrightness(bool allow_off) override {
  237. dbus::MethodCall method_call(
  238. power_manager::kPowerManagerInterface,
  239. power_manager::kDecreaseScreenBrightnessMethod);
  240. dbus::MessageWriter writer(&method_call);
  241. writer.AppendBool(allow_off);
  242. power_manager_proxy_->CallMethod(&method_call,
  243. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  244. base::DoNothing());
  245. }
  246. void IncreaseScreenBrightness() override {
  247. SimpleMethodCallToPowerManager(
  248. power_manager::kIncreaseScreenBrightnessMethod);
  249. }
  250. void DecreaseKeyboardBrightness() override {
  251. SimpleMethodCallToPowerManager(
  252. power_manager::kDecreaseKeyboardBrightnessMethod);
  253. }
  254. void IncreaseKeyboardBrightness() override {
  255. SimpleMethodCallToPowerManager(
  256. power_manager::kIncreaseKeyboardBrightnessMethod);
  257. }
  258. const absl::optional<power_manager::PowerSupplyProperties>& GetLastStatus()
  259. override {
  260. return proto_;
  261. }
  262. void SetScreenBrightness(
  263. const power_manager::SetBacklightBrightnessRequest& request) override {
  264. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  265. power_manager::kSetScreenBrightnessMethod);
  266. if (!dbus::MessageWriter(&method_call).AppendProtoAsArrayOfBytes(request)) {
  267. POWER_LOG(ERROR) << "Error serializing "
  268. << power_manager::kSetScreenBrightnessMethod
  269. << " request";
  270. return;
  271. }
  272. power_manager_proxy_->CallMethod(&method_call,
  273. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  274. base::DoNothing());
  275. }
  276. void GetScreenBrightnessPercent(
  277. DBusMethodCallback<double> callback) override {
  278. dbus::MethodCall method_call(
  279. power_manager::kPowerManagerInterface,
  280. power_manager::kGetScreenBrightnessPercentMethod);
  281. power_manager_proxy_->CallMethod(
  282. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  283. base::BindOnce(
  284. &PowerManagerClientImpl::OnGetScreenOrKeyboardBrightnessPercent,
  285. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  286. }
  287. void GetKeyboardBrightnessPercent(
  288. DBusMethodCallback<double> callback) override {
  289. dbus::MethodCall method_call(
  290. power_manager::kPowerManagerInterface,
  291. power_manager::kGetKeyboardBrightnessPercentMethod);
  292. power_manager_proxy_->CallMethod(
  293. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  294. base::BindOnce(
  295. &PowerManagerClientImpl::OnGetScreenOrKeyboardBrightnessPercent,
  296. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  297. }
  298. void RequestStatusUpdate() override {
  299. POWER_LOG(USER) << "RequestStatusUpdate";
  300. dbus::MethodCall method_call(
  301. power_manager::kPowerManagerInterface,
  302. power_manager::kGetPowerSupplyPropertiesMethod);
  303. power_manager_proxy_->CallMethod(
  304. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  305. base::BindOnce(
  306. &PowerManagerClientImpl::OnGetPowerSupplyPropertiesMethod,
  307. weak_ptr_factory_.GetWeakPtr()));
  308. }
  309. void RequestAllPeripheralBatteryUpdate() override {
  310. POWER_LOG(USER) << "RequestAllPeripheralBatteryUpdate";
  311. dbus::MethodCall method_call(
  312. power_manager::kPowerManagerInterface,
  313. power_manager::kRefreshAllPeripheralBatteryMethod);
  314. power_manager_proxy_->CallMethod(
  315. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  316. base::BindOnce(
  317. &PowerManagerClientImpl::OnRefreshAllPeripheralBatteryMethod,
  318. weak_ptr_factory_.GetWeakPtr()));
  319. }
  320. void RequestThermalState() override {
  321. POWER_LOG(USER) << "RequestThermalState";
  322. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  323. power_manager::kGetThermalStateMethod);
  324. power_manager_proxy_->CallMethod(
  325. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  326. base::BindOnce(&PowerManagerClientImpl::OnGetCurrentThermalStateMethod,
  327. weak_ptr_factory_.GetWeakPtr()));
  328. }
  329. void RequestSuspend() override {
  330. POWER_LOG(USER) << "RequestSuspend";
  331. SimpleMethodCallToPowerManager(power_manager::kRequestSuspendMethod);
  332. }
  333. void RequestRestart(power_manager::RequestRestartReason reason,
  334. const std::string& description) override {
  335. POWER_LOG(USER) << "RequestRestart: " << reason << " (" << description
  336. << ")";
  337. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  338. power_manager::kRequestRestartMethod);
  339. dbus::MessageWriter writer(&method_call);
  340. writer.AppendInt32(reason);
  341. writer.AppendString(description);
  342. power_manager_proxy_->CallMethod(&method_call,
  343. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  344. base::DoNothing());
  345. }
  346. void RequestShutdown(power_manager::RequestShutdownReason reason,
  347. const std::string& description) override {
  348. POWER_LOG(USER) << "RequestShutdown: " << reason << " (" << description
  349. << ")";
  350. for (auto& observer : observers_)
  351. observer.ShutdownRequested(reason);
  352. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  353. power_manager::kRequestShutdownMethod);
  354. dbus::MessageWriter writer(&method_call);
  355. writer.AppendInt32(reason);
  356. writer.AppendString(description);
  357. power_manager_proxy_->CallMethod(&method_call,
  358. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  359. base::DoNothing());
  360. }
  361. void NotifyUserActivity(power_manager::UserActivityType type) override {
  362. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  363. power_manager::kHandleUserActivityMethod);
  364. dbus::MessageWriter writer(&method_call);
  365. writer.AppendInt32(type);
  366. power_manager_proxy_->CallMethod(&method_call,
  367. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  368. base::DoNothing());
  369. }
  370. void NotifyVideoActivity(bool is_fullscreen) override {
  371. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  372. power_manager::kHandleVideoActivityMethod);
  373. dbus::MessageWriter writer(&method_call);
  374. writer.AppendBool(is_fullscreen);
  375. power_manager_proxy_->CallMethod(&method_call,
  376. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  377. base::DoNothing());
  378. }
  379. void NotifyWakeNotification() override {
  380. SimpleMethodCallToPowerManager(
  381. power_manager::kHandleWakeNotificationMethod);
  382. }
  383. void SetPolicy(const power_manager::PowerManagementPolicy& policy) override {
  384. POWER_LOG(USER) << "SetPolicy";
  385. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  386. power_manager::kSetPolicyMethod);
  387. dbus::MessageWriter writer(&method_call);
  388. if (!writer.AppendProtoAsArrayOfBytes(policy)) {
  389. POWER_LOG(ERROR) << "Error calling " << power_manager::kSetPolicyMethod;
  390. return;
  391. }
  392. power_manager_proxy_->CallMethod(&method_call,
  393. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  394. base::DoNothing());
  395. }
  396. void SetIsProjecting(bool is_projecting) override {
  397. POWER_LOG(USER) << "SetIsProjecting";
  398. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  399. power_manager::kSetIsProjectingMethod);
  400. dbus::MessageWriter writer(&method_call);
  401. writer.AppendBool(is_projecting);
  402. power_manager_proxy_->CallMethod(&method_call,
  403. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  404. base::DoNothing());
  405. last_is_projecting_ = is_projecting;
  406. }
  407. void SetPowerSource(const std::string& id) override {
  408. POWER_LOG(USER) << "SetPowerSource: " << id;
  409. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  410. power_manager::kSetPowerSourceMethod);
  411. dbus::MessageWriter writer(&method_call);
  412. writer.AppendString(id);
  413. power_manager_proxy_->CallMethod(&method_call,
  414. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  415. base::DoNothing());
  416. }
  417. void SetBacklightsForcedOff(bool forced_off) override {
  418. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  419. power_manager::kSetBacklightsForcedOffMethod);
  420. dbus::MessageWriter(&method_call).AppendBool(forced_off);
  421. power_manager_proxy_->CallMethod(&method_call,
  422. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  423. base::DoNothing());
  424. }
  425. void GetBacklightsForcedOff(DBusMethodCallback<bool> callback) override {
  426. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  427. power_manager::kGetBacklightsForcedOffMethod);
  428. power_manager_proxy_->CallMethod(
  429. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  430. base::BindOnce(&PowerManagerClientImpl::OnGetBacklightsForcedOff,
  431. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  432. }
  433. void SetKeyboardBacklightToggledOff(bool toggled_off) override {
  434. dbus::MethodCall method_call(
  435. power_manager::kPowerManagerInterface,
  436. power_manager::kSetKeyboardBacklightToggledOffMethod);
  437. dbus::MessageWriter(&method_call).AppendBool(toggled_off);
  438. power_manager_proxy_->CallMethod(&method_call,
  439. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  440. base::DoNothing());
  441. }
  442. void GetKeyboardBacklightToggledOff(
  443. DBusMethodCallback<bool> callback) override {
  444. dbus::MethodCall method_call(
  445. power_manager::kPowerManagerInterface,
  446. power_manager::kGetKeyboardBacklightToggledOffMethod);
  447. power_manager_proxy_->CallMethod(
  448. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  449. base::BindOnce(
  450. &PowerManagerClientImpl::OnGetKeyboardBacklightToggledOff,
  451. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  452. }
  453. void GetSwitchStates(DBusMethodCallback<SwitchStates> callback) override {
  454. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  455. power_manager::kGetSwitchStatesMethod);
  456. power_manager_proxy_->CallMethod(
  457. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  458. base::BindOnce(&PowerManagerClientImpl::OnGetSwitchStates,
  459. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  460. }
  461. void GetInactivityDelays(
  462. DBusMethodCallback<power_manager::PowerManagementPolicy::Delays> callback)
  463. override {
  464. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  465. power_manager::kGetInactivityDelaysMethod);
  466. power_manager_proxy_->CallMethod(
  467. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  468. base::BindOnce(&PowerManagerClientImpl::OnGetInactivityDelays,
  469. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  470. }
  471. void BlockSuspend(const base::UnguessableToken& token,
  472. const std::string& debug_info) override {
  473. DCHECK(OnOriginThread());
  474. DCHECK(suspend_is_pending_);
  475. DCHECK(token);
  476. suspend_readiness_registry_[token.ToString()] = {
  477. pending_suspend_id_, suspending_from_dark_resume_, debug_info};
  478. }
  479. void UnblockSuspend(const base::UnguessableToken& token) override {
  480. DCHECK(OnOriginThread());
  481. auto registration = suspend_readiness_registry_.find(token.ToString());
  482. if (registration == suspend_readiness_registry_.end() ||
  483. registration->second.suspend_id != pending_suspend_id_ ||
  484. registration->second.suspending_from_dark_resume !=
  485. suspending_from_dark_resume_ ||
  486. !suspend_is_pending_) {
  487. return;
  488. }
  489. suspend_readiness_registry_.erase(registration);
  490. MaybeReportSuspendReadiness();
  491. }
  492. bool SupportsAmbientColor() override {
  493. return device_supports_ambient_color_;
  494. }
  495. void CreateArcTimers(
  496. const std::string& tag,
  497. std::vector<std::pair<clockid_t, base::ScopedFD>> arc_timer_requests,
  498. DBusMethodCallback<std::vector<TimerId>> callback) override {
  499. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  500. power_manager::kCreateArcTimersMethod);
  501. // Write mojo arguments i.e. client's tag and array of {int, fd} as a D-Bus
  502. // message.
  503. dbus::MessageWriter writer(&method_call);
  504. writer.AppendString(tag);
  505. dbus::MessageWriter array_writer(nullptr);
  506. writer.OpenArray("(ih)", &array_writer);
  507. for (const auto& request : arc_timer_requests) {
  508. dbus::MessageWriter struct_writer(nullptr);
  509. array_writer.OpenStruct(&struct_writer);
  510. struct_writer.AppendInt32(static_cast<int32_t>(request.first));
  511. // This dups the file descriptor and the original one stored as
  512. // base::ScopedFD in |arc_timer_requests| will be closed when the function
  513. // ends and it goes out of scope.
  514. struct_writer.AppendFileDescriptor(request.second.get());
  515. array_writer.CloseContainer(&struct_writer);
  516. }
  517. writer.CloseContainer(&array_writer);
  518. power_manager_proxy_->CallMethod(
  519. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  520. base::BindOnce(&OnCreateArcTimersDBusMethod, std::move(callback)));
  521. }
  522. void StartArcTimer(TimerId timer_id,
  523. base::TimeTicks absolute_expiration_time,
  524. VoidDBusMethodCallback callback) override {
  525. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  526. power_manager::kStartArcTimerMethod);
  527. // Write clock id and 64-bit expiration time ticks value as a D-Bus message.
  528. dbus::MessageWriter writer(&method_call);
  529. writer.AppendInt32(timer_id);
  530. // The absolute ticks are still being sent because base::TimeTicks() returns
  531. // 0.
  532. writer.AppendInt64(
  533. (absolute_expiration_time - base::TimeTicks()).InMicroseconds());
  534. power_manager_proxy_->CallMethod(
  535. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  536. base::BindOnce(&OnVoidDBusMethod, std::move(callback)));
  537. }
  538. void DeleteArcTimers(const std::string& tag,
  539. VoidDBusMethodCallback callback) override {
  540. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  541. power_manager::kDeleteArcTimersMethod);
  542. dbus::MessageWriter writer(&method_call);
  543. writer.AppendString(tag);
  544. power_manager_proxy_->CallMethod(
  545. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  546. base::BindOnce(&OnVoidDBusMethod, std::move(callback)));
  547. }
  548. base::TimeDelta GetDarkSuspendDelayTimeout() override {
  549. return max_dark_suspend_delay_timeout_;
  550. }
  551. void RefreshBluetoothBattery(const std::string& address) override {
  552. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  553. power_manager::kRefreshBluetoothBatteryMethod);
  554. dbus::MessageWriter writer(&method_call);
  555. writer.AppendString(address);
  556. // This refresh request is best effort, so we don't have to handle errors.
  557. power_manager_proxy_->CallMethod(&method_call,
  558. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  559. base::DoNothing());
  560. }
  561. void SetExternalDisplayALSBrightness(bool enabled) override {
  562. dbus::MethodCall method_call(
  563. power_manager::kPowerManagerInterface,
  564. power_manager::kSetExternalDisplayALSBrightnessMethod);
  565. dbus::MessageWriter writer(&method_call);
  566. writer.AppendBool(enabled);
  567. power_manager_proxy_->CallMethod(&method_call,
  568. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  569. base::DoNothing());
  570. }
  571. void GetExternalDisplayALSBrightness(
  572. DBusMethodCallback<bool> callback) override {
  573. dbus::MethodCall method_call(
  574. power_manager::kPowerManagerInterface,
  575. power_manager::kGetExternalDisplayALSBrightnessMethod);
  576. power_manager_proxy_->CallMethod(
  577. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  578. base::BindOnce(
  579. &PowerManagerClientImpl::OnGetExternalDisplayALSBrightness,
  580. weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
  581. }
  582. void ChargeNowForAdaptiveCharging() override {
  583. dbus::MethodCall method_call(
  584. power_manager::kPowerManagerInterface,
  585. power_manager::kChargeNowForAdaptiveChargingMethod);
  586. power_manager_proxy_->CallMethod(&method_call,
  587. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  588. base::DoNothing());
  589. }
  590. private:
  591. // Returns true if the current thread is the origin thread.
  592. bool OnOriginThread() {
  593. return base::PlatformThread::CurrentId() == origin_thread_id_;
  594. }
  595. // Called when a dbus signal is initially connected.
  596. void SignalConnected(const std::string& interface_name,
  597. const std::string& signal_name,
  598. bool success) {
  599. if (!success)
  600. POWER_LOG(ERROR) << "Failed to connect to signal " << signal_name << ".";
  601. }
  602. // Makes a method call to power manager with no arguments and no response.
  603. void SimpleMethodCallToPowerManager(const std::string& method_name) {
  604. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  605. method_name);
  606. power_manager_proxy_->CallMethod(&method_call,
  607. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  608. base::DoNothing());
  609. }
  610. void NotifyServiceBecameAvailable(bool available) {
  611. service_available_ = available;
  612. for (auto& observer : observers_)
  613. observer.PowerManagerBecameAvailable(available);
  614. }
  615. void NameOwnerChangedReceived(const std::string& old_owner,
  616. const std::string& new_owner) {
  617. POWER_LOG(EVENT) << "Power manager restarted. Old owner: "
  618. << (old_owner.empty() ? "[none]" : old_owner.c_str())
  619. << " New owner: "
  620. << (new_owner.empty() ? "[none]" : new_owner.c_str());
  621. suspend_is_pending_ = false;
  622. pending_suspend_id_ = -1;
  623. suspending_from_dark_resume_ = false;
  624. if (!new_owner.empty()) {
  625. POWER_LOG(EVENT) << "Sending initial state to power manager";
  626. RegisterSuspendDelays();
  627. SetIsProjecting(last_is_projecting_);
  628. for (auto& observer : observers_)
  629. observer.PowerManagerRestarted();
  630. }
  631. }
  632. void NotifyInitialization() {
  633. for (auto& observer : observers_)
  634. observer.PowerManagerInitialized();
  635. }
  636. void ScreenBrightnessChangedReceived(dbus::Signal* signal) {
  637. dbus::MessageReader reader(signal);
  638. power_manager::BacklightBrightnessChange proto;
  639. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  640. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  641. << power_manager::kScreenBrightnessChangedSignal
  642. << " signal";
  643. return;
  644. }
  645. POWER_LOG(DEBUG) << "Screen brightness changed to " << proto.percent()
  646. << ": cause " << proto.cause();
  647. for (auto& observer : observers_)
  648. observer.ScreenBrightnessChanged(proto);
  649. }
  650. void AmbientColorTemperatureChangedReceived(dbus::Signal* signal) {
  651. dbus::MessageReader reader(signal);
  652. int32_t color_temperature = 0;
  653. if (!reader.PopInt32(&color_temperature)) {
  654. POWER_LOG(ERROR) << "Unable to decode read ambient color from "
  655. << power_manager::kAmbientColorTemperatureChangedSignal
  656. << " signal";
  657. return;
  658. }
  659. for (auto& observer : observers_)
  660. observer.AmbientColorChanged(color_temperature);
  661. }
  662. void KeyboardBrightnessChangedReceived(dbus::Signal* signal) {
  663. dbus::MessageReader reader(signal);
  664. power_manager::BacklightBrightnessChange proto;
  665. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  666. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  667. << power_manager::kKeyboardBrightnessChangedSignal
  668. << " signal";
  669. return;
  670. }
  671. POWER_LOG(DEBUG) << "Keyboard brightness changed to " << proto.percent()
  672. << ": cause " << proto.cause();
  673. for (auto& observer : observers_)
  674. observer.KeyboardBrightnessChanged(proto);
  675. }
  676. void ScreenIdleStateChangedReceived(dbus::Signal* signal) {
  677. dbus::MessageReader reader(signal);
  678. power_manager::ScreenIdleState proto;
  679. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  680. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  681. << power_manager::kScreenIdleStateChangedSignal
  682. << " signal";
  683. return;
  684. }
  685. for (auto& observer : observers_)
  686. observer.ScreenIdleStateChanged(proto);
  687. }
  688. void InactivityDelaysChangedReceived(dbus::Signal* signal) {
  689. dbus::MessageReader reader(signal);
  690. power_manager::PowerManagementPolicy::Delays proto;
  691. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  692. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  693. << power_manager::kInactivityDelaysChangedSignal
  694. << " signal";
  695. return;
  696. }
  697. for (auto& observer : observers_)
  698. observer.InactivityDelaysChanged(proto);
  699. }
  700. void PeripheralBatteryStatusReceived(dbus::Signal* signal) {
  701. dbus::MessageReader reader(signal);
  702. power_manager::PeripheralBatteryStatus protobuf_status;
  703. if (!reader.PopArrayOfBytesAsProto(&protobuf_status)) {
  704. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  705. << power_manager::kPeripheralBatteryStatusSignal
  706. << " signal";
  707. return;
  708. }
  709. std::string path = protobuf_status.path();
  710. std::string name = protobuf_status.name();
  711. int level = protobuf_status.has_level() ? protobuf_status.level() : -1;
  712. power_manager::PeripheralBatteryStatus_ChargeStatus status =
  713. protobuf_status.has_charge_status()
  714. ? protobuf_status.charge_status()
  715. : power_manager::
  716. PeripheralBatteryStatus_ChargeStatus_CHARGE_STATUS_UNKNOWN;
  717. bool active_update = protobuf_status.has_active_update()
  718. ? protobuf_status.active_update()
  719. : false;
  720. std::string serial_number = "";
  721. if (protobuf_status.has_serial_number())
  722. serial_number = protobuf_status.serial_number();
  723. for (auto& observer : observers_)
  724. observer.PeripheralBatteryStatusReceived(path, name, level, status,
  725. serial_number, active_update);
  726. }
  727. void PowerSupplyPollReceived(dbus::Signal* signal) {
  728. POWER_LOG(DEBUG) << "Received power supply poll signal.";
  729. dbus::MessageReader reader(signal);
  730. power_manager::PowerSupplyProperties protobuf;
  731. if (reader.PopArrayOfBytesAsProto(&protobuf)) {
  732. HandlePowerSupplyProperties(protobuf);
  733. } else {
  734. POWER_LOG(ERROR) << "Unable to decode "
  735. << power_manager::kPowerSupplyPollSignal << " signal";
  736. }
  737. }
  738. void OnGetCurrentThermalStateMethod(dbus::Response* response) {
  739. if (!response) {
  740. POWER_LOG(ERROR) << "Error calling "
  741. << power_manager::kGetThermalStateMethod;
  742. return;
  743. }
  744. dbus::MessageReader reader(response);
  745. power_manager::ThermalEvent protobuf;
  746. if (!reader.PopArrayOfBytesAsProto(&protobuf)) {
  747. POWER_LOG(ERROR) << "Unable to decode "
  748. << power_manager::kGetThermalStateMethod << " response";
  749. return;
  750. }
  751. POWER_LOG(USER) << "Got " << power_manager::kGetThermalStateMethod
  752. << " response:"
  753. << " thermal_state=" << protobuf.thermal_state()
  754. << " timestamp=" << protobuf.timestamp();
  755. base::PowerMonitorDeviceSource::ThermalEventReceived(
  756. GetThermalStateFromProtoEnum(protobuf.thermal_state()));
  757. }
  758. void OnGetPowerSupplyPropertiesMethod(dbus::Response* response) {
  759. // This is the last callback to run after all the initialization in |Init|.
  760. // Notify all observers that the initialization is complete.
  761. base::ScopedClosureRunner notify_runner(base::BindOnce(
  762. &PowerManagerClientImpl::NotifyInitialization, base::Unretained(this)));
  763. if (!response) {
  764. POWER_LOG(ERROR) << "Error calling "
  765. << power_manager::kGetPowerSupplyPropertiesMethod;
  766. return;
  767. }
  768. dbus::MessageReader reader(response);
  769. power_manager::PowerSupplyProperties protobuf;
  770. if (reader.PopArrayOfBytesAsProto(&protobuf)) {
  771. HandlePowerSupplyProperties(protobuf);
  772. } else {
  773. POWER_LOG(ERROR) << "Unable to decode "
  774. << power_manager::kGetPowerSupplyPropertiesMethod
  775. << " response";
  776. }
  777. }
  778. void OnRefreshAllPeripheralBatteryMethod(dbus::Response* response) {
  779. if (!response) {
  780. POWER_LOG(ERROR) << "Error calling "
  781. << power_manager::kRefreshAllPeripheralBatteryMethod;
  782. return;
  783. }
  784. }
  785. void OnGetScreenOrKeyboardBrightnessPercent(
  786. DBusMethodCallback<double> callback,
  787. dbus::Response* response) {
  788. if (!response) {
  789. std::move(callback).Run(absl::nullopt);
  790. return;
  791. }
  792. dbus::MessageReader reader(response);
  793. double percent = 0.0;
  794. if (!reader.PopDouble(&percent)) {
  795. POWER_LOG(ERROR) << "Error reading response from powerd: "
  796. << response->ToString();
  797. std::move(callback).Run(absl::nullopt);
  798. return;
  799. }
  800. std::move(callback).Run(percent);
  801. }
  802. void OnGetBacklightsForcedOff(DBusMethodCallback<bool> callback,
  803. dbus::Response* response) {
  804. if (!response) {
  805. POWER_LOG(ERROR) << "Error calling "
  806. << power_manager::kGetBacklightsForcedOffMethod;
  807. std::move(callback).Run(absl::nullopt);
  808. return;
  809. }
  810. dbus::MessageReader reader(response);
  811. bool state = false;
  812. if (!reader.PopBool(&state)) {
  813. POWER_LOG(ERROR) << "Error reading response from powerd: "
  814. << response->ToString();
  815. std::move(callback).Run(absl::nullopt);
  816. return;
  817. }
  818. std::move(callback).Run(state);
  819. }
  820. void OnGetKeyboardBacklightToggledOff(DBusMethodCallback<bool> callback,
  821. dbus::Response* response) {
  822. if (!response) {
  823. POWER_LOG(ERROR) << "Error calling "
  824. << power_manager::kGetKeyboardBacklightToggledOffMethod;
  825. std::move(callback).Run(absl::nullopt);
  826. return;
  827. }
  828. dbus::MessageReader reader(response);
  829. bool toggled_off = false;
  830. if (!reader.PopBool(&toggled_off)) {
  831. POWER_LOG(ERROR) << "Error reading response from powerd: "
  832. << response->ToString();
  833. std::move(callback).Run(absl::nullopt);
  834. return;
  835. }
  836. std::move(callback).Run(toggled_off);
  837. }
  838. void CheckAmbientColorSupport() {
  839. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  840. power_manager::kHasAmbientColorDeviceMethod);
  841. power_manager_proxy_->CallMethod(
  842. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  843. base::BindOnce(&PowerManagerClientImpl::OnHasAmbientColorDevice,
  844. weak_ptr_factory_.GetWeakPtr()));
  845. }
  846. void OnHasAmbientColorDevice(dbus::Response* response) {
  847. if (!response) {
  848. device_supports_ambient_color_ = false;
  849. return;
  850. }
  851. dbus::MessageReader reader(response);
  852. bool is_supported = false;
  853. if (!reader.PopBool(&is_supported)) {
  854. POWER_LOG(ERROR) << "Error reading response from powerd: "
  855. << response->ToString();
  856. device_supports_ambient_color_ = false;
  857. return;
  858. }
  859. device_supports_ambient_color_ = is_supported;
  860. }
  861. void OnGetSwitchStates(DBusMethodCallback<SwitchStates> callback,
  862. dbus::Response* response) {
  863. if (!response) {
  864. POWER_LOG(ERROR) << "Error calling "
  865. << power_manager::kGetSwitchStatesMethod;
  866. std::move(callback).Run(absl::nullopt);
  867. return;
  868. }
  869. dbus::MessageReader reader(response);
  870. power_manager::SwitchStates proto;
  871. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  872. POWER_LOG(ERROR) << "Error parsing response from "
  873. << power_manager::kGetSwitchStatesMethod;
  874. std::move(callback).Run(absl::nullopt);
  875. return;
  876. }
  877. std::move(callback).Run(
  878. SwitchStates{GetLidStateFromProtoEnum(proto.lid_state()),
  879. GetTabletModeFromProtoEnum(proto.tablet_mode())});
  880. }
  881. void OnGetInactivityDelays(
  882. DBusMethodCallback<power_manager::PowerManagementPolicy::Delays> callback,
  883. dbus::Response* response) {
  884. if (!response) {
  885. POWER_LOG(ERROR) << "Error calling "
  886. << power_manager::kGetInactivityDelaysMethod;
  887. std::move(callback).Run(absl::nullopt);
  888. return;
  889. }
  890. dbus::MessageReader reader(response);
  891. power_manager::PowerManagementPolicy::Delays proto;
  892. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  893. POWER_LOG(ERROR) << "Error parsing response from "
  894. << power_manager::kGetInactivityDelaysMethod;
  895. std::move(callback).Run(absl::nullopt);
  896. return;
  897. }
  898. std::move(callback).Run(proto);
  899. }
  900. void OnGetExternalDisplayALSBrightness(DBusMethodCallback<bool> callback,
  901. dbus::Response* response) {
  902. if (!response) {
  903. POWER_LOG(ERROR) << "Error calling "
  904. << power_manager::kGetExternalDisplayALSBrightnessMethod;
  905. std::move(callback).Run(false);
  906. return;
  907. }
  908. dbus::MessageReader reader(response);
  909. bool enabled = false;
  910. if (!reader.PopBool(&enabled)) {
  911. POWER_LOG(ERROR) << "Error parsing response from "
  912. << power_manager::kGetExternalDisplayALSBrightnessMethod;
  913. std::move(callback).Run(false);
  914. return;
  915. }
  916. std::move(callback).Run(enabled);
  917. }
  918. void HandlePowerSupplyProperties(
  919. const power_manager::PowerSupplyProperties& proto) {
  920. proto_ = SanitizePowerSupplyProperties(proto);
  921. for (auto& observer : observers_)
  922. observer.PowerChanged(*proto_);
  923. const bool on_battery =
  924. proto_->external_power() ==
  925. power_manager::PowerSupplyProperties_ExternalPower_DISCONNECTED;
  926. base::PowerMonitorDeviceSource::SetPowerSource(on_battery);
  927. }
  928. void HandleRegisterSuspendDelayReply(bool dark_suspend,
  929. const std::string& method_name,
  930. dbus::Response* response) {
  931. if (!response) {
  932. POWER_LOG(ERROR) << "Error calling " << method_name;
  933. return;
  934. }
  935. dbus::MessageReader reader(response);
  936. power_manager::RegisterSuspendDelayReply protobuf;
  937. if (!reader.PopArrayOfBytesAsProto(&protobuf)) {
  938. POWER_LOG(ERROR) << "Unable to parse reply from " << method_name;
  939. return;
  940. }
  941. if (dark_suspend) {
  942. dark_suspend_delay_id_ = protobuf.delay_id();
  943. has_dark_suspend_delay_id_ = true;
  944. // Set |max_dark_suspend_delay_timeout_| to the minimum time power manager
  945. // guarantees before resuspending.
  946. max_dark_suspend_delay_timeout_ =
  947. base::Milliseconds(protobuf.min_delay_timeout_ms());
  948. POWER_LOG(EVENT) << "Registered dark suspend delay "
  949. << dark_suspend_delay_id_;
  950. } else {
  951. suspend_delay_id_ = protobuf.delay_id();
  952. has_suspend_delay_id_ = true;
  953. POWER_LOG(EVENT) << "Registered suspend delay " << suspend_delay_id_;
  954. }
  955. }
  956. void SuspendImminentReceived(dbus::Signal* signal) {
  957. HandleSuspendImminent(false /* in_dark_resume */, signal);
  958. }
  959. void DarkSuspendImminentReceived(dbus::Signal* signal) {
  960. HandleSuspendImminent(true /* in_dark_resume */, signal);
  961. }
  962. void HandleSuspendImminent(bool in_dark_resume, dbus::Signal* signal) {
  963. std::string signal_name = signal->GetMember();
  964. if ((in_dark_resume && !has_dark_suspend_delay_id_) ||
  965. (!in_dark_resume && !has_suspend_delay_id_)) {
  966. POWER_LOG(ERROR) << "Received unrequested " << signal_name << " signal";
  967. return;
  968. }
  969. dbus::MessageReader reader(signal);
  970. power_manager::SuspendImminent proto;
  971. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  972. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  973. << signal_name << " signal";
  974. return;
  975. }
  976. POWER_LOG(EVENT) << "Got " << signal_name
  977. << " signal announcing suspend attempt "
  978. << proto.suspend_id();
  979. // If a previous suspend is pending from the same state we are currently in
  980. // (fully powered on or in dark resume), then something's gone a little
  981. // wonky.
  982. if (suspend_is_pending_ && suspending_from_dark_resume_ == in_dark_resume) {
  983. POWER_LOG(ERROR) << "Got " << signal_name
  984. << " signal about pending suspend attempt "
  985. << proto.suspend_id()
  986. << " while still waiting on attempt "
  987. << pending_suspend_id_;
  988. }
  989. pending_suspend_id_ = proto.suspend_id();
  990. suspend_is_pending_ = true;
  991. suspending_from_dark_resume_ = in_dark_resume;
  992. suspend_readiness_registry_.clear();
  993. // Record the fact that observers are being notified to ensure that we don't
  994. // report readiness prematurely if one of them calls BlockSuspend() and then
  995. // runs UnblockSuspend() synchonously instead of asynchronously.
  996. notifying_observers_about_suspend_imminent_ = true;
  997. if (suspending_from_dark_resume_) {
  998. for (auto& observer : observers_)
  999. observer.DarkSuspendImminent();
  1000. } else {
  1001. for (auto& observer : observers_)
  1002. observer.SuspendImminent(proto.reason());
  1003. }
  1004. notifying_observers_about_suspend_imminent_ = false;
  1005. base::PowerMonitorDeviceSource::HandleSystemSuspending();
  1006. MaybeReportSuspendReadiness();
  1007. }
  1008. void SuspendDoneReceived(dbus::Signal* signal) {
  1009. dbus::MessageReader reader(signal);
  1010. power_manager::SuspendDone proto;
  1011. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  1012. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  1013. << power_manager::kSuspendDoneSignal << " signal";
  1014. return;
  1015. }
  1016. const base::TimeDelta duration =
  1017. base::TimeDelta::FromInternalValue(proto.suspend_duration());
  1018. POWER_LOG(EVENT) << "Got " << power_manager::kSuspendDoneSignal
  1019. << " signal:"
  1020. << " suspend_id=" << proto.suspend_id()
  1021. << " duration=" << duration.InSeconds() << " sec"
  1022. << " deepest_state=" << proto.deepest_state();
  1023. // RenderProcessManagerDelegate is only notified that suspend is imminent
  1024. // when readiness is being reported to powerd. If the suspend attempt was
  1025. // cancelled before then, we shouldn't notify the delegate about completion.
  1026. const bool cancelled_while_regular_suspend_pending =
  1027. suspend_is_pending_ && !suspending_from_dark_resume_;
  1028. if (render_process_manager_delegate_ &&
  1029. !cancelled_while_regular_suspend_pending)
  1030. render_process_manager_delegate_->SuspendDone();
  1031. // powerd always pairs each SuspendImminent signal with SuspendDone before
  1032. // starting the next suspend attempt, so we should no longer report
  1033. // readiness for any in-progress suspend attempts.
  1034. pending_suspend_id_ = -1;
  1035. suspend_is_pending_ = false;
  1036. suspending_from_dark_resume_ = false;
  1037. // powerd gives clients a limited amount of time to report suspend
  1038. // readiness. Log the stragglers within Chrome to aid in debugging.
  1039. for (const auto& it : suspend_readiness_registry_) {
  1040. LOG(WARNING) << "Didn't report suspend readiness due to "
  1041. << it.second.debug_info;
  1042. }
  1043. suspend_readiness_registry_.clear();
  1044. for (auto& observer : observers_)
  1045. observer.SuspendDoneEx(proto);
  1046. base::PowerMonitorDeviceSource::HandleSystemResumed();
  1047. }
  1048. void IdleActionImminentReceived(dbus::Signal* signal) {
  1049. dbus::MessageReader reader(signal);
  1050. power_manager::IdleActionImminent proto;
  1051. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  1052. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  1053. << power_manager::kIdleActionImminentSignal << " signal";
  1054. return;
  1055. }
  1056. for (auto& observer : observers_) {
  1057. observer.IdleActionImminent(
  1058. base::TimeDelta::FromInternalValue(proto.time_until_idle_action()));
  1059. }
  1060. }
  1061. void IdleActionDeferredReceived(dbus::Signal* signal) {
  1062. for (auto& observer : observers_)
  1063. observer.IdleActionDeferred();
  1064. }
  1065. void InputEventReceived(dbus::Signal* signal) {
  1066. dbus::MessageReader reader(signal);
  1067. power_manager::InputEvent proto;
  1068. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  1069. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  1070. << power_manager::kInputEventSignal << " signal";
  1071. return;
  1072. }
  1073. base::TimeTicks timestamp =
  1074. base::TimeTicks::FromInternalValue(proto.timestamp());
  1075. POWER_LOG(USER) << "Got " << power_manager::kInputEventSignal << " signal:"
  1076. << " type=" << proto.type()
  1077. << " timestamp=" << proto.timestamp();
  1078. switch (proto.type()) {
  1079. case power_manager::InputEvent_Type_POWER_BUTTON_DOWN:
  1080. case power_manager::InputEvent_Type_POWER_BUTTON_UP: {
  1081. const bool down =
  1082. (proto.type() == power_manager::InputEvent_Type_POWER_BUTTON_DOWN);
  1083. for (auto& observer : observers_)
  1084. observer.PowerButtonEventReceived(down, timestamp);
  1085. // Tell powerd that Chrome has handled power button presses.
  1086. if (down) {
  1087. dbus::MethodCall method_call(
  1088. power_manager::kPowerManagerInterface,
  1089. power_manager::kHandlePowerButtonAcknowledgmentMethod);
  1090. dbus::MessageWriter writer(&method_call);
  1091. writer.AppendInt64(proto.timestamp());
  1092. power_manager_proxy_->CallMethod(
  1093. &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  1094. base::DoNothing());
  1095. }
  1096. break;
  1097. }
  1098. case power_manager::InputEvent_Type_LID_OPEN:
  1099. for (auto& observer : observers_)
  1100. observer.LidEventReceived(LidState::OPEN, timestamp);
  1101. break;
  1102. case power_manager::InputEvent_Type_LID_CLOSED:
  1103. for (auto& observer : observers_)
  1104. observer.LidEventReceived(LidState::CLOSED, timestamp);
  1105. break;
  1106. case power_manager::InputEvent_Type_TABLET_MODE_ON:
  1107. for (auto& observer : observers_)
  1108. observer.TabletModeEventReceived(TabletMode::ON, timestamp);
  1109. break;
  1110. case power_manager::InputEvent_Type_TABLET_MODE_OFF:
  1111. for (auto& observer : observers_)
  1112. observer.TabletModeEventReceived(TabletMode::OFF, timestamp);
  1113. break;
  1114. default:
  1115. // TODO(henryhsu): handle the missing cases.
  1116. break;
  1117. }
  1118. }
  1119. void ThermalEventReceived(dbus::Signal* signal) {
  1120. dbus::MessageReader reader(signal);
  1121. power_manager::ThermalEvent proto;
  1122. if (!reader.PopArrayOfBytesAsProto(&proto)) {
  1123. POWER_LOG(ERROR) << "Unable to decode protocol buffer from "
  1124. << power_manager::kThermalEventSignal << " signal";
  1125. return;
  1126. }
  1127. POWER_LOG(USER) << "Got " << power_manager::kThermalEventSignal
  1128. << " signal:"
  1129. << " thermal_state=" << proto.thermal_state()
  1130. << " timestamp=" << proto.timestamp();
  1131. base::PowerMonitorDeviceSource::ThermalEventReceived(
  1132. GetThermalStateFromProtoEnum(proto.thermal_state()));
  1133. }
  1134. void RegisterSuspendDelayImpl(
  1135. const std::string& method_name,
  1136. const power_manager::RegisterSuspendDelayRequest& protobuf_request,
  1137. dbus::ObjectProxy::ResponseCallback callback) {
  1138. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  1139. method_name);
  1140. dbus::MessageWriter writer(&method_call);
  1141. if (!writer.AppendProtoAsArrayOfBytes(protobuf_request)) {
  1142. POWER_LOG(ERROR) << "Error constructing message for " << method_name;
  1143. return;
  1144. }
  1145. power_manager_proxy_->CallMethod(&method_call,
  1146. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  1147. std::move(callback));
  1148. }
  1149. // Registers suspend delays with the power manager. This is usually only
  1150. // called at startup, but if the power manager restarts, we need to create new
  1151. // delays.
  1152. void RegisterSuspendDelays() {
  1153. // Throw out any old delay that was registered.
  1154. suspend_delay_id_ = -1;
  1155. has_suspend_delay_id_ = false;
  1156. dark_suspend_delay_id_ = -1;
  1157. has_dark_suspend_delay_id_ = false;
  1158. power_manager::RegisterSuspendDelayRequest protobuf_request;
  1159. base::TimeDelta timeout = base::Milliseconds(kSuspendDelayTimeoutMs);
  1160. protobuf_request.set_timeout(timeout.ToInternalValue());
  1161. protobuf_request.set_description(kSuspendDelayDescription);
  1162. RegisterSuspendDelayImpl(
  1163. power_manager::kRegisterSuspendDelayMethod, protobuf_request,
  1164. base::BindOnce(&PowerManagerClientImpl::HandleRegisterSuspendDelayReply,
  1165. weak_ptr_factory_.GetWeakPtr(), false,
  1166. power_manager::kRegisterSuspendDelayMethod));
  1167. if (base::CommandLine::ForCurrentProcess()->HasSwitch(
  1168. chromeos::switches::kRegisterMaxDarkSuspendDelay)) {
  1169. // Negative timeout means request maximum delay.
  1170. protobuf_request.set_timeout(-1);
  1171. }
  1172. RegisterSuspendDelayImpl(
  1173. power_manager::kRegisterDarkSuspendDelayMethod, protobuf_request,
  1174. base::BindOnce(&PowerManagerClientImpl::HandleRegisterSuspendDelayReply,
  1175. weak_ptr_factory_.GetWeakPtr(), true,
  1176. power_manager::kRegisterDarkSuspendDelayMethod));
  1177. }
  1178. // Reports suspend readiness to powerd if no observers are still holding
  1179. // suspend readiness callbacks.
  1180. void MaybeReportSuspendReadiness() {
  1181. DCHECK(suspend_is_pending_);
  1182. // Avoid reporting suspend readiness if some observers have yet to be
  1183. // notified about the pending attempt.
  1184. if (notifying_observers_about_suspend_imminent_)
  1185. return;
  1186. if (!suspend_readiness_registry_.empty())
  1187. return;
  1188. std::string method_name;
  1189. int32_t delay_id = -1;
  1190. if (suspending_from_dark_resume_) {
  1191. method_name = power_manager::kHandleDarkSuspendReadinessMethod;
  1192. delay_id = dark_suspend_delay_id_;
  1193. } else {
  1194. method_name = power_manager::kHandleSuspendReadinessMethod;
  1195. delay_id = suspend_delay_id_;
  1196. }
  1197. if (render_process_manager_delegate_ && !suspending_from_dark_resume_)
  1198. render_process_manager_delegate_->SuspendImminent();
  1199. dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
  1200. method_name);
  1201. dbus::MessageWriter writer(&method_call);
  1202. POWER_LOG(EVENT) << "Announcing readiness of suspend delay " << delay_id
  1203. << " for suspend attempt " << pending_suspend_id_;
  1204. power_manager::SuspendReadinessInfo protobuf_request;
  1205. protobuf_request.set_delay_id(delay_id);
  1206. protobuf_request.set_suspend_id(pending_suspend_id_);
  1207. pending_suspend_id_ = -1;
  1208. suspend_is_pending_ = false;
  1209. if (!writer.AppendProtoAsArrayOfBytes(protobuf_request)) {
  1210. POWER_LOG(ERROR) << "Error constructing message for " << method_name;
  1211. return;
  1212. }
  1213. power_manager_proxy_->CallMethod(&method_call,
  1214. dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
  1215. base::DoNothing());
  1216. }
  1217. // Origin thread (i.e. the UI thread in production).
  1218. base::PlatformThreadId origin_thread_id_;
  1219. dbus::ObjectProxy* power_manager_proxy_ = nullptr;
  1220. base::ObserverList<Observer>::Unchecked observers_;
  1221. absl::optional<bool> service_available_;
  1222. // The delay ID obtained from the RegisterSuspendDelay request.
  1223. int32_t suspend_delay_id_ = -1;
  1224. bool has_suspend_delay_id_ = false;
  1225. // The delay ID obtained from the RegisterDarkSuspendDelay request.
  1226. int32_t dark_suspend_delay_id_ = -1;
  1227. bool has_dark_suspend_delay_id_ = false;
  1228. // The maximum time power manager will wait before resuspending from a dark
  1229. // resume.
  1230. base::TimeDelta max_dark_suspend_delay_timeout_;
  1231. // powerd-supplied ID corresponding to an imminent (either regular or dark)
  1232. // suspend attempt that is currently being delayed.
  1233. int32_t pending_suspend_id_ = -1;
  1234. bool suspend_is_pending_ = false;
  1235. // Set to true when the suspend currently being delayed was triggered during a
  1236. // dark resume. Since |pending_suspend_id_| and |suspend_is_pending_| are
  1237. // both shared by normal and dark suspends, |suspending_from_dark_resume_|
  1238. // helps distinguish the context within which these variables are being used.
  1239. bool suspending_from_dark_resume_ = false;
  1240. struct SuspendInfo {
  1241. int32_t suspend_id;
  1242. bool suspending_from_dark_resume;
  1243. std::string debug_info;
  1244. };
  1245. // A map that holds BlockSuspend() registrations. It maps from the token (in
  1246. // string form) to details about the suspend.
  1247. std::unordered_map<std::string, SuspendInfo> suspend_readiness_registry_;
  1248. // Inspected by MaybeReportSuspendReadiness() to avoid prematurely notifying
  1249. // powerd about suspend readiness while |observers_|' SuspendImminent()
  1250. // methods are being called by HandleSuspendImminent().
  1251. bool notifying_observers_about_suspend_imminent_ = false;
  1252. // Last state passed to SetIsProjecting().
  1253. bool last_is_projecting_ = false;
  1254. // Whether the device supports ambient color. This value is checked when the
  1255. // DBUS service starts and is cached.
  1256. bool device_supports_ambient_color_ = false;
  1257. // The last proto received from D-Bus; initially empty.
  1258. absl::optional<power_manager::PowerSupplyProperties> proto_;
  1259. // The delegate used to manage the power consumption of Chrome's renderer
  1260. // processes.
  1261. base::WeakPtr<RenderProcessManagerDelegate> render_process_manager_delegate_;
  1262. // Note: This should remain the last member so it'll be destroyed and
  1263. // invalidate its weak pointers before any other members are destroyed.
  1264. base::WeakPtrFactory<PowerManagerClientImpl> weak_ptr_factory_{this};
  1265. };
  1266. PowerManagerClient::PowerManagerClient() {
  1267. DCHECK(!g_instance);
  1268. g_instance = this;
  1269. }
  1270. PowerManagerClient::~PowerManagerClient() {
  1271. DCHECK_EQ(g_instance, this);
  1272. g_instance = nullptr;
  1273. }
  1274. // static
  1275. void PowerManagerClient::Initialize(dbus::Bus* bus) {
  1276. DCHECK(bus);
  1277. DCHECK(!g_instance);
  1278. auto* power_manager_client = new PowerManagerClientImpl();
  1279. power_manager_client->Init(bus);
  1280. g_instance = power_manager_client;
  1281. }
  1282. // static
  1283. void PowerManagerClient::InitializeFake() {
  1284. new FakePowerManagerClient();
  1285. }
  1286. // static
  1287. void PowerManagerClient::Shutdown() {
  1288. delete g_instance;
  1289. }
  1290. // static
  1291. PowerManagerClient* PowerManagerClient::Get() {
  1292. return g_instance;
  1293. }
  1294. void PowerManagerClient::Observer::SuspendDoneEx(
  1295. const power_manager::SuspendDone& proto) {
  1296. const base::TimeDelta duration =
  1297. base::TimeDelta::FromInternalValue(proto.suspend_duration());
  1298. this->SuspendDone(duration);
  1299. }
  1300. } // namespace chromeos