blob: 6f8441ce08009c6acd66d666e221c200aba45d3d [file] [log] [blame]
Gary Morain43bc6272012-01-30 14:01:15 -08001// Copyright (c) 2012 The Chromium OS 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 "shill/power_manager.h"
6
7#include <map>
8#include <string>
9
Prathmesh Prabhud9c786c2014-04-23 17:37:28 -070010#include <base/bind.h>
Eric Shienbrood3e20a232012-02-16 11:35:56 -050011#include <base/stl_util.h>
Prathmesh Prabhud9c786c2014-04-23 17:37:28 -070012#include <chromeos/dbus/service_constants.h>
Gary Morain43bc6272012-01-30 14:01:15 -080013
Prathmesh Prabhud9c786c2014-04-23 17:37:28 -070014#include "shill/dbus_manager.h"
Darin Petkov3ec55342012-09-28 14:04:44 +020015#include "shill/event_dispatcher.h"
Christopher Wileyb691efd2012-08-09 13:51:51 -070016#include "shill/logging.h"
Gary Morain43bc6272012-01-30 14:01:15 -080017#include "shill/power_manager_proxy_interface.h"
18#include "shill/proxy_factory.h"
19
Prathmesh Prabhud9c786c2014-04-23 17:37:28 -070020using base::Bind;
21using base::TimeDelta;
22using base::Unretained;
Gary Morain52fabab2012-08-22 09:27:31 -070023using std::map;
Gary Morain43bc6272012-01-30 14:01:15 -080024using std::string;
25
26namespace shill {
27
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070028// static
Prathmesh Prabhu0f4e0a42014-08-27 15:29:00 -070029const int PowerManager::kInvalidSuspendId = -1;
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070030const char PowerManager::kSuspendDelayDescription[] = "shill";
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -070031const char PowerManager::kDarkSuspendDelayDescription[] = "shill";
Darin Petkov3ec55342012-09-28 14:04:44 +020032const int PowerManager::kSuspendTimeoutMilliseconds = 15 * 1000;
33
Paul Stewart1a212a62015-06-16 13:13:10 -070034PowerManager::PowerManager(EventDispatcher* dispatcher,
35 ProxyFactory* proxy_factory)
Darin Petkov3ec55342012-09-28 14:04:44 +020036 : dispatcher_(dispatcher),
37 power_manager_proxy_(proxy_factory->CreatePowerManagerProxy(this)),
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070038 suspend_delay_registered_(false),
39 suspend_delay_id_(0),
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -070040 dark_suspend_delay_registered_(false),
41 dark_suspend_delay_id_(0),
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070042 suspending_(false),
Samuel Tan787a1ce2014-11-11 17:17:27 -080043 in_dark_resume_(false),
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -070044 current_suspend_id_(0),
45 current_dark_suspend_id_(0) {}
Gary Morain43bc6272012-01-30 14:01:15 -080046
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070047PowerManager::~PowerManager() {}
Gary Morain43bc6272012-01-30 14:01:15 -080048
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070049void PowerManager::Start(
Paul Stewart1a212a62015-06-16 13:13:10 -070050 DBusManager* dbus_manager,
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070051 TimeDelta suspend_delay,
Paul Stewart1a212a62015-06-16 13:13:10 -070052 const SuspendImminentCallback& suspend_imminent_callback,
53 const SuspendDoneCallback& suspend_done_callback,
54 const DarkSuspendImminentCallback& dark_suspend_imminent_callback) {
Prathmesh Prabhud9c786c2014-04-23 17:37:28 -070055 power_manager_name_watcher_.reset(
56 dbus_manager->CreateNameWatcher(
57 power_manager::kPowerManagerServiceName,
58 Bind(&PowerManager::OnPowerManagerAppeared, Unretained(this)),
59 Bind(&PowerManager::OnPowerManagerVanished, Unretained(this))));
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070060
61 suspend_delay_ = suspend_delay;
62 suspend_imminent_callback_ = suspend_imminent_callback;
63 suspend_done_callback_ = suspend_done_callback;
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -070064 dark_suspend_imminent_callback_ = dark_suspend_imminent_callback;
Prathmesh Prabhud9c786c2014-04-23 17:37:28 -070065}
66
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070067void PowerManager::Stop() {
68 LOG(INFO) << __func__;
69 power_manager_name_watcher_.reset();
70 // We may attempt to unregister with a stale |suspend_delay_id_| if powerd
Prathmesh Prabhud9c786c2014-04-23 17:37:28 -070071 // reappeared behind our back. It is safe to do so.
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070072 if (suspend_delay_registered_)
73 power_manager_proxy_->UnregisterSuspendDelay(suspend_delay_id_);
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -070074 if (dark_suspend_delay_registered_)
75 power_manager_proxy_->UnregisterDarkSuspendDelay(dark_suspend_delay_id_);
Daniel Eratfac09532014-04-17 20:25:59 -070076
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070077 suspend_delay_registered_ = false;
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -070078 dark_suspend_delay_registered_ = false;
Gary Morain43bc6272012-01-30 14:01:15 -080079}
80
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070081bool PowerManager::ReportSuspendReadiness() {
82 if (!suspending_) {
83 LOG(INFO) << __func__ << ": Suspend attempt ("
84 << current_suspend_id_ << ") not active. Ignoring signal.";
Daniel Eratfac09532014-04-17 20:25:59 -070085 return false;
86 }
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -070087 return power_manager_proxy_->ReportSuspendReadiness(suspend_delay_id_,
88 current_suspend_id_);
Gary Morain52fabab2012-08-22 09:27:31 -070089}
90
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -070091bool PowerManager::ReportDarkSuspendReadiness() {
92 return power_manager_proxy_->ReportDarkSuspendReadiness(
93 dark_suspend_delay_id_,
94 current_dark_suspend_id_);
95}
96
Paul Stewart1a212a62015-06-16 13:13:10 -070097bool PowerManager::RecordDarkResumeWakeReason(const string& wake_reason) {
Samuel Tan1897afa2015-05-21 14:21:56 -070098 return power_manager_proxy_->RecordDarkResumeWakeReason(wake_reason);
99}
100
Daniel Erat0818cca2012-12-14 10:16:21 -0800101void PowerManager::OnSuspendImminent(int suspend_id) {
102 LOG(INFO) << __func__ << "(" << suspend_id << ")";
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -0700103 current_suspend_id_ = suspend_id;
104
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -0700105 // If we're already suspending, don't call the |suspend_imminent_callback_|
106 // again.
107 if (!suspending_) {
108 // Change the power state to suspending as soon as this signal is received
109 // so that the manager can suppress auto-connect, for example.
Prathmesh Prabhu0f4e0a42014-08-27 15:29:00 -0700110 // Also, we must set this before running the callback below, because the
111 // callback may synchronously report suspend readiness.
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -0700112 suspending_ = true;
113 suspend_imminent_callback_.Run();
Daniel Eratfac09532014-04-17 20:25:59 -0700114 }
Gary Morain43bc6272012-01-30 14:01:15 -0800115}
116
Daniel Eratfac09532014-04-17 20:25:59 -0700117void PowerManager::OnSuspendDone(int suspend_id) {
Prathmesh Prabhu0f4e0a42014-08-27 15:29:00 -0700118 // NB: |suspend_id| could be -1. See OnPowerManagerVanished.
Daniel Eratfac09532014-04-17 20:25:59 -0700119 LOG(INFO) << __func__ << "(" << suspend_id << ")";
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -0700120 if (!suspending_) {
121 LOG(WARNING) << "Recieved unexpected SuspendDone ("
122 << suspend_id << "). Ignoring.";
123 return;
124 }
125
Daniel Eratfac09532014-04-17 20:25:59 -0700126 suspending_ = false;
Samuel Tan787a1ce2014-11-11 17:17:27 -0800127 in_dark_resume_ = false;
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -0700128 suspend_done_callback_.Run();
Gary Morain52fabab2012-08-22 09:27:31 -0700129}
130
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -0700131void PowerManager::OnDarkSuspendImminent(int suspend_id) {
132 LOG(INFO) << __func__ << "(" << suspend_id << ")";
133 if (!dark_suspend_delay_registered_) {
134 LOG(WARNING) << "Ignoring DarkSuspendImminent signal from powerd. shill "
135 << "does not have a dark suspend delay registered. This "
136 << "means that shill is not guaranteed any time before a "
137 << "resuspend.";
138 return;
139 }
Samuel Tan787a1ce2014-11-11 17:17:27 -0800140 in_dark_resume_ = true;
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -0700141 current_dark_suspend_id_ = suspend_id;
142 dark_suspend_imminent_callback_.Run();
143}
144
Paul Stewart1a212a62015-06-16 13:13:10 -0700145void PowerManager::OnPowerManagerAppeared(const string& /*name*/,
146 const string& /*owner*/) {
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -0700147 LOG(INFO) << __func__;
148 CHECK(!suspend_delay_registered_);
149 if (power_manager_proxy_->RegisterSuspendDelay(suspend_delay_,
150 kSuspendDelayDescription,
151 &suspend_delay_id_))
152 suspend_delay_registered_ = true;
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -0700153
154 if (power_manager_proxy_->RegisterDarkSuspendDelay(
155 suspend_delay_,
156 kDarkSuspendDelayDescription,
157 &dark_suspend_delay_id_))
158 dark_suspend_delay_registered_ = true;
Prathmesh Prabhud9c786c2014-04-23 17:37:28 -0700159}
160
Paul Stewart1a212a62015-06-16 13:13:10 -0700161void PowerManager::OnPowerManagerVanished(const string& /*name*/) {
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -0700162 LOG(INFO) << __func__;
Prathmesh Prabhu0f4e0a42014-08-27 15:29:00 -0700163 // If powerd vanished during a suspend, we need to wake ourselves up.
164 if (suspending_)
165 OnSuspendDone(kInvalidSuspendId);
Prathmesh Prabhu9fdb84b2014-08-21 18:41:58 -0700166 suspend_delay_registered_ = false;
Prathmesh Prabhu64ad2382014-08-26 11:19:30 -0700167 dark_suspend_delay_registered_ = false;
Prathmesh Prabhud9c786c2014-04-23 17:37:28 -0700168}
169
Gary Morain43bc6272012-01-30 14:01:15 -0800170} // namespace shill