Chromium Code Reviews| 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 |