- add sources.
[platform/framework/web/crosswalk.git] / src / chromeos / dbus / power_policy_controller.cc
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chromeos/dbus/power_policy_controller.h"
6
7 #include "base/format_macros.h"
8 #include "base/logging.h"
9 #include "base/strings/string_util.h"
10 #include "base/strings/stringprintf.h"
11 #include "chromeos/dbus/dbus_thread_manager.h"
12
13 namespace chromeos {
14
15 namespace {
16
17 // Appends a description of |field|, a field within |delays|, a
18 // power_manager::PowerManagementPolicy::Delays object, to |str|, an
19 // std::string, if the field is set.  |name| is a char* describing the
20 // field.
21 #define APPEND_DELAY(str, delays, field, name)                                 \
22     {                                                                          \
23       if (delays.has_##field())                                                \
24         str += base::StringPrintf(name "=%" PRId64 " ", delays.field());       \
25     }
26
27 // Appends descriptions of all of the set delays in |delays|, a
28 // power_manager::PowerManagementPolicy::Delays object, to |str|, an
29 // std::string.  |prefix| should be a char* containing either "ac" or
30 // "battery".
31 #define APPEND_DELAYS(str, delays, prefix)                                     \
32     {                                                                          \
33       APPEND_DELAY(str, delays, screen_dim_ms, prefix "_screen_dim_ms");       \
34       APPEND_DELAY(str, delays, screen_off_ms, prefix "_screen_off_ms");       \
35       APPEND_DELAY(str, delays, screen_lock_ms, prefix "_screen_lock_ms");     \
36       APPEND_DELAY(str, delays, idle_warning_ms, prefix "_idle_warning_ms");   \
37       APPEND_DELAY(str, delays, idle_ms, prefix "_idle_ms");                   \
38     }
39
40 // Returns the power_manager::PowerManagementPolicy_Action value
41 // corresponding to |action|.
42 power_manager::PowerManagementPolicy_Action GetProtoAction(
43     PowerPolicyController::Action action) {
44   switch (action) {
45     case PowerPolicyController::ACTION_SUSPEND:
46       return power_manager::PowerManagementPolicy_Action_SUSPEND;
47     case PowerPolicyController::ACTION_STOP_SESSION:
48       return power_manager::PowerManagementPolicy_Action_STOP_SESSION;
49     case PowerPolicyController::ACTION_SHUT_DOWN:
50       return power_manager::PowerManagementPolicy_Action_SHUT_DOWN;
51     case PowerPolicyController::ACTION_DO_NOTHING:
52       return power_manager::PowerManagementPolicy_Action_DO_NOTHING;
53     default:
54       NOTREACHED() << "Unhandled action " << action;
55       return power_manager::PowerManagementPolicy_Action_DO_NOTHING;
56   }
57 }
58
59 }  // namespace
60
61 const int PowerPolicyController::kScreenLockAfterOffDelayMs = 10000;  // 10 sec.
62
63 // -1 is interpreted as "unset" by powerd, resulting in powerd's default
64 // delays being used instead.  There are no similarly-interpreted values
65 // for the other fields, unfortunately (but the constructor-assigned values
66 // will only reach powerd if Chrome messes up and forgets to override them
67 // with the pref-assigned values).
68 PowerPolicyController::PrefValues::PrefValues()
69     : ac_screen_dim_delay_ms(-1),
70       ac_screen_off_delay_ms(-1),
71       ac_screen_lock_delay_ms(-1),
72       ac_idle_warning_delay_ms(-1),
73       ac_idle_delay_ms(-1),
74       battery_screen_dim_delay_ms(-1),
75       battery_screen_off_delay_ms(-1),
76       battery_screen_lock_delay_ms(-1),
77       battery_idle_warning_delay_ms(-1),
78       battery_idle_delay_ms(-1),
79       ac_idle_action(ACTION_SUSPEND),
80       battery_idle_action(ACTION_SUSPEND),
81       lid_closed_action(ACTION_SUSPEND),
82       use_audio_activity(true),
83       use_video_activity(true),
84       allow_screen_wake_locks(true),
85       enable_screen_lock(false),
86       presentation_screen_dim_delay_factor(1.0),
87       user_activity_screen_dim_delay_factor(1.0),
88       wait_for_initial_user_activity(false) {}
89
90 // static
91 std::string PowerPolicyController::GetPolicyDebugString(
92     const power_manager::PowerManagementPolicy& policy) {
93   std::string str;
94   if (policy.has_ac_delays())
95     APPEND_DELAYS(str, policy.ac_delays(), "ac");
96   if (policy.has_battery_delays())
97     APPEND_DELAYS(str, policy.battery_delays(), "battery");
98   if (policy.has_ac_idle_action())
99     str += base::StringPrintf("ac_idle=%d ", policy.ac_idle_action());
100   if (policy.has_battery_idle_action())
101     str += base::StringPrintf("battery_idle=%d ", policy.battery_idle_action());
102   if (policy.has_lid_closed_action())
103     str += base::StringPrintf("lid_closed=%d ", policy.lid_closed_action());
104   if (policy.has_use_audio_activity())
105     str += base::StringPrintf("use_audio=%d ", policy.use_audio_activity());
106   if (policy.has_use_video_activity())
107     str += base::StringPrintf("use_video=%d ", policy.use_audio_activity());
108   if (policy.has_presentation_screen_dim_delay_factor()) {
109     str += base::StringPrintf("presentation_screen_dim_delay_factor=%f ",
110         policy.presentation_screen_dim_delay_factor());
111   }
112   if (policy.has_user_activity_screen_dim_delay_factor()) {
113     str += base::StringPrintf("user_activity_screen_dim_delay_factor=%f ",
114         policy.user_activity_screen_dim_delay_factor());
115   }
116   if (policy.has_wait_for_initial_user_activity()) {
117     str += base::StringPrintf("wait_for_initial_user_activity=%d ",
118         policy.wait_for_initial_user_activity());
119   }
120   if (policy.has_reason())
121     str += base::StringPrintf("reason=\"%s\" ", policy.reason().c_str());
122   TrimWhitespace(str, TRIM_TRAILING, &str);
123   return str;
124 }
125
126 PowerPolicyController::PowerPolicyController(DBusThreadManager* manager,
127                                              PowerManagerClient* client)
128     : manager_(manager),
129       client_(client),
130       prefs_were_set_(false),
131       honor_screen_wake_locks_(true),
132       next_wake_lock_id_(1) {
133   manager_->AddObserver(this);
134   client_->AddObserver(this);
135   SendCurrentPolicy();
136 }
137
138 PowerPolicyController::~PowerPolicyController() {
139   // The power manager's policy is reset before this point, in
140   // OnDBusThreadManagerDestroying().  At the time that
141   // PowerPolicyController is destroyed, PowerManagerClient's D-Bus proxy
142   // to the power manager is already gone.
143   client_->RemoveObserver(this);
144   client_ = NULL;
145   manager_->RemoveObserver(this);
146   manager_ = NULL;
147 }
148
149 void PowerPolicyController::ApplyPrefs(const PrefValues& values) {
150   prefs_policy_.Clear();
151
152   power_manager::PowerManagementPolicy::Delays* delays =
153       prefs_policy_.mutable_ac_delays();
154   delays->set_screen_dim_ms(values.ac_screen_dim_delay_ms);
155   delays->set_screen_off_ms(values.ac_screen_off_delay_ms);
156   delays->set_screen_lock_ms(values.ac_screen_lock_delay_ms);
157   delays->set_idle_warning_ms(values.ac_idle_warning_delay_ms);
158   delays->set_idle_ms(values.ac_idle_delay_ms);
159
160   // If screen-locking is enabled, ensure that the screen is locked soon
161   // after it's turned off due to user inactivity.
162   int64 lock_ms = delays->screen_off_ms() + kScreenLockAfterOffDelayMs;
163   if (values.enable_screen_lock && delays->screen_off_ms() > 0 &&
164       (delays->screen_lock_ms() <= 0 || lock_ms < delays->screen_lock_ms()) &&
165       lock_ms < delays->idle_ms()) {
166     delays->set_screen_lock_ms(lock_ms);
167   }
168
169   delays = prefs_policy_.mutable_battery_delays();
170   delays->set_screen_dim_ms(values.battery_screen_dim_delay_ms);
171   delays->set_screen_off_ms(values.battery_screen_off_delay_ms);
172   delays->set_screen_lock_ms(values.battery_screen_lock_delay_ms);
173   delays->set_idle_warning_ms(values.battery_idle_warning_delay_ms);
174   delays->set_idle_ms(values.battery_idle_delay_ms);
175
176   lock_ms = delays->screen_off_ms() + kScreenLockAfterOffDelayMs;
177   if (values.enable_screen_lock && delays->screen_off_ms() > 0 &&
178       (delays->screen_lock_ms() <= 0 || lock_ms < delays->screen_lock_ms()) &&
179       lock_ms < delays->idle_ms()) {
180     delays->set_screen_lock_ms(lock_ms);
181   }
182
183   prefs_policy_.set_ac_idle_action(GetProtoAction(values.ac_idle_action));
184   prefs_policy_.set_battery_idle_action(
185       GetProtoAction(values.battery_idle_action));
186   prefs_policy_.set_lid_closed_action(GetProtoAction(values.lid_closed_action));
187   prefs_policy_.set_use_audio_activity(values.use_audio_activity);
188   prefs_policy_.set_use_video_activity(values.use_video_activity);
189   prefs_policy_.set_presentation_screen_dim_delay_factor(
190       values.presentation_screen_dim_delay_factor);
191   prefs_policy_.set_user_activity_screen_dim_delay_factor(
192       values.user_activity_screen_dim_delay_factor);
193   prefs_policy_.set_wait_for_initial_user_activity(
194       values.wait_for_initial_user_activity);
195
196   honor_screen_wake_locks_ = values.allow_screen_wake_locks;
197
198   prefs_were_set_ = true;
199   SendCurrentPolicy();
200 }
201
202 void PowerPolicyController::ClearPrefs() {
203   prefs_policy_.Clear();
204   honor_screen_wake_locks_ = true;
205   prefs_were_set_ = false;
206   SendCurrentPolicy();
207 }
208
209 int PowerPolicyController::AddScreenWakeLock(const std::string& reason) {
210   int id = next_wake_lock_id_++;
211   screen_wake_locks_[id] = reason;
212   SendCurrentPolicy();
213   return id;
214 }
215
216 int PowerPolicyController::AddSystemWakeLock(const std::string& reason) {
217   int id = next_wake_lock_id_++;
218   system_wake_locks_[id] = reason;
219   SendCurrentPolicy();
220   return id;
221 }
222
223 void PowerPolicyController::RemoveWakeLock(int id) {
224   if (!screen_wake_locks_.erase(id) && !system_wake_locks_.erase(id))
225     LOG(WARNING) << "Ignoring request to remove nonexistent wake lock " << id;
226   else
227     SendCurrentPolicy();
228 }
229
230 void PowerPolicyController::OnDBusThreadManagerDestroying(
231     DBusThreadManager* manager) {
232   DCHECK_EQ(manager, manager_);
233   SendEmptyPolicy();
234 }
235
236 void PowerPolicyController::PowerManagerRestarted() {
237   SendCurrentPolicy();
238 }
239
240 void PowerPolicyController::SendCurrentPolicy() {
241   std::string reason;
242
243   power_manager::PowerManagementPolicy policy = prefs_policy_;
244   if (prefs_were_set_)
245     reason = "Prefs";
246
247   if (honor_screen_wake_locks_ && !screen_wake_locks_.empty()) {
248     policy.mutable_ac_delays()->set_screen_dim_ms(0);
249     policy.mutable_ac_delays()->set_screen_off_ms(0);
250     policy.mutable_ac_delays()->set_screen_lock_ms(0);
251     policy.mutable_battery_delays()->set_screen_dim_ms(0);
252     policy.mutable_battery_delays()->set_screen_off_ms(0);
253     policy.mutable_battery_delays()->set_screen_lock_ms(0);
254   }
255
256   if (!screen_wake_locks_.empty() || !system_wake_locks_.empty()) {
257     if (!policy.has_ac_idle_action() || policy.ac_idle_action() ==
258         power_manager::PowerManagementPolicy_Action_SUSPEND) {
259       policy.set_ac_idle_action(
260           power_manager::PowerManagementPolicy_Action_DO_NOTHING);
261     }
262     if (!policy.has_battery_idle_action() || policy.battery_idle_action() ==
263         power_manager::PowerManagementPolicy_Action_SUSPEND) {
264       policy.set_battery_idle_action(
265           power_manager::PowerManagementPolicy_Action_DO_NOTHING);
266     }
267   }
268
269   for (WakeLockMap::const_iterator it = screen_wake_locks_.begin();
270        it != screen_wake_locks_.end(); ++it) {
271     reason += (reason.empty() ? "" : ", ") + it->second;
272   }
273   for (WakeLockMap::const_iterator it = system_wake_locks_.begin();
274        it != system_wake_locks_.end(); ++it) {
275     reason += (reason.empty() ? "" : ", ") + it->second;
276   }
277
278   if (!reason.empty())
279     policy.set_reason(reason);
280   client_->SetPolicy(policy);
281 }
282
283 void PowerPolicyController::SendEmptyPolicy() {
284   client_->SetPolicy(power_manager::PowerManagementPolicy());
285 }
286
287 }  // namespace chromeos