OLD | NEW |
---|---|
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 Loading... | |
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 |
OLD | NEW |