1//
2// Copyright (C) 2012 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#ifndef SHILL_POWER_MANAGER_H_
18#define SHILL_POWER_MANAGER_H_
19
20// This class instantiates a PowerManagerProxy and distributes power events to
21// registered users.  It also provides a means for calling methods on the
22// PowerManagerProxy.
23
24#include <map>
25#include <memory>
26#include <string>
27
28#include <base/callback.h>
29#include <base/cancelable_callback.h>
30
31#include "shill/power_manager_proxy_interface.h"
32
33namespace shill {
34
35class EventDispatcher;
36class ControlInterface;
37
38class PowerManager : public PowerManagerProxyDelegate {
39 public:
40  // This callback is called prior to a suspend attempt.  When it is OK for the
41  // system to suspend, this callback should call ReportSuspendReadiness().
42  typedef base::Closure SuspendImminentCallback;
43
44  // This callback is called after the completion of a suspend attempt.  The
45  // receiver should undo any pre-suspend work that was done by the
46  // SuspendImminentCallback.
47  // The receiver should be aware that it is possible to get a
48  // SuspendDoneCallback while processing a DarkSuspendImminentCallback. So,
49  // SuspendDoneCallback should be ready to run concurrently with (and in a
50  // sense override) the actions taken by DarkSuspendImminentCallback.
51  typedef base::Closure SuspendDoneCallback;
52
53  // This callback is called at the beginning of a dark resume.
54  // The receiver should arrange for ReportDarkSuspendImminentReadiness() to be
55  // called when shill is ready to resuspend. In most cases,
56  // ReportDarkSuspendImminentReadiness will be called asynchronously.
57  typedef base::Closure DarkSuspendImminentCallback;
58
59  // |control_itnerface| creates the PowerManagerProxy. Use a fake for testing.
60  // Note: |Start| should be called to initialize this object before using it.
61  PowerManager(EventDispatcher* dispatcher,
62               ControlInterface* control_interface);
63  ~PowerManager() override;
64
65  bool suspending() const { return suspending_; }
66  bool in_dark_resume() const { return in_dark_resume_; }
67
68  // Starts the PowerManager: Registers a suspend delay with the power manager
69  // for |suspend_delay|. See PowerManagerProxyInterface::RegisterSuspendDelay()
70  // for information about |suspend_delay|.
71  // - |imminent_callback| will be invoked when a suspend attempt is commenced
72  // - |done_callback| will be invoked when the attempt is completed. Returns
73  //   false on failure.
74  // - This object guarantees that a call to |imminent_callback| is followed by
75  //   a call to |done_callback| (before any more calls to |imminent_callback|).
76  virtual void Start(
77      base::TimeDelta suspend_delay,
78      const SuspendImminentCallback& suspend_imminent_callback,
79      const SuspendDoneCallback& suspend_done_callback,
80      const DarkSuspendImminentCallback& dark_suspend_imminent_callback);
81  virtual void Stop();
82
83  // Report suspend readiness. If called when there is no suspend attempt
84  // active, this function will fail. Returns true if sucessfully reported to
85  // powerd.
86  virtual bool ReportSuspendReadiness();
87
88  // Report dark suspend readiness. See ReportSuspendReadiness for more details.
89  virtual bool ReportDarkSuspendReadiness();
90
91  // Record the wake reason for the current dark resume.
92  bool RecordDarkResumeWakeReason(const std::string& wake_reason);
93
94  // Methods inherited from PowerManagerProxyDelegate.
95  void OnSuspendImminent(int suspend_id) override;
96  void OnSuspendDone(int suspend_id) override;
97  void OnDarkSuspendImminent(int suspend_id) override;
98
99 private:
100  friend class ManagerTest;
101  friend class PowerManagerTest;
102  friend class ServiceTest;
103
104  // Human-readable string describing the suspend delay that is registered
105  // with the power manager.
106  static const int kInvalidSuspendId;
107  static const char kSuspendDelayDescription[];
108  static const char kDarkSuspendDelayDescription[];
109  static const int kSuspendTimeoutMilliseconds;
110
111  // These functions track the power_manager daemon appearing/vanishing from the
112  // DBus connection.
113  void OnPowerManagerAppeared();
114  void OnPowerManagerVanished();
115
116  EventDispatcher* dispatcher_;
117  ControlInterface* control_interface_;
118
119  // The power manager proxy created by this class.  It dispatches the inherited
120  // delegate methods of this object when changes in the power state occur.
121  std::unique_ptr<PowerManagerProxyInterface> power_manager_proxy_;
122  // The delay (in milliseconds) to request powerd to wait after a suspend
123  // notification is received. powerd will actually suspend the system at least
124  // |suspend_delay_| after the notification, if we do not
125  // |ReportSuspendReadiness| earlier.
126  base::TimeDelta suspend_delay_;
127  // powerd tracks each (dark) suspend delay requested (by different clients)
128  // using randomly generated unique |(dark)suspend_delay_id_|s.
129  bool suspend_delay_registered_;
130  int suspend_delay_id_;
131  bool dark_suspend_delay_registered_;
132  int dark_suspend_delay_id_;
133  // Callbacks from shill called by this object when:
134  // ... powerd notified us that a suspend is imminent.
135  SuspendImminentCallback suspend_imminent_callback_;
136  // ... powerd notified us that the suspend attempt has finished.
137  SuspendDoneCallback suspend_done_callback_;
138  // ... powerd notified us that a dark suspend is imminent. This means that we
139  // just entered dark resume.
140  DarkSuspendImminentCallback dark_suspend_imminent_callback_;
141
142  // Set to true by OnSuspendImminent() and to false by OnSuspendDone().
143  bool suspending_;
144  // Set to true by OnDarkSuspendImminent() and to false by OnSuspendDone().
145  bool in_dark_resume_;
146  int current_suspend_id_;
147  int current_dark_suspend_id_;
148
149  DISALLOW_COPY_AND_ASSIGN(PowerManager);
150};
151
152}  // namespace shill
153
154#endif  // SHILL_POWER_MANAGER_H_
155