power_policy_controller.cc 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. // Copyright (c) 2013 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_policy_controller.h"
  5. #include <stdint.h>
  6. #include <algorithm>
  7. #include <memory>
  8. #include <utility>
  9. #include "base/format_macros.h"
  10. #include "base/logging.h"
  11. #include "base/strings/string_util.h"
  12. #include "base/strings/stringprintf.h"
  13. #include "chromeos/dbus/power_manager/backlight.pb.h"
  14. // Avoid some ugly line-wrapping later.
  15. using base::StringAppendF;
  16. namespace chromeos {
  17. namespace {
  18. PowerPolicyController* g_power_policy_controller = nullptr;
  19. // Appends a description of |field|, a field within |delays|, a
  20. // power_manager::PowerManagementPolicy::Delays object, to |str|, an
  21. // std::string, if the field is set. |name| is a char* describing the
  22. // field.
  23. #define APPEND_DELAY(str, delays, field, name) \
  24. { \
  25. if (delays.has_##field()) \
  26. StringAppendF(&str, name "=%" PRId64 " ", delays.field()); \
  27. }
  28. // Appends descriptions of all of the set delays in |delays|, a
  29. // power_manager::PowerManagementPolicy::Delays object, to |str|, an
  30. // std::string. |prefix| should be a char* containing either "ac" or
  31. // "battery".
  32. #define APPEND_DELAYS(str, delays, prefix) \
  33. { \
  34. APPEND_DELAY(str, delays, screen_dim_ms, prefix "_screen_dim_ms"); \
  35. APPEND_DELAY(str, delays, quick_dim_ms, prefix "_quick_dim_ms"); \
  36. APPEND_DELAY(str, delays, screen_off_ms, prefix "_screen_off_ms"); \
  37. APPEND_DELAY(str, delays, screen_lock_ms, prefix "_screen_lock_ms"); \
  38. APPEND_DELAY(str, delays, quick_lock_ms, prefix "_quick_lock_ms"); \
  39. APPEND_DELAY(str, delays, idle_warning_ms, prefix "_idle_warning_ms"); \
  40. APPEND_DELAY(str, delays, idle_ms, prefix "_idle_ms"); \
  41. }
  42. // Returns the power_manager::PowerManagementPolicy_Action value
  43. // corresponding to |action|.
  44. power_manager::PowerManagementPolicy_Action GetProtoAction(
  45. PowerPolicyController::Action action) {
  46. switch (action) {
  47. case PowerPolicyController::ACTION_SUSPEND:
  48. return power_manager::PowerManagementPolicy_Action_SUSPEND;
  49. case PowerPolicyController::ACTION_STOP_SESSION:
  50. return power_manager::PowerManagementPolicy_Action_STOP_SESSION;
  51. case PowerPolicyController::ACTION_SHUT_DOWN:
  52. return power_manager::PowerManagementPolicy_Action_SHUT_DOWN;
  53. case PowerPolicyController::ACTION_DO_NOTHING:
  54. return power_manager::PowerManagementPolicy_Action_DO_NOTHING;
  55. default:
  56. NOTREACHED() << "Unhandled action " << action;
  57. return power_manager::PowerManagementPolicy_Action_DO_NOTHING;
  58. }
  59. }
  60. // Returns false if |use_audio_activity| and |use_audio_activity| prevent wake
  61. // locks created for |reason| from being honored or true otherwise.
  62. bool IsWakeLockReasonHonored(PowerPolicyController::WakeLockReason reason,
  63. bool use_audio_activity,
  64. bool use_video_activity) {
  65. if (reason == PowerPolicyController::REASON_AUDIO_PLAYBACK &&
  66. !use_audio_activity)
  67. return false;
  68. if (reason == PowerPolicyController::REASON_VIDEO_PLAYBACK &&
  69. !use_video_activity)
  70. return false;
  71. return true;
  72. }
  73. // Adjusts |delays| appropriately for backlights having been forced off by
  74. // tapping the power button. The idle delay is shortened to (idle - screen off),
  75. // and the idle warning delay (if set) is shortened to (idle warning - screen
  76. // off). All other delays are cleared, as the display should already be off.
  77. void AdjustDelaysForBacklightsForcedOff(
  78. power_manager::PowerManagementPolicy::Delays* delays) {
  79. if (delays->screen_off_ms() <= 0 || delays->idle_ms() <= 0)
  80. return;
  81. // The screen-off delay should always be shorter than or equal to the idle
  82. // delay, but we clamp the value just in case the prefs don't adhere to this.
  83. // powerd only honors delays that are greater than 0, so use 1 ms as the min.
  84. const int64_t idle_ms = std::max(delays->idle_ms() - delays->screen_off_ms(),
  85. static_cast<int64_t>(1));
  86. const int64_t warn_ms =
  87. delays->idle_warning_ms() > 0
  88. ? std::max(delays->idle_warning_ms() - delays->screen_off_ms(),
  89. static_cast<int64_t>(1))
  90. : -1;
  91. delays->Clear();
  92. delays->set_idle_ms(idle_ms);
  93. if (warn_ms > 0)
  94. delays->set_idle_warning_ms(warn_ms);
  95. }
  96. // Saves appropriate value to |week_day| and returns true if there is mapping
  97. // between week day string and enum value.
  98. bool GetWeekDayFromString(
  99. const std::string& week_day_str,
  100. power_manager::PowerManagementPolicy::WeekDay* week_day) {
  101. DCHECK(week_day);
  102. if (week_day_str == "MONDAY") {
  103. *week_day = power_manager::PowerManagementPolicy::MONDAY;
  104. } else if (week_day_str == "TUESDAY") {
  105. *week_day = power_manager::PowerManagementPolicy::TUESDAY;
  106. } else if (week_day_str == "WEDNESDAY") {
  107. *week_day = power_manager::PowerManagementPolicy::WEDNESDAY;
  108. } else if (week_day_str == "THURSDAY") {
  109. *week_day = power_manager::PowerManagementPolicy::THURSDAY;
  110. } else if (week_day_str == "FRIDAY") {
  111. *week_day = power_manager::PowerManagementPolicy::FRIDAY;
  112. } else if (week_day_str == "SATURDAY") {
  113. *week_day = power_manager::PowerManagementPolicy::SATURDAY;
  114. } else if (week_day_str == "SUNDAY") {
  115. *week_day = power_manager::PowerManagementPolicy::SUNDAY;
  116. } else {
  117. return false;
  118. }
  119. return true;
  120. }
  121. } // namespace
  122. PowerPolicyController::PrefValues::PrefValues() = default;
  123. PowerPolicyController::PrefValues::~PrefValues() = default;
  124. const int PowerPolicyController::kScreenLockAfterOffDelayMs = 10000; // 10 sec.
  125. const char PowerPolicyController::kPrefsReason[] = "Prefs";
  126. // static
  127. bool PowerPolicyController::GetPeakShiftDayConfigs(
  128. const base::Value::Dict& value,
  129. std::vector<PeakShiftDayConfig>* configs_out) {
  130. DCHECK(configs_out);
  131. configs_out->clear();
  132. const base::Value::List* entries = value.FindList({"entries"});
  133. if (!entries) {
  134. return false;
  135. }
  136. for (const base::Value& item : *entries) {
  137. const base::Value* week_day_value =
  138. item.FindKeyOfType({"day"}, base::Value::Type::STRING);
  139. const base::Value* start_time_hour =
  140. item.FindPathOfType({"start_time", "hour"}, base::Value::Type::INTEGER);
  141. const base::Value* start_time_minute = item.FindPathOfType(
  142. {"start_time", "minute"}, base::Value::Type::INTEGER);
  143. const base::Value* end_time_hour =
  144. item.FindPathOfType({"end_time", "hour"}, base::Value::Type::INTEGER);
  145. const base::Value* end_time_minute =
  146. item.FindPathOfType({"end_time", "minute"}, base::Value::Type::INTEGER);
  147. const base::Value* charge_start_time_hour = item.FindPathOfType(
  148. {"charge_start_time", "hour"}, base::Value::Type::INTEGER);
  149. const base::Value* charge_start_time_minute = item.FindPathOfType(
  150. {"charge_start_time", "minute"}, base::Value::Type::INTEGER);
  151. power_manager::PowerManagementPolicy::WeekDay week_day_enum;
  152. if (!week_day_value ||
  153. !GetWeekDayFromString(week_day_value->GetString(), &week_day_enum) ||
  154. !start_time_hour || !start_time_minute || !end_time_hour ||
  155. !end_time_minute || !charge_start_time_hour ||
  156. !charge_start_time_minute) {
  157. return false;
  158. }
  159. PeakShiftDayConfig config;
  160. config.set_day(week_day_enum);
  161. config.mutable_start_time()->set_hour(start_time_hour->GetInt());
  162. config.mutable_start_time()->set_minute(start_time_minute->GetInt());
  163. config.mutable_end_time()->set_hour(end_time_hour->GetInt());
  164. config.mutable_end_time()->set_minute(end_time_minute->GetInt());
  165. config.mutable_charge_start_time()->set_hour(
  166. charge_start_time_hour->GetInt());
  167. config.mutable_charge_start_time()->set_minute(
  168. charge_start_time_minute->GetInt());
  169. configs_out->push_back(std::move(config));
  170. }
  171. return true;
  172. }
  173. // static
  174. bool PowerPolicyController::GetAdvancedBatteryChargeModeDayConfigs(
  175. const base::Value::Dict& value,
  176. std::vector<AdvancedBatteryChargeModeDayConfig>* configs_out) {
  177. DCHECK(configs_out);
  178. configs_out->clear();
  179. const base::Value::List* entries = value.FindList({"entries"});
  180. if (!entries) {
  181. return false;
  182. }
  183. for (const base::Value& item : *entries) {
  184. const base::Value* week_day_value =
  185. item.FindKeyOfType({"day"}, base::Value::Type::STRING);
  186. const base::Value* charge_start_time_hour = item.FindPathOfType(
  187. {"charge_start_time", "hour"}, base::Value::Type::INTEGER);
  188. const base::Value* charge_start_time_minute = item.FindPathOfType(
  189. {"charge_start_time", "minute"}, base::Value::Type::INTEGER);
  190. const base::Value* charge_end_time_hour = item.FindPathOfType(
  191. {"charge_end_time", "hour"}, base::Value::Type::INTEGER);
  192. const base::Value* charge_end_time_minute = item.FindPathOfType(
  193. {"charge_end_time", "minute"}, base::Value::Type::INTEGER);
  194. power_manager::PowerManagementPolicy::WeekDay week_day_enum;
  195. if (!week_day_value ||
  196. !GetWeekDayFromString(week_day_value->GetString(), &week_day_enum) ||
  197. !charge_start_time_hour || !charge_start_time_minute ||
  198. !charge_end_time_hour || !charge_end_time_minute) {
  199. return false;
  200. }
  201. AdvancedBatteryChargeModeDayConfig config;
  202. config.set_day(week_day_enum);
  203. config.mutable_charge_start_time()->set_hour(
  204. charge_start_time_hour->GetInt());
  205. config.mutable_charge_start_time()->set_minute(
  206. charge_start_time_minute->GetInt());
  207. config.mutable_charge_end_time()->set_hour(charge_end_time_hour->GetInt());
  208. config.mutable_charge_end_time()->set_minute(
  209. charge_end_time_minute->GetInt());
  210. configs_out->push_back(std::move(config));
  211. }
  212. return true;
  213. }
  214. // static
  215. bool PowerPolicyController::GetBatteryChargeModeFromInteger(
  216. int mode,
  217. power_manager::PowerManagementPolicy::BatteryChargeMode::Mode* mode_out) {
  218. DCHECK(mode_out);
  219. switch (mode) {
  220. case 1:
  221. *mode_out =
  222. power_manager::PowerManagementPolicy::BatteryChargeMode::STANDARD;
  223. return true;
  224. case 2:
  225. *mode_out = power_manager::PowerManagementPolicy::BatteryChargeMode::
  226. EXPRESS_CHARGE;
  227. return true;
  228. case 3:
  229. *mode_out = power_manager::PowerManagementPolicy::BatteryChargeMode::
  230. PRIMARILY_AC_USE;
  231. return true;
  232. case 4:
  233. *mode_out =
  234. power_manager::PowerManagementPolicy::BatteryChargeMode::ADAPTIVE;
  235. return true;
  236. case 5:
  237. *mode_out =
  238. power_manager::PowerManagementPolicy::BatteryChargeMode::CUSTOM;
  239. return true;
  240. default:
  241. return false;
  242. }
  243. }
  244. // static
  245. std::string PowerPolicyController::GetPolicyDebugString(
  246. const power_manager::PowerManagementPolicy& policy) {
  247. std::string str;
  248. if (policy.has_ac_delays())
  249. APPEND_DELAYS(str, policy.ac_delays(), "ac");
  250. if (policy.has_battery_delays())
  251. APPEND_DELAYS(str, policy.battery_delays(), "battery");
  252. if (policy.has_ac_idle_action())
  253. StringAppendF(&str, "ac_idle=%d ", policy.ac_idle_action());
  254. if (policy.has_battery_idle_action())
  255. StringAppendF(&str, "battery_idle=%d ", policy.battery_idle_action());
  256. if (policy.has_lid_closed_action())
  257. StringAppendF(&str, "lid_closed=%d ", policy.lid_closed_action());
  258. if (policy.has_screen_wake_lock())
  259. StringAppendF(&str, "screen_wake_lock=%d ", policy.screen_wake_lock());
  260. if (policy.has_dim_wake_lock())
  261. StringAppendF(&str, "dim_wake_lock=%d ", policy.dim_wake_lock());
  262. if (policy.has_system_wake_lock())
  263. StringAppendF(&str, "system_wake_lock=%d ", policy.system_wake_lock());
  264. if (policy.has_use_audio_activity())
  265. StringAppendF(&str, "use_audio=%d ", policy.use_audio_activity());
  266. if (policy.has_use_video_activity())
  267. StringAppendF(&str, "use_video=%d ", policy.use_audio_activity());
  268. if (policy.has_ac_brightness_percent())
  269. StringAppendF(&str, "ac_brightness_percent=%f ",
  270. policy.ac_brightness_percent());
  271. if (policy.has_battery_brightness_percent()) {
  272. StringAppendF(&str, "battery_brightness_percent=%f ",
  273. policy.battery_brightness_percent());
  274. }
  275. if (policy.has_presentation_screen_dim_delay_factor()) {
  276. StringAppendF(&str, "presentation_screen_dim_delay_factor=%f ",
  277. policy.presentation_screen_dim_delay_factor());
  278. }
  279. if (policy.has_user_activity_screen_dim_delay_factor()) {
  280. StringAppendF(&str, "user_activity_screen_dim_delay_factor=%f ",
  281. policy.user_activity_screen_dim_delay_factor());
  282. }
  283. if (policy.has_wait_for_initial_user_activity()) {
  284. StringAppendF(&str, "wait_for_initial_user_activity=%d ",
  285. policy.wait_for_initial_user_activity());
  286. }
  287. if (policy.has_force_nonzero_brightness_for_user_activity()) {
  288. StringAppendF(&str, "force_nonzero_brightness_for_user_activity=%d ",
  289. policy.force_nonzero_brightness_for_user_activity());
  290. }
  291. str += GetPeakShiftPolicyDebugString(policy);
  292. str += GetAdvancedBatteryChargeModePolicyDebugString(policy);
  293. if (policy.has_battery_charge_mode()) {
  294. if (policy.battery_charge_mode().has_mode()) {
  295. StringAppendF(&str, "battery_charge_mode=%d ",
  296. policy.battery_charge_mode().mode());
  297. }
  298. if (policy.battery_charge_mode().has_custom_charge_start()) {
  299. StringAppendF(&str, "custom_charge_start=%d ",
  300. policy.battery_charge_mode().custom_charge_start());
  301. }
  302. if (policy.battery_charge_mode().has_custom_charge_stop()) {
  303. StringAppendF(&str, "custom_charge_stop=%d ",
  304. policy.battery_charge_mode().custom_charge_stop());
  305. }
  306. }
  307. if (policy.has_boot_on_ac()) {
  308. StringAppendF(&str, "boot_on_ac=%d ", policy.boot_on_ac());
  309. }
  310. if (policy.has_usb_power_share()) {
  311. StringAppendF(&str, "usb_power_share=%d ", policy.usb_power_share());
  312. }
  313. if (policy.has_send_feedback_if_undimmed()) {
  314. StringAppendF(&str, "send_feedback_if_undimmed=%d ",
  315. policy.send_feedback_if_undimmed());
  316. }
  317. if (policy.has_reason())
  318. StringAppendF(&str, "reason=\"%s\" ", policy.reason().c_str());
  319. base::TrimWhitespaceASCII(str, base::TRIM_TRAILING, &str);
  320. return str;
  321. }
  322. // static
  323. std::string PowerPolicyController::GetPeakShiftPolicyDebugString(
  324. const power_manager::PowerManagementPolicy& policy) {
  325. std::string str;
  326. if (policy.has_peak_shift_battery_percent_threshold()) {
  327. StringAppendF(&str, "peak_shift_battery_threshold=%d ",
  328. policy.peak_shift_battery_percent_threshold());
  329. }
  330. if (policy.peak_shift_day_configs_size() == 0) {
  331. return str;
  332. }
  333. std::vector<std::string> list;
  334. for (auto config : policy.peak_shift_day_configs()) {
  335. list.push_back(base::StringPrintf(
  336. "{day=%d start_time=%d:%02d end_time=%d:%02d "
  337. "charge_start_time=%d:%02d}",
  338. config.day(), config.start_time().hour(), config.start_time().minute(),
  339. config.end_time().hour(), config.end_time().minute(),
  340. config.charge_start_time().hour(),
  341. config.charge_start_time().minute()));
  342. }
  343. StringAppendF(&str, "peak_shift_day_config=[%s] ",
  344. base::JoinString(list, " ").c_str());
  345. return str;
  346. }
  347. // static
  348. std::string
  349. PowerPolicyController::GetAdvancedBatteryChargeModePolicyDebugString(
  350. const power_manager::PowerManagementPolicy& policy) {
  351. if (policy.advanced_battery_charge_mode_day_configs_size() == 0) {
  352. return "";
  353. }
  354. std::vector<std::string> list;
  355. for (auto config : policy.advanced_battery_charge_mode_day_configs()) {
  356. list.push_back(base::StringPrintf(
  357. "{day=%d charge_start_time=%d:%02d charge_end_time=%d:%02d}",
  358. config.day(), config.charge_start_time().hour(),
  359. config.charge_start_time().minute(), config.charge_end_time().hour(),
  360. config.charge_end_time().minute()));
  361. }
  362. return base::StringPrintf("advanced_battery_charge_mode_day_config=[%s] ",
  363. base::JoinString(list, " ").c_str());
  364. }
  365. // static
  366. void PowerPolicyController::Initialize(PowerManagerClient* client) {
  367. DCHECK(!IsInitialized());
  368. g_power_policy_controller = new PowerPolicyController(client);
  369. }
  370. // static
  371. bool PowerPolicyController::IsInitialized() {
  372. return g_power_policy_controller;
  373. }
  374. // static
  375. void PowerPolicyController::Shutdown() {
  376. DCHECK(IsInitialized());
  377. delete g_power_policy_controller;
  378. g_power_policy_controller = nullptr;
  379. }
  380. // static
  381. PowerPolicyController* PowerPolicyController::Get() {
  382. DCHECK(IsInitialized());
  383. return g_power_policy_controller;
  384. }
  385. void PowerPolicyController::ApplyPrefs(const PrefValues& values) {
  386. prefs_policy_.Clear();
  387. power_manager::PowerManagementPolicy::Delays* delays =
  388. prefs_policy_.mutable_ac_delays();
  389. delays->set_screen_dim_ms(values.ac_screen_dim_delay_ms);
  390. delays->set_screen_off_ms(values.ac_screen_off_delay_ms);
  391. delays->set_screen_lock_ms(values.ac_screen_lock_delay_ms);
  392. delays->set_idle_warning_ms(values.ac_idle_warning_delay_ms);
  393. delays->set_idle_ms(values.ac_idle_delay_ms);
  394. // If auto screen-locking is enabled, ensure that the screen is locked soon
  395. // after it's turned off due to user inactivity.
  396. int64_t lock_ms = delays->screen_off_ms() + kScreenLockAfterOffDelayMs;
  397. if (values.enable_auto_screen_lock && delays->screen_off_ms() > 0 &&
  398. (delays->screen_lock_ms() <= 0 || lock_ms < delays->screen_lock_ms()) &&
  399. lock_ms < delays->idle_ms()) {
  400. delays->set_screen_lock_ms(lock_ms);
  401. }
  402. delays = prefs_policy_.mutable_battery_delays();
  403. delays->set_screen_dim_ms(values.battery_screen_dim_delay_ms);
  404. delays->set_screen_off_ms(values.battery_screen_off_delay_ms);
  405. delays->set_screen_lock_ms(values.battery_screen_lock_delay_ms);
  406. delays->set_idle_warning_ms(values.battery_idle_warning_delay_ms);
  407. delays->set_idle_ms(values.battery_idle_delay_ms);
  408. // Sets quick_dim_ms and send_feedback_if_undimmed for prefs_policy_.
  409. if (values.battery_quick_dim_delay_ms >= 0) {
  410. prefs_policy_.mutable_battery_delays()->set_quick_dim_ms(
  411. values.battery_quick_dim_delay_ms);
  412. }
  413. if (values.ac_quick_dim_delay_ms >= 0) {
  414. prefs_policy_.mutable_ac_delays()->set_quick_dim_ms(
  415. values.ac_quick_dim_delay_ms);
  416. }
  417. if (values.battery_quick_lock_delay_ms >= 0) {
  418. prefs_policy_.mutable_battery_delays()->set_quick_lock_ms(
  419. values.battery_quick_lock_delay_ms);
  420. }
  421. if (values.ac_quick_lock_delay_ms >= 0) {
  422. prefs_policy_.mutable_ac_delays()->set_quick_lock_ms(
  423. values.ac_quick_lock_delay_ms);
  424. }
  425. if (values.send_feedback_if_undimmed.has_value()) {
  426. prefs_policy_.set_send_feedback_if_undimmed(
  427. values.send_feedback_if_undimmed.value());
  428. }
  429. lock_ms = delays->screen_off_ms() + kScreenLockAfterOffDelayMs;
  430. if (values.enable_auto_screen_lock && delays->screen_off_ms() > 0 &&
  431. (delays->screen_lock_ms() <= 0 || lock_ms < delays->screen_lock_ms()) &&
  432. lock_ms < delays->idle_ms()) {
  433. delays->set_screen_lock_ms(lock_ms);
  434. }
  435. auto_screen_lock_enabled_ = values.enable_auto_screen_lock;
  436. prefs_policy_.set_ac_idle_action(GetProtoAction(values.ac_idle_action));
  437. prefs_policy_.set_battery_idle_action(
  438. GetProtoAction(values.battery_idle_action));
  439. prefs_policy_.set_lid_closed_action(GetProtoAction(values.lid_closed_action));
  440. prefs_policy_.set_use_audio_activity(values.use_audio_activity);
  441. prefs_policy_.set_use_video_activity(values.use_video_activity);
  442. if (!per_session_brightness_override_) {
  443. if (values.ac_brightness_percent >= 0.0)
  444. prefs_policy_.set_ac_brightness_percent(values.ac_brightness_percent);
  445. if (values.battery_brightness_percent >= 0.0) {
  446. prefs_policy_.set_battery_brightness_percent(
  447. values.battery_brightness_percent);
  448. }
  449. }
  450. prefs_policy_.set_presentation_screen_dim_delay_factor(
  451. values.presentation_screen_dim_delay_factor);
  452. prefs_policy_.set_user_activity_screen_dim_delay_factor(
  453. values.user_activity_screen_dim_delay_factor);
  454. prefs_policy_.set_wait_for_initial_user_activity(
  455. values.wait_for_initial_user_activity);
  456. prefs_policy_.set_force_nonzero_brightness_for_user_activity(
  457. values.force_nonzero_brightness_for_user_activity);
  458. honor_wake_locks_ = values.allow_wake_locks;
  459. honor_screen_wake_locks_ =
  460. honor_wake_locks_ && values.allow_screen_wake_locks;
  461. fast_suspend_when_backlights_forced_off_ =
  462. values.fast_suspend_when_backlights_forced_off;
  463. if (values.peak_shift_enabled) {
  464. prefs_policy_.set_peak_shift_battery_percent_threshold(
  465. values.peak_shift_battery_threshold);
  466. *prefs_policy_.mutable_peak_shift_day_configs() = {
  467. values.peak_shift_day_configs.begin(),
  468. values.peak_shift_day_configs.end()};
  469. }
  470. if (values.advanced_battery_charge_mode_enabled) {
  471. *prefs_policy_.mutable_advanced_battery_charge_mode_day_configs() = {
  472. values.advanced_battery_charge_mode_day_configs.begin(),
  473. values.advanced_battery_charge_mode_day_configs.end()};
  474. }
  475. auto* battery_charge_mode = prefs_policy_.mutable_battery_charge_mode();
  476. battery_charge_mode->set_mode(values.battery_charge_mode);
  477. if (values.battery_charge_mode ==
  478. power_manager::PowerManagementPolicy::BatteryChargeMode::CUSTOM) {
  479. battery_charge_mode->set_custom_charge_start(values.custom_charge_start);
  480. battery_charge_mode->set_custom_charge_stop(values.custom_charge_stop);
  481. }
  482. prefs_policy_.set_boot_on_ac(values.boot_on_ac);
  483. prefs_policy_.set_usb_power_share(values.usb_power_share);
  484. if (values.adaptive_charging_enabled.has_value()) {
  485. prefs_policy_.set_adaptive_charging_enabled(
  486. values.adaptive_charging_enabled.value());
  487. if (values.adaptive_charging_enabled.value()) {
  488. prefs_policy_.set_adaptive_charging_min_probability(
  489. values.adaptive_charging_min_probability);
  490. prefs_policy_.set_adaptive_charging_hold_percent(
  491. values.adaptive_charging_hold_percent);
  492. }
  493. }
  494. prefs_were_set_ = true;
  495. SendCurrentPolicy();
  496. }
  497. base::TimeDelta PowerPolicyController::GetMaxPolicyAutoScreenLockDelay() {
  498. if (!prefs_were_set_ || !auto_screen_lock_enabled_) {
  499. return base::TimeDelta();
  500. }
  501. int ac_delay = prefs_policy_.ac_delays().screen_lock_ms();
  502. int battery_delay = prefs_policy_.battery_delays().screen_lock_ms();
  503. return base::Milliseconds(std::max(ac_delay, battery_delay));
  504. }
  505. int PowerPolicyController::AddScreenWakeLock(WakeLockReason reason,
  506. const std::string& description) {
  507. return AddWakeLockInternal(WakeLock::TYPE_SCREEN, reason, description);
  508. }
  509. int PowerPolicyController::AddDimWakeLock(WakeLockReason reason,
  510. const std::string& description) {
  511. return AddWakeLockInternal(WakeLock::TYPE_DIM, reason, description);
  512. }
  513. int PowerPolicyController::AddSystemWakeLock(WakeLockReason reason,
  514. const std::string& description) {
  515. return AddWakeLockInternal(WakeLock::TYPE_SYSTEM, reason, description);
  516. }
  517. void PowerPolicyController::RemoveWakeLock(int id) {
  518. if (!wake_locks_.erase(id))
  519. LOG(WARNING) << "Ignoring request to remove nonexistent wake lock " << id;
  520. else
  521. SendCurrentPolicy();
  522. }
  523. void PowerPolicyController::PowerManagerRestarted() {
  524. SendCurrentPolicy();
  525. }
  526. void PowerPolicyController::ScreenBrightnessChanged(
  527. const power_manager::BacklightBrightnessChange& change) {
  528. if (prefs_were_set_ &&
  529. (prefs_policy_.has_ac_brightness_percent() ||
  530. prefs_policy_.has_battery_brightness_percent()) &&
  531. change.cause() ==
  532. power_manager::BacklightBrightnessChange_Cause_USER_REQUEST) {
  533. per_session_brightness_override_ = true;
  534. }
  535. }
  536. void PowerPolicyController::NotifyChromeIsExiting() {
  537. if (chrome_is_exiting_)
  538. return;
  539. chrome_is_exiting_ = true;
  540. SendCurrentPolicy();
  541. }
  542. void PowerPolicyController::HandleBacklightsForcedOffForPowerButton(
  543. bool forced_off) {
  544. if (forced_off == backlights_forced_off_for_power_button_)
  545. return;
  546. backlights_forced_off_for_power_button_ = forced_off;
  547. SendCurrentPolicy();
  548. }
  549. void PowerPolicyController::SetEncryptionMigrationActive(bool active) {
  550. if (encryption_migration_active_ == active)
  551. return;
  552. encryption_migration_active_ = active;
  553. SendCurrentPolicy();
  554. }
  555. PowerPolicyController::PowerPolicyController(PowerManagerClient* client)
  556. : client_(client) {
  557. DCHECK(client_);
  558. client_->AddObserver(this);
  559. }
  560. PowerPolicyController::~PowerPolicyController() {
  561. client_->RemoveObserver(this);
  562. }
  563. PowerPolicyController::WakeLock::WakeLock(Type type,
  564. WakeLockReason reason,
  565. const std::string& description)
  566. : type(type), reason(reason), description(description) {}
  567. PowerPolicyController::WakeLock::~WakeLock() = default;
  568. int PowerPolicyController::AddWakeLockInternal(WakeLock::Type type,
  569. WakeLockReason reason,
  570. const std::string& description) {
  571. const int id = next_wake_lock_id_++;
  572. wake_locks_.insert(std::make_pair(id, WakeLock(type, reason, description)));
  573. SendCurrentPolicy();
  574. return id;
  575. }
  576. void PowerPolicyController::SendCurrentPolicy() {
  577. std::string causes;
  578. power_manager::PowerManagementPolicy policy = prefs_policy_;
  579. if (prefs_were_set_)
  580. causes = kPrefsReason;
  581. // Shorten suspend delays if the backlight is forced off via the power button.
  582. if (backlights_forced_off_for_power_button_ &&
  583. fast_suspend_when_backlights_forced_off_) {
  584. if (policy.ac_idle_action() ==
  585. power_manager::PowerManagementPolicy_Action_SUSPEND) {
  586. AdjustDelaysForBacklightsForcedOff(policy.mutable_ac_delays());
  587. }
  588. if (policy.battery_idle_action() ==
  589. power_manager::PowerManagementPolicy_Action_SUSPEND) {
  590. AdjustDelaysForBacklightsForcedOff(policy.mutable_battery_delays());
  591. }
  592. }
  593. if (honor_wake_locks_) {
  594. bool have_screen_wake_locks = false;
  595. bool have_dim_wake_locks = false;
  596. bool have_system_wake_locks = false;
  597. for (const auto& it : wake_locks_) {
  598. // Skip audio and video locks that should be ignored due to policy.
  599. if (!IsWakeLockReasonHonored(it.second.reason,
  600. policy.use_audio_activity(),
  601. policy.use_video_activity()))
  602. continue;
  603. switch (it.second.type) {
  604. case WakeLock::TYPE_SCREEN:
  605. have_screen_wake_locks = true;
  606. break;
  607. case WakeLock::TYPE_DIM:
  608. have_dim_wake_locks = true;
  609. break;
  610. case WakeLock::TYPE_SYSTEM:
  611. have_system_wake_locks = true;
  612. break;
  613. }
  614. causes += (causes.empty() ? "" : ", ") + it.second.description;
  615. }
  616. // Downgrade full-brightness and dimmed-brightness locks to system locks if
  617. // wake locks aren't allowed to keep the screen on.
  618. if (!honor_screen_wake_locks_ &&
  619. (have_screen_wake_locks || have_dim_wake_locks)) {
  620. have_system_wake_locks = true;
  621. have_screen_wake_locks = false;
  622. have_dim_wake_locks = false;
  623. }
  624. if (have_screen_wake_locks)
  625. policy.set_screen_wake_lock(true);
  626. if (have_dim_wake_locks)
  627. policy.set_dim_wake_lock(true);
  628. if (have_system_wake_locks)
  629. policy.set_system_wake_lock(true);
  630. }
  631. if (encryption_migration_active_ &&
  632. policy.lid_closed_action() !=
  633. power_manager::PowerManagementPolicy_Action_DO_NOTHING) {
  634. policy.set_lid_closed_action(
  635. power_manager::PowerManagementPolicy_Action_SUSPEND);
  636. causes +=
  637. std::string((causes.empty() ? "" : ", ")) + "encryption migration";
  638. }
  639. // To avoid a race in the case where the user asks Chrome to sign out
  640. // and then immediately closes the lid, override the lid-closed action
  641. // so the system will stay awake while Chrome is exiting. When Chrome
  642. // restarts to display the login screen, it will send an updated
  643. // policy that powerd can act on.
  644. if (chrome_is_exiting_ &&
  645. (!policy.has_lid_closed_action() ||
  646. policy.lid_closed_action() ==
  647. power_manager::PowerManagementPolicy_Action_SUSPEND ||
  648. policy.lid_closed_action() ==
  649. power_manager::PowerManagementPolicy_Action_SHUT_DOWN)) {
  650. policy.set_lid_closed_action(
  651. power_manager::PowerManagementPolicy_Action_DO_NOTHING);
  652. }
  653. if (!causes.empty())
  654. policy.set_reason(causes);
  655. client_->SetPolicy(policy);
  656. }
  657. } // namespace chromeos