Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(374)

Side by Side Diff: chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc

Issue 2853113004: chromeos: Add settings to control power management prefs. (Closed)
Patch Set: add c++ and js tests Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h" 5 #include "chrome/browser/ui/webui/settings/chromeos/device_power_handler.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/memory/ptr_util.h"
12 #include "base/strings/string_number_conversions.h" 13 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
14 #include "base/values.h" 15 #include "base/values.h"
16 #include "chrome/common/pref_names.h"
15 #include "chrome/grit/generated_resources.h" 17 #include "chrome/grit/generated_resources.h"
18 #include "chromeos/dbus/dbus_thread_manager.h"
19 #include "components/prefs/pref_change_registrar.h"
20 #include "components/prefs/pref_service.h"
16 #include "content/public/browser/web_ui.h" 21 #include "content/public/browser/web_ui.h"
17 #include "ui/base/l10n/l10n_util.h" 22 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/l10n/time_format.h" 23 #include "ui/base/l10n/time_format.h"
19 #include "ui/base/webui/web_ui_util.h" 24 #include "ui/base/webui/web_ui_util.h"
20 25
21 namespace chromeos { 26 namespace chromeos {
22 namespace settings { 27 namespace settings {
23 namespace { 28 namespace {
24 29
25 base::string16 GetBatteryTimeText(base::TimeDelta time_left) { 30 base::string16 GetBatteryTimeText(base::TimeDelta time_left) {
26 int hour = 0; 31 int hour = 0;
27 int min = 0; 32 int min = 0;
28 ash::PowerStatus::SplitTimeIntoHoursAndMinutes(time_left, &hour, &min); 33 ash::PowerStatus::SplitTimeIntoHoursAndMinutes(time_left, &hour, &min);
29 34
30 base::string16 time_text; 35 base::string16 time_text;
31 if (hour == 0 || min == 0) { 36 if (hour == 0 || min == 0) {
32 // Display only one unit ("2 hours" or "10 minutes"). 37 // Display only one unit ("2 hours" or "10 minutes").
33 return ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION, 38 return ui::TimeFormat::Simple(ui::TimeFormat::FORMAT_DURATION,
34 ui::TimeFormat::LENGTH_LONG, time_left); 39 ui::TimeFormat::LENGTH_LONG, time_left);
35 } 40 }
36 41
37 return ui::TimeFormat::Detailed(ui::TimeFormat::FORMAT_DURATION, 42 return ui::TimeFormat::Detailed(ui::TimeFormat::FORMAT_DURATION,
38 ui::TimeFormat::LENGTH_LONG, 43 ui::TimeFormat::LENGTH_LONG,
39 -1, // force hour and minute output 44 -1, // force hour and minute output
40 time_left); 45 time_left);
41 } 46 }
42 47
43 } // namespace 48 } // namespace
44 49
45 PowerHandler::PowerHandler() 50 const char PowerHandler::kPowerManagementSettingsChangedName[] =
46 : power_observer_(this) { 51 "power-management-settings-changed";
52 const char PowerHandler::kIdleBehaviorKey[] = "idleBehavior";
53 const char PowerHandler::kIdleManagedKey[] = "idleManaged";
54 const char PowerHandler::kLidClosedBehaviorKey[] = "lidClosedBehavior";
55 const char PowerHandler::kLidClosedManagedKey[] = "lidClosedManaged";
56 const char PowerHandler::kHasLidKey[] = "hasLid";
57
58 PowerHandler::TestAPI::TestAPI(PowerHandler* handler) : handler_(handler) {}
59
60 PowerHandler::TestAPI::~TestAPI() = default;
michaelpg 2017/06/16 01:35:00 just for my benefit: what's the advantage of a def
Daniel Erat 2017/06/16 02:34:24 i'm not sure that there's a real advantage, or tha
61
62 void PowerHandler::TestAPI::RequestPowerManagementSettings() {
63 base::ListValue args;
64 handler_->HandleRequestPowerManagementSettings(&args);
65 }
66
67 void PowerHandler::TestAPI::SetIdleBehavior(IdleBehavior behavior) {
68 base::ListValue args;
69 args.AppendInteger(static_cast<int>(behavior));
70 handler_->HandleSetIdleBehavior(&args);
71 }
72
73 void PowerHandler::TestAPI::SetLidClosedBehavior(
74 PowerPolicyController::Action behavior) {
75 base::ListValue args;
76 args.AppendInteger(behavior);
77 handler_->HandleSetLidClosedBehavior(&args);
78 }
79
80 PowerHandler::PowerHandler(PrefService* prefs)
81 : prefs_(prefs),
82 power_status_observer_(this),
83 power_manager_client_observer_(this),
84 weak_ptr_factory_(this) {
47 power_status_ = ash::PowerStatus::Get(); 85 power_status_ = ash::PowerStatus::Get();
48 } 86 }
49 87
50 PowerHandler::~PowerHandler() {} 88 PowerHandler::~PowerHandler() {}
51 89
52 void PowerHandler::RegisterMessages() { 90 void PowerHandler::RegisterMessages() {
53 web_ui()->RegisterMessageCallback( 91 web_ui()->RegisterMessageCallback(
54 "updatePowerStatus", base::Bind(&PowerHandler::HandleUpdatePowerStatus, 92 "updatePowerStatus", base::Bind(&PowerHandler::HandleUpdatePowerStatus,
55 base::Unretained(this))); 93 base::Unretained(this)));
56 web_ui()->RegisterMessageCallback( 94 web_ui()->RegisterMessageCallback(
57 "setPowerSource", 95 "setPowerSource",
58 base::Bind(&PowerHandler::HandleSetPowerSource, base::Unretained(this))); 96 base::Bind(&PowerHandler::HandleSetPowerSource, base::Unretained(this)));
97 web_ui()->RegisterMessageCallback(
98 "requestPowerManagementSettings",
99 base::Bind(&PowerHandler::HandleRequestPowerManagementSettings,
100 base::Unretained(this)));
101 web_ui()->RegisterMessageCallback(
102 "setLidClosedBehavior",
103 base::Bind(&PowerHandler::HandleSetLidClosedBehavior,
104 base::Unretained(this)));
105 web_ui()->RegisterMessageCallback(
106 "setIdleBehavior",
107 base::Bind(&PowerHandler::HandleSetIdleBehavior, base::Unretained(this)));
59 } 108 }
60 109
61 void PowerHandler::OnJavascriptAllowed() { 110 void PowerHandler::OnJavascriptAllowed() {
62 power_observer_.Add(power_status_); 111 power_status_observer_.Add(power_status_);
112
113 PowerManagerClient* power_manager_client =
114 DBusThreadManager::Get()->GetPowerManagerClient();
115 power_manager_client_observer_.Add(power_manager_client);
116 power_manager_client->GetSwitchStates(base::Bind(
117 &PowerHandler::OnGotSwitchStates, weak_ptr_factory_.GetWeakPtr()));
118
119 // Register to be notified about changes to power management prefs that are
michaelpg 2017/06/16 01:35:00 optional nit: less wordy: "Observe power managemen
Daniel Erat 2017/06/16 02:34:24 Done.
120 // incorporated into the UI.
121 base::Closure callback(base::Bind(&PowerHandler::SendPowerManagementSettings,
122 base::Unretained(this), false /* force */));
123 pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>();
124 pref_change_registrar_->Init(prefs_);
125 pref_change_registrar_->Add(prefs::kPowerAcIdleAction, callback);
126 pref_change_registrar_->Add(prefs::kPowerAcScreenDimDelayMs, callback);
127 pref_change_registrar_->Add(prefs::kPowerAcScreenOffDelayMs, callback);
128 pref_change_registrar_->Add(prefs::kPowerAcScreenLockDelayMs, callback);
129 pref_change_registrar_->Add(prefs::kPowerBatteryIdleAction, callback);
130 pref_change_registrar_->Add(prefs::kPowerBatteryScreenDimDelayMs, callback);
131 pref_change_registrar_->Add(prefs::kPowerBatteryScreenOffDelayMs, callback);
132 pref_change_registrar_->Add(prefs::kPowerBatteryScreenLockDelayMs, callback);
133 pref_change_registrar_->Add(prefs::kPowerLidClosedAction, callback);
63 } 134 }
64 135
65 void PowerHandler::OnJavascriptDisallowed() { 136 void PowerHandler::OnJavascriptDisallowed() {
66 power_observer_.RemoveAll(); 137 power_status_observer_.RemoveAll();
138 power_manager_client_observer_.RemoveAll();
139 pref_change_registrar_.reset();
67 } 140 }
68 141
69 void PowerHandler::OnPowerStatusChanged() { 142 void PowerHandler::OnPowerStatusChanged() {
70 SendBatteryStatus(); 143 SendBatteryStatus();
71 SendPowerSources(); 144 SendPowerSources();
72 } 145 }
73 146
147 void PowerHandler::PowerManagerRestarted() {
148 DBusThreadManager::Get()->GetPowerManagerClient()->GetSwitchStates(base::Bind(
149 &PowerHandler::OnGotSwitchStates, weak_ptr_factory_.GetWeakPtr()));
150 }
151
152 void PowerHandler::LidEventReceived(PowerManagerClient::LidState state,
153 const base::TimeTicks& timestamp) {
154 lid_state_ = state;
155 SendPowerManagementSettings(false /* force */);
156 }
157
74 void PowerHandler::HandleUpdatePowerStatus(const base::ListValue* args) { 158 void PowerHandler::HandleUpdatePowerStatus(const base::ListValue* args) {
75 AllowJavascript(); 159 AllowJavascript();
76 power_status_->RequestStatusUpdate(); 160 power_status_->RequestStatusUpdate();
77 } 161 }
78 162
79 void PowerHandler::HandleSetPowerSource(const base::ListValue* args) { 163 void PowerHandler::HandleSetPowerSource(const base::ListValue* args) {
80 AllowJavascript(); 164 AllowJavascript();
81 165
82 std::string id; 166 std::string id;
83 CHECK(args->GetString(0, &id)); 167 CHECK(args->GetString(0, &id));
84 power_status_->SetPowerSource(id); 168 power_status_->SetPowerSource(id);
85 } 169 }
86 170
171 void PowerHandler::HandleRequestPowerManagementSettings(
172 const base::ListValue* args) {
173 AllowJavascript();
174 SendPowerManagementSettings(true /* force */);
175 }
176
177 void PowerHandler::HandleSetIdleBehavior(const base::ListValue* args) {
178 AllowJavascript();
179
180 int value = 0;
181 CHECK(args->GetInteger(0, &value));
182 switch (static_cast<IdleBehavior>(value)) {
183 case IdleBehavior::DISPLAY_OFF_SLEEP:
michaelpg 2017/06/16 01:35:00 could you add a brief comment about each of these
Daniel Erat 2017/06/16 02:34:24 Done.
184 prefs_->ClearPref(prefs::kPowerAcIdleAction);
michaelpg 2017/06/16 01:35:00 I'm not sure clearing the pref is the right move.
Daniel Erat 2017/06/16 02:34:24 hmm, i'd like to keep the possibility of changing
michaelpg 2017/06/19 22:38:06 A meta-pref would let us tweak the default delay w
185 prefs_->ClearPref(prefs::kPowerAcScreenDimDelayMs);
186 prefs_->ClearPref(prefs::kPowerAcScreenOffDelayMs);
187 prefs_->ClearPref(prefs::kPowerAcScreenLockDelayMs);
188 prefs_->ClearPref(prefs::kPowerBatteryIdleAction);
189 prefs_->ClearPref(prefs::kPowerBatteryScreenDimDelayMs);
190 prefs_->ClearPref(prefs::kPowerBatteryScreenOffDelayMs);
191 prefs_->ClearPref(prefs::kPowerBatteryScreenLockDelayMs);
192 break;
193 case IdleBehavior::DISPLAY_OFF_STAY_AWAKE:
194 prefs_->SetInteger(prefs::kPowerAcIdleAction,
195 PowerPolicyController::ACTION_DO_NOTHING);
196 prefs_->ClearPref(prefs::kPowerAcScreenDimDelayMs);
197 prefs_->ClearPref(prefs::kPowerAcScreenOffDelayMs);
198 prefs_->ClearPref(prefs::kPowerAcScreenLockDelayMs);
199 prefs_->SetInteger(prefs::kPowerBatteryIdleAction,
200 PowerPolicyController::ACTION_DO_NOTHING);
201 prefs_->ClearPref(prefs::kPowerBatteryScreenDimDelayMs);
202 prefs_->ClearPref(prefs::kPowerBatteryScreenOffDelayMs);
203 prefs_->ClearPref(prefs::kPowerBatteryScreenLockDelayMs);
204 break;
205 case IdleBehavior::DISPLAY_ON:
206 prefs_->SetInteger(prefs::kPowerAcIdleAction,
207 PowerPolicyController::ACTION_DO_NOTHING);
208 prefs_->SetInteger(prefs::kPowerAcScreenDimDelayMs, 0);
michaelpg 2017/06/16 01:35:00 does 0 mean infinite (never dim, etc)?
Daniel Erat 2017/06/16 02:34:24 yes, 0 disables the delays. they're documented at
209 prefs_->SetInteger(prefs::kPowerAcScreenOffDelayMs, 0);
210 prefs_->SetInteger(prefs::kPowerAcScreenLockDelayMs, 0);
211 prefs_->SetInteger(prefs::kPowerBatteryIdleAction,
212 PowerPolicyController::ACTION_DO_NOTHING);
213 prefs_->SetInteger(prefs::kPowerBatteryScreenDimDelayMs, 0);
214 prefs_->SetInteger(prefs::kPowerBatteryScreenOffDelayMs, 0);
215 prefs_->SetInteger(prefs::kPowerBatteryScreenLockDelayMs, 0);
216 break;
217 default:
218 NOTREACHED() << "Invalid idle behavior " << value;
219 }
220 }
221
222 void PowerHandler::HandleSetLidClosedBehavior(const base::ListValue* args) {
223 AllowJavascript();
224
225 int value = 0;
226 CHECK(args->GetInteger(0, &value));
227 switch (static_cast<PowerPolicyController::Action>(value)) {
228 case PowerPolicyController::ACTION_SUSPEND:
229 prefs_->ClearPref(prefs::kPowerLidClosedAction);
230 break;
231 case PowerPolicyController::ACTION_DO_NOTHING:
232 prefs_->SetInteger(prefs::kPowerLidClosedAction,
233 PowerPolicyController::ACTION_DO_NOTHING);
234 break;
235 default:
236 NOTREACHED() << "Unsupported lid-closed behavior " << value;
237 }
238 }
239
87 void PowerHandler::SendBatteryStatus() { 240 void PowerHandler::SendBatteryStatus() {
88 bool charging = power_status_->IsBatteryCharging(); 241 bool charging = power_status_->IsBatteryCharging();
89 bool calculating = power_status_->IsBatteryTimeBeingCalculated(); 242 bool calculating = power_status_->IsBatteryTimeBeingCalculated();
90 int percent = power_status_->GetRoundedBatteryPercent(); 243 int percent = power_status_->GetRoundedBatteryPercent();
91 base::TimeDelta time_left; 244 base::TimeDelta time_left;
92 bool show_time = false; 245 bool show_time = false;
93 246
94 if (!calculating) { 247 if (!calculating) {
95 time_left = charging ? power_status_->GetBatteryTimeToFull() 248 time_left = charging ? power_status_->GetBatteryTimeToFull()
96 : power_status_->GetBatteryTimeToEmpty(); 249 : power_status_->GetBatteryTimeToEmpty();
(...skipping 29 matching lines...) Expand all
126 dict->SetString("description", 279 dict->SetString("description",
127 l10n_util::GetStringUTF16(source.description_id)); 280 l10n_util::GetStringUTF16(source.description_id));
128 sources_list.Append(std::move(dict)); 281 sources_list.Append(std::move(dict));
129 } 282 }
130 283
131 FireWebUIListener("power-sources-changed", sources_list, 284 FireWebUIListener("power-sources-changed", sources_list,
132 base::Value(power_status_->GetCurrentPowerSourceID()), 285 base::Value(power_status_->GetCurrentPowerSourceID()),
133 base::Value(power_status_->IsUsbChargerConnected())); 286 base::Value(power_status_->IsUsbChargerConnected()));
134 } 287 }
135 288
289 void PowerHandler::SendPowerManagementSettings(bool force) {
290 // Infer the idle behavior based on the idle action (determining whether we'll
291 // sleep eventually or not) and the AC screen-off delay. Policy can request
292 // more-nuanced combinations of AC/battery actions and delays, but we wouldn't
293 // be able to display something meaningful in the UI in those cases anyway.
294 const PowerPolicyController::Action idle_action =
295 static_cast<PowerPolicyController::Action>(
296 prefs_->GetInteger(prefs::kPowerAcIdleAction));
297 IdleBehavior idle_behavior = IdleBehavior::OTHER;
298 if (idle_action == PowerPolicyController::ACTION_SUSPEND) {
299 idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP;
300 } else if (idle_action == PowerPolicyController::ACTION_DO_NOTHING) {
301 idle_behavior = (prefs_->GetInteger(prefs::kPowerAcScreenOffDelayMs) > 0
302 ? IdleBehavior::DISPLAY_OFF_STAY_AWAKE
303 : IdleBehavior::DISPLAY_ON);
304 }
305
306 const bool idle_managed =
307 prefs_->IsManagedPreference(prefs::kPowerAcIdleAction) ||
308 prefs_->IsManagedPreference(prefs::kPowerAcScreenDimDelayMs) ||
309 prefs_->IsManagedPreference(prefs::kPowerAcScreenOffDelayMs) ||
310 prefs_->IsManagedPreference(prefs::kPowerAcScreenLockDelayMs) ||
311 prefs_->IsManagedPreference(prefs::kPowerBatteryIdleAction) ||
312 prefs_->IsManagedPreference(prefs::kPowerBatteryScreenDimDelayMs) ||
313 prefs_->IsManagedPreference(prefs::kPowerBatteryScreenOffDelayMs) ||
314 prefs_->IsManagedPreference(prefs::kPowerBatteryScreenLockDelayMs);
315
316 const PowerPolicyController::Action lid_closed_behavior =
317 static_cast<PowerPolicyController::Action>(
318 prefs_->GetInteger(prefs::kPowerLidClosedAction));
319 const bool lid_closed_managed =
320 prefs_->IsManagedPreference(prefs::kPowerLidClosedAction);
321 const bool has_lid = lid_state_ != PowerManagerClient::LidState::NOT_PRESENT;
322
323 // Don't notify the UI if nothing changed.
324 if (!force && idle_behavior == last_idle_behavior_ &&
325 idle_managed == last_idle_managed_ &&
326 lid_closed_behavior == last_lid_closed_behavior_ &&
327 lid_closed_managed == last_lid_closed_managed_ &&
328 has_lid == last_has_lid_)
329 return;
330
331 base::DictionaryValue dict;
332 dict.SetInteger(kIdleBehaviorKey, static_cast<int>(idle_behavior));
333 dict.SetBoolean(kIdleManagedKey, idle_managed);
334 dict.SetInteger(kLidClosedBehaviorKey, lid_closed_behavior);
335 dict.SetBoolean(kLidClosedManagedKey, lid_closed_managed);
336 dict.SetBoolean(kHasLidKey, has_lid);
337 CallJavascriptFunction("cr.webUIListenerCallback",
338 base::Value(kPowerManagementSettingsChangedName),
339 dict);
340
341 last_idle_behavior_ = idle_behavior;
342 last_idle_managed_ = idle_managed;
343 last_lid_closed_behavior_ = lid_closed_behavior;
344 last_lid_closed_managed_ = lid_closed_managed;
345 last_has_lid_ = has_lid;
346 }
347
348 void PowerHandler::OnGotSwitchStates(
349 PowerManagerClient::LidState lid_state,
350 PowerManagerClient::TabletMode tablet_mode) {
351 lid_state_ = lid_state;
352 SendPowerManagementSettings(false /* force */);
353 }
354
136 } // namespace settings 355 } // namespace settings
137 } // namespace chromeos 356 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698