Chromium Code Reviews| Index: chromeos/dbus/power_policy_controller.cc |
| diff --git a/chromeos/dbus/power_policy_controller.cc b/chromeos/dbus/power_policy_controller.cc |
| index ef59b81bdb754c3d095251b9608e647fbc1d71d6..862dd9ca8d9a3a6c42b929b806e061d1a9b27aab 100644 |
| --- a/chromeos/dbus/power_policy_controller.cc |
| +++ b/chromeos/dbus/power_policy_controller.cc |
| @@ -14,35 +14,42 @@ namespace { |
| // If |pref|, a PrefService::Preference containing an integer, has been |
| // explicitly set to 0 or a positive value, assigns it to |proto_field|, a |
| -// int32 field in |proto|, a google::protobuf::MessageLite*. |
| -#define SET_DELAY_FROM_PREF(pref, proto_field, proto) \ |
| +// int32 field in |proto|, a google::protobuf::MessageLite*. If |proto| |
| +// was updated, |got_prefs| is set to true; otherwise it is left unchanged. |
| +#define SET_DELAY_FROM_PREF(pref, proto_field, proto, got_prefs) \ |
|
bartfab (slow)
2013/03/21 14:22:26
Optional nit: When you see the calls to these macr
Daniel Erat
2013/03/21 14:48:46
Makes sense; done. (I had considered this but inc
bartfab (slow)
2013/03/21 15:34:38
The |proto| should also be made a pointer then, ju
Daniel Erat
2013/03/21 15:42:30
I'm confused; maybe I'm misunderstanding the reque
bartfab (slow)
2013/03/21 16:27:34
Nevermind. I thought that in UpdatePolicyFromPrefs
|
| { \ |
| int value = GetIntPrefValue(pref); \ |
| - if (value >= 0) \ |
| + if (value >= 0) { \ |
| (proto)->set_##proto_field(value); \ |
| + got_prefs = true; \ |
| + } \ |
| } |
| // Similar to SET_DELAY_FROM_PREF() but sets a |
| // power_manager::PowerManagementPolicy_Action field instead. |
| -#define SET_ACTION_FROM_PREF(pref, proto_field, proto) \ |
| +#define SET_ACTION_FROM_PREF(pref, proto_field, proto, got_prefs) \ |
| { \ |
| int value = GetIntPrefValue(pref); \ |
| if (value >= 0) { \ |
| (proto)->set_##proto_field( \ |
| static_cast<power_manager::PowerManagementPolicy_Action>(value)); \ |
| + got_prefs = true; \ |
| } \ |
| } |
| -// If |pref|, a PrefService::Preference containing a bool, has been |
| -// set, assigns it to |proto_field|, a bool field in |proto|, a |
| -// google::protobuf::MessageLite*. |
| -#define SET_BOOL_FROM_PREF(pref, proto_field, proto) \ |
| +// If |pref|, a PrefService::Preference containing a bool, has been set, |
| +// assigns it to |proto_field|, a bool field in |proto|, a |
| +// google::protobuf::MessageLite*. If |proto| was updated, |got_prefs| is |
| +// set to true; otherwise it is left unchanged. |
| +#define SET_BOOL_FROM_PREF(pref, proto_field, proto, got_prefs) \ |
| if (!pref.IsDefaultValue()) { \ |
| bool value = false; \ |
| - if (pref.GetValue()->GetAsBoolean(&value)) \ |
| + if (pref.GetValue()->GetAsBoolean(&value)) { \ |
| (proto)->set_##proto_field(value); \ |
| - else \ |
| + got_prefs = true; \ |
| + } else { \ |
| LOG(DFATAL) << pref.name() << " pref has non-boolean value"; \ |
| + } \ |
| } |
| // Returns a zero or positive integer value from |pref|. Returns -1 if the |
| @@ -86,7 +93,9 @@ power_manager::PowerManagementPolicy_Action GetProtoAction( |
| PowerPolicyController::PowerPolicyController(DBusThreadManager* manager, |
| PowerManagerClient* client) |
| : manager_(manager), |
| - client_(client) { |
| + client_(client), |
| + prefs_were_set_(false), |
| + next_block_id_(1) { |
| manager_->AddObserver(this); |
| client_->AddObserver(this); |
| SendEmptyPolicy(); |
| @@ -120,46 +129,77 @@ void PowerPolicyController::UpdatePolicyFromPrefs( |
| const PrefService::Preference& use_video_activity_pref, |
| const PrefService::Preference& presentation_idle_delay_factor_pref) { |
| prefs_policy_.Clear(); |
| + bool got_prefs = false; |
| power_manager::PowerManagementPolicy::Delays* delays = |
| prefs_policy_.mutable_ac_delays(); |
| - SET_DELAY_FROM_PREF(ac_screen_dim_delay_ms_pref, screen_dim_ms, delays); |
| - SET_DELAY_FROM_PREF(ac_screen_off_delay_ms_pref, screen_off_ms, delays); |
| - SET_DELAY_FROM_PREF(ac_screen_lock_delay_ms_pref, screen_lock_ms, delays); |
| - SET_DELAY_FROM_PREF(ac_idle_warning_delay_ms_pref, idle_warning_ms, delays); |
| - SET_DELAY_FROM_PREF(ac_idle_delay_ms_pref, idle_ms, delays); |
| + SET_DELAY_FROM_PREF( |
| + ac_screen_dim_delay_ms_pref, screen_dim_ms, delays, got_prefs); |
| + SET_DELAY_FROM_PREF( |
| + ac_screen_off_delay_ms_pref, screen_off_ms, delays, got_prefs); |
| + SET_DELAY_FROM_PREF( |
| + ac_screen_lock_delay_ms_pref, screen_lock_ms, delays, got_prefs); |
| + SET_DELAY_FROM_PREF( |
| + ac_idle_warning_delay_ms_pref, idle_warning_ms, delays, got_prefs); |
| + SET_DELAY_FROM_PREF(ac_idle_delay_ms_pref, idle_ms, delays, got_prefs); |
| delays = prefs_policy_.mutable_battery_delays(); |
| - SET_DELAY_FROM_PREF(battery_screen_dim_delay_ms_pref, screen_dim_ms, delays); |
| - SET_DELAY_FROM_PREF(battery_screen_off_delay_ms_pref, screen_off_ms, delays); |
| SET_DELAY_FROM_PREF( |
| - battery_screen_lock_delay_ms_pref, screen_lock_ms, delays); |
| + battery_screen_dim_delay_ms_pref, screen_dim_ms, delays, got_prefs); |
| SET_DELAY_FROM_PREF( |
| - battery_idle_warning_delay_ms_pref, idle_warning_ms, delays); |
| - SET_DELAY_FROM_PREF(battery_idle_delay_ms_pref, idle_ms, delays); |
| + battery_screen_off_delay_ms_pref, screen_off_ms, delays, got_prefs); |
| + SET_DELAY_FROM_PREF( |
| + battery_screen_lock_delay_ms_pref, screen_lock_ms, delays, got_prefs); |
| + SET_DELAY_FROM_PREF( |
| + battery_idle_warning_delay_ms_pref, idle_warning_ms, delays, got_prefs); |
| + SET_DELAY_FROM_PREF(battery_idle_delay_ms_pref, idle_ms, delays, got_prefs); |
| - SET_ACTION_FROM_PREF(idle_action_pref, idle_action, &prefs_policy_); |
| SET_ACTION_FROM_PREF( |
| - lid_closed_action_pref, lid_closed_action, &prefs_policy_); |
| + idle_action_pref, idle_action, &prefs_policy_, got_prefs); |
| + SET_ACTION_FROM_PREF( |
| + lid_closed_action_pref, lid_closed_action, &prefs_policy_, got_prefs); |
| SET_BOOL_FROM_PREF( |
| - use_audio_activity_pref, use_audio_activity, &prefs_policy_); |
| + use_audio_activity_pref, use_audio_activity, &prefs_policy_, got_prefs); |
| SET_BOOL_FROM_PREF( |
| - use_video_activity_pref, use_video_activity, &prefs_policy_); |
| + use_video_activity_pref, use_video_activity, &prefs_policy_, got_prefs); |
| if (!presentation_idle_delay_factor_pref.IsDefaultValue()) { |
| double value = 0.0; |
| if (presentation_idle_delay_factor_pref.GetValue()->GetAsDouble(&value)) { |
| prefs_policy_.set_presentation_idle_delay_factor(value); |
| + got_prefs = true; |
| } else { |
| LOG(DFATAL) << presentation_idle_delay_factor_pref.name() |
| << " pref has non-double value"; |
| } |
| } |
| + prefs_were_set_ = got_prefs; |
| SendCurrentPolicy(); |
| } |
| +int PowerPolicyController::AddScreenBlock(const std::string& reason) { |
| + int id = next_block_id_++; |
| + screen_blocks_[id] = reason; |
| + SendCurrentPolicy(); |
| + return id; |
| +} |
| + |
| +int PowerPolicyController::AddSuspendBlock(const std::string& reason) { |
| + int id = next_block_id_++; |
| + suspend_blocks_[id] = reason; |
| + SendCurrentPolicy(); |
| + return id; |
| +} |
| + |
| +void PowerPolicyController::RemoveBlock(int id) { |
| + if (!screen_blocks_.erase(id) && !suspend_blocks_.erase(id)) |
| + LOG(WARNING) << "Ignoring request to remove nonexistent block " << id; |
| + else |
| + SendCurrentPolicy(); |
| +} |
| + |
| void PowerPolicyController::OnDBusThreadManagerDestroying( |
| DBusThreadManager* manager) { |
| DCHECK_EQ(manager, manager_); |
| @@ -171,9 +211,38 @@ void PowerPolicyController::PowerManagerRestarted() { |
| } |
| void PowerPolicyController::SendCurrentPolicy() { |
| - // TODO(derat): Incorporate other information into the policy that is |
| - // sent, e.g. from content::PowerSaveBlocker. |
| - client_->SetPolicy(prefs_policy_); |
| + std::string reason; |
| + |
| + power_manager::PowerManagementPolicy policy = prefs_policy_; |
| + if (prefs_were_set_) |
| + reason = "Prefs"; |
| + |
| + if (!screen_blocks_.empty()) { |
| + policy.mutable_ac_delays()->set_screen_dim_ms(0); |
| + policy.mutable_ac_delays()->set_screen_off_ms(0); |
| + policy.mutable_battery_delays()->set_screen_dim_ms(0); |
| + policy.mutable_battery_delays()->set_screen_off_ms(0); |
| + } |
| + |
| + if ((!screen_blocks_.empty() || !suspend_blocks_.empty()) && |
| + (!policy.has_idle_action() || policy.idle_action() == |
| + power_manager::PowerManagementPolicy_Action_SUSPEND)) { |
| + policy.set_idle_action( |
| + power_manager::PowerManagementPolicy_Action_DO_NOTHING); |
| + } |
| + |
| + for (BlockMap::const_iterator it = screen_blocks_.begin(); |
| + it != screen_blocks_.end(); ++it) { |
| + reason += (reason.empty() ? "" : ", ") + it->second; |
| + } |
| + for (BlockMap::const_iterator it = suspend_blocks_.begin(); |
| + it != suspend_blocks_.end(); ++it) { |
| + reason += (reason.empty() ? "" : ", ") + it->second; |
| + } |
| + |
| + if (!reason.empty()) |
| + policy.set_reason(reason); |
| + client_->SetPolicy(policy); |
| } |
| void PowerPolicyController::SendEmptyPolicy() { |