Chromium Code Reviews| Index: chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc |
| diff --git a/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc b/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc |
| index fd724b204fe41856e03c9ff2c7146e73467a78d7..956eff1319c0758d28843e9210343e881b2a1891 100644 |
| --- a/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc |
| +++ b/chrome/browser/ui/webui/settings/chromeos/device_power_handler.cc |
| @@ -9,10 +9,15 @@ |
| #include "base/bind.h" |
| #include "base/bind_helpers.h" |
| +#include "base/memory/ptr_util.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/strings/utf_string_conversions.h" |
| #include "base/values.h" |
| +#include "chrome/common/pref_names.h" |
| #include "chrome/grit/generated_resources.h" |
| +#include "chromeos/dbus/dbus_thread_manager.h" |
| +#include "components/prefs/pref_change_registrar.h" |
| +#include "components/prefs/pref_service.h" |
| #include "content/public/browser/web_ui.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/l10n/time_format.h" |
| @@ -42,8 +47,41 @@ base::string16 GetBatteryTimeText(base::TimeDelta time_left) { |
| } // namespace |
| -PowerHandler::PowerHandler() |
| - : power_observer_(this) { |
| +const char PowerHandler::kPowerManagementSettingsChangedName[] = |
| + "power-management-settings-changed"; |
| +const char PowerHandler::kIdleBehaviorKey[] = "idleBehavior"; |
| +const char PowerHandler::kIdleManagedKey[] = "idleManaged"; |
| +const char PowerHandler::kLidClosedBehaviorKey[] = "lidClosedBehavior"; |
| +const char PowerHandler::kLidClosedManagedKey[] = "lidClosedManaged"; |
| +const char PowerHandler::kHasLidKey[] = "hasLid"; |
| + |
| +PowerHandler::TestAPI::TestAPI(PowerHandler* handler) : handler_(handler) {} |
| + |
| +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
|
| + |
| +void PowerHandler::TestAPI::RequestPowerManagementSettings() { |
| + base::ListValue args; |
| + handler_->HandleRequestPowerManagementSettings(&args); |
| +} |
| + |
| +void PowerHandler::TestAPI::SetIdleBehavior(IdleBehavior behavior) { |
| + base::ListValue args; |
| + args.AppendInteger(static_cast<int>(behavior)); |
| + handler_->HandleSetIdleBehavior(&args); |
| +} |
| + |
| +void PowerHandler::TestAPI::SetLidClosedBehavior( |
| + PowerPolicyController::Action behavior) { |
| + base::ListValue args; |
| + args.AppendInteger(behavior); |
| + handler_->HandleSetLidClosedBehavior(&args); |
| +} |
| + |
| +PowerHandler::PowerHandler(PrefService* prefs) |
| + : prefs_(prefs), |
| + power_status_observer_(this), |
| + power_manager_client_observer_(this), |
| + weak_ptr_factory_(this) { |
| power_status_ = ash::PowerStatus::Get(); |
| } |
| @@ -56,14 +94,49 @@ void PowerHandler::RegisterMessages() { |
| web_ui()->RegisterMessageCallback( |
| "setPowerSource", |
| base::Bind(&PowerHandler::HandleSetPowerSource, base::Unretained(this))); |
| + web_ui()->RegisterMessageCallback( |
| + "requestPowerManagementSettings", |
| + base::Bind(&PowerHandler::HandleRequestPowerManagementSettings, |
| + base::Unretained(this))); |
| + web_ui()->RegisterMessageCallback( |
| + "setLidClosedBehavior", |
| + base::Bind(&PowerHandler::HandleSetLidClosedBehavior, |
| + base::Unretained(this))); |
| + web_ui()->RegisterMessageCallback( |
| + "setIdleBehavior", |
| + base::Bind(&PowerHandler::HandleSetIdleBehavior, base::Unretained(this))); |
| } |
| void PowerHandler::OnJavascriptAllowed() { |
| - power_observer_.Add(power_status_); |
| + power_status_observer_.Add(power_status_); |
| + |
| + PowerManagerClient* power_manager_client = |
| + DBusThreadManager::Get()->GetPowerManagerClient(); |
| + power_manager_client_observer_.Add(power_manager_client); |
| + power_manager_client->GetSwitchStates(base::Bind( |
| + &PowerHandler::OnGotSwitchStates, weak_ptr_factory_.GetWeakPtr())); |
| + |
| + // 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.
|
| + // incorporated into the UI. |
| + base::Closure callback(base::Bind(&PowerHandler::SendPowerManagementSettings, |
| + base::Unretained(this), false /* force */)); |
| + pref_change_registrar_ = base::MakeUnique<PrefChangeRegistrar>(); |
| + pref_change_registrar_->Init(prefs_); |
| + pref_change_registrar_->Add(prefs::kPowerAcIdleAction, callback); |
| + pref_change_registrar_->Add(prefs::kPowerAcScreenDimDelayMs, callback); |
| + pref_change_registrar_->Add(prefs::kPowerAcScreenOffDelayMs, callback); |
| + pref_change_registrar_->Add(prefs::kPowerAcScreenLockDelayMs, callback); |
| + pref_change_registrar_->Add(prefs::kPowerBatteryIdleAction, callback); |
| + pref_change_registrar_->Add(prefs::kPowerBatteryScreenDimDelayMs, callback); |
| + pref_change_registrar_->Add(prefs::kPowerBatteryScreenOffDelayMs, callback); |
| + pref_change_registrar_->Add(prefs::kPowerBatteryScreenLockDelayMs, callback); |
| + pref_change_registrar_->Add(prefs::kPowerLidClosedAction, callback); |
| } |
| void PowerHandler::OnJavascriptDisallowed() { |
| - power_observer_.RemoveAll(); |
| + power_status_observer_.RemoveAll(); |
| + power_manager_client_observer_.RemoveAll(); |
| + pref_change_registrar_.reset(); |
| } |
| void PowerHandler::OnPowerStatusChanged() { |
| @@ -71,6 +144,17 @@ void PowerHandler::OnPowerStatusChanged() { |
| SendPowerSources(); |
| } |
| +void PowerHandler::PowerManagerRestarted() { |
| + DBusThreadManager::Get()->GetPowerManagerClient()->GetSwitchStates(base::Bind( |
| + &PowerHandler::OnGotSwitchStates, weak_ptr_factory_.GetWeakPtr())); |
| +} |
| + |
| +void PowerHandler::LidEventReceived(PowerManagerClient::LidState state, |
| + const base::TimeTicks& timestamp) { |
| + lid_state_ = state; |
| + SendPowerManagementSettings(false /* force */); |
| +} |
| + |
| void PowerHandler::HandleUpdatePowerStatus(const base::ListValue* args) { |
| AllowJavascript(); |
| power_status_->RequestStatusUpdate(); |
| @@ -84,6 +168,75 @@ void PowerHandler::HandleSetPowerSource(const base::ListValue* args) { |
| power_status_->SetPowerSource(id); |
| } |
| +void PowerHandler::HandleRequestPowerManagementSettings( |
| + const base::ListValue* args) { |
| + AllowJavascript(); |
| + SendPowerManagementSettings(true /* force */); |
| +} |
| + |
| +void PowerHandler::HandleSetIdleBehavior(const base::ListValue* args) { |
| + AllowJavascript(); |
| + |
| + int value = 0; |
| + CHECK(args->GetInteger(0, &value)); |
| + switch (static_cast<IdleBehavior>(value)) { |
| + 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.
|
| + 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
|
| + prefs_->ClearPref(prefs::kPowerAcScreenDimDelayMs); |
| + prefs_->ClearPref(prefs::kPowerAcScreenOffDelayMs); |
| + prefs_->ClearPref(prefs::kPowerAcScreenLockDelayMs); |
| + prefs_->ClearPref(prefs::kPowerBatteryIdleAction); |
| + prefs_->ClearPref(prefs::kPowerBatteryScreenDimDelayMs); |
| + prefs_->ClearPref(prefs::kPowerBatteryScreenOffDelayMs); |
| + prefs_->ClearPref(prefs::kPowerBatteryScreenLockDelayMs); |
| + break; |
| + case IdleBehavior::DISPLAY_OFF_STAY_AWAKE: |
| + prefs_->SetInteger(prefs::kPowerAcIdleAction, |
| + PowerPolicyController::ACTION_DO_NOTHING); |
| + prefs_->ClearPref(prefs::kPowerAcScreenDimDelayMs); |
| + prefs_->ClearPref(prefs::kPowerAcScreenOffDelayMs); |
| + prefs_->ClearPref(prefs::kPowerAcScreenLockDelayMs); |
| + prefs_->SetInteger(prefs::kPowerBatteryIdleAction, |
| + PowerPolicyController::ACTION_DO_NOTHING); |
| + prefs_->ClearPref(prefs::kPowerBatteryScreenDimDelayMs); |
| + prefs_->ClearPref(prefs::kPowerBatteryScreenOffDelayMs); |
| + prefs_->ClearPref(prefs::kPowerBatteryScreenLockDelayMs); |
| + break; |
| + case IdleBehavior::DISPLAY_ON: |
| + prefs_->SetInteger(prefs::kPowerAcIdleAction, |
| + PowerPolicyController::ACTION_DO_NOTHING); |
| + 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
|
| + prefs_->SetInteger(prefs::kPowerAcScreenOffDelayMs, 0); |
| + prefs_->SetInteger(prefs::kPowerAcScreenLockDelayMs, 0); |
| + prefs_->SetInteger(prefs::kPowerBatteryIdleAction, |
| + PowerPolicyController::ACTION_DO_NOTHING); |
| + prefs_->SetInteger(prefs::kPowerBatteryScreenDimDelayMs, 0); |
| + prefs_->SetInteger(prefs::kPowerBatteryScreenOffDelayMs, 0); |
| + prefs_->SetInteger(prefs::kPowerBatteryScreenLockDelayMs, 0); |
| + break; |
| + default: |
| + NOTREACHED() << "Invalid idle behavior " << value; |
| + } |
| +} |
| + |
| +void PowerHandler::HandleSetLidClosedBehavior(const base::ListValue* args) { |
| + AllowJavascript(); |
| + |
| + int value = 0; |
| + CHECK(args->GetInteger(0, &value)); |
| + switch (static_cast<PowerPolicyController::Action>(value)) { |
| + case PowerPolicyController::ACTION_SUSPEND: |
| + prefs_->ClearPref(prefs::kPowerLidClosedAction); |
| + break; |
| + case PowerPolicyController::ACTION_DO_NOTHING: |
| + prefs_->SetInteger(prefs::kPowerLidClosedAction, |
| + PowerPolicyController::ACTION_DO_NOTHING); |
| + break; |
| + default: |
| + NOTREACHED() << "Unsupported lid-closed behavior " << value; |
| + } |
| +} |
| + |
| void PowerHandler::SendBatteryStatus() { |
| bool charging = power_status_->IsBatteryCharging(); |
| bool calculating = power_status_->IsBatteryTimeBeingCalculated(); |
| @@ -133,5 +286,71 @@ void PowerHandler::SendPowerSources() { |
| base::Value(power_status_->IsUsbChargerConnected())); |
| } |
| +void PowerHandler::SendPowerManagementSettings(bool force) { |
| + // Infer the idle behavior based on the idle action (determining whether we'll |
| + // sleep eventually or not) and the AC screen-off delay. Policy can request |
| + // more-nuanced combinations of AC/battery actions and delays, but we wouldn't |
| + // be able to display something meaningful in the UI in those cases anyway. |
| + const PowerPolicyController::Action idle_action = |
| + static_cast<PowerPolicyController::Action>( |
| + prefs_->GetInteger(prefs::kPowerAcIdleAction)); |
| + IdleBehavior idle_behavior = IdleBehavior::OTHER; |
| + if (idle_action == PowerPolicyController::ACTION_SUSPEND) { |
| + idle_behavior = IdleBehavior::DISPLAY_OFF_SLEEP; |
| + } else if (idle_action == PowerPolicyController::ACTION_DO_NOTHING) { |
| + idle_behavior = (prefs_->GetInteger(prefs::kPowerAcScreenOffDelayMs) > 0 |
| + ? IdleBehavior::DISPLAY_OFF_STAY_AWAKE |
| + : IdleBehavior::DISPLAY_ON); |
| + } |
| + |
| + const bool idle_managed = |
| + prefs_->IsManagedPreference(prefs::kPowerAcIdleAction) || |
| + prefs_->IsManagedPreference(prefs::kPowerAcScreenDimDelayMs) || |
| + prefs_->IsManagedPreference(prefs::kPowerAcScreenOffDelayMs) || |
| + prefs_->IsManagedPreference(prefs::kPowerAcScreenLockDelayMs) || |
| + prefs_->IsManagedPreference(prefs::kPowerBatteryIdleAction) || |
| + prefs_->IsManagedPreference(prefs::kPowerBatteryScreenDimDelayMs) || |
| + prefs_->IsManagedPreference(prefs::kPowerBatteryScreenOffDelayMs) || |
| + prefs_->IsManagedPreference(prefs::kPowerBatteryScreenLockDelayMs); |
| + |
| + const PowerPolicyController::Action lid_closed_behavior = |
| + static_cast<PowerPolicyController::Action>( |
| + prefs_->GetInteger(prefs::kPowerLidClosedAction)); |
| + const bool lid_closed_managed = |
| + prefs_->IsManagedPreference(prefs::kPowerLidClosedAction); |
| + const bool has_lid = lid_state_ != PowerManagerClient::LidState::NOT_PRESENT; |
| + |
| + // Don't notify the UI if nothing changed. |
| + if (!force && idle_behavior == last_idle_behavior_ && |
| + idle_managed == last_idle_managed_ && |
| + lid_closed_behavior == last_lid_closed_behavior_ && |
| + lid_closed_managed == last_lid_closed_managed_ && |
| + has_lid == last_has_lid_) |
| + return; |
| + |
| + base::DictionaryValue dict; |
| + dict.SetInteger(kIdleBehaviorKey, static_cast<int>(idle_behavior)); |
| + dict.SetBoolean(kIdleManagedKey, idle_managed); |
| + dict.SetInteger(kLidClosedBehaviorKey, lid_closed_behavior); |
| + dict.SetBoolean(kLidClosedManagedKey, lid_closed_managed); |
| + dict.SetBoolean(kHasLidKey, has_lid); |
| + CallJavascriptFunction("cr.webUIListenerCallback", |
| + base::Value(kPowerManagementSettingsChangedName), |
| + dict); |
| + |
| + last_idle_behavior_ = idle_behavior; |
| + last_idle_managed_ = idle_managed; |
| + last_lid_closed_behavior_ = lid_closed_behavior; |
| + last_lid_closed_managed_ = lid_closed_managed; |
| + last_has_lid_ = has_lid; |
| +} |
| + |
| +void PowerHandler::OnGotSwitchStates( |
| + PowerManagerClient::LidState lid_state, |
| + PowerManagerClient::TabletMode tablet_mode) { |
| + lid_state_ = lid_state; |
| + SendPowerManagementSettings(false /* force */); |
| +} |
| + |
| } // namespace settings |
| } // namespace chromeos |