1 /*
2 * Copyright (C) 2015 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 #include <nativepower/power_manager_client.h>
18
19 #include <base/bind.h>
20 #include <base/logging.h>
21 #include <binder/IBinder.h>
22 #include <binderwrapper/binder_wrapper.h>
23 #include <nativepower/constants.h>
24 #include <nativepower/wake_lock.h>
25 #include <powermanager/PowerManager.h>
26
27 namespace android {
28 namespace {
29
30 // Returns the string corresponding to |reason|. Values are hardcoded in
31 // core/java/android/os/PowerManager.java.
ShutdownReasonToString16(ShutdownReason reason)32 String16 ShutdownReasonToString16(ShutdownReason reason) {
33 switch (reason) {
34 case ShutdownReason::DEFAULT:
35 return String16();
36 case ShutdownReason::USER_REQUESTED:
37 return String16(kShutdownReasonUserRequested);
38 default:
39 LOG(ERROR) << "Unknown shutdown reason " << static_cast<int>(reason);
40 return String16();
41 }
42 }
43
44 // Returns the string corresponding to |reason|. Values are hardcoded in
45 // core/java/android/os/PowerManager.java.
RebootReasonToString16(RebootReason reason)46 String16 RebootReasonToString16(RebootReason reason) {
47 switch (reason) {
48 case RebootReason::DEFAULT:
49 return String16();
50 case RebootReason::RECOVERY:
51 return String16(kRebootReasonRecovery);
52 default:
53 LOG(ERROR) << "Unknown reboot reason " << static_cast<int>(reason);
54 return String16();
55 }
56 }
57
58 } // namespace
59
PowerManagerClient()60 PowerManagerClient::PowerManagerClient()
61 : weak_ptr_factory_(this) {}
62
~PowerManagerClient()63 PowerManagerClient::~PowerManagerClient() {
64 if (power_manager_.get()) {
65 BinderWrapper::Get()->UnregisterForDeathNotifications(
66 IInterface::asBinder(power_manager_));
67 }
68 }
69
Init()70 bool PowerManagerClient::Init() {
71 sp<IBinder> power_manager_binder =
72 BinderWrapper::Get()->GetService(kPowerManagerServiceName);
73 if (!power_manager_binder.get()) {
74 LOG(ERROR) << "Didn't get " << kPowerManagerServiceName << " service";
75 return false;
76 }
77
78 BinderWrapper::Get()->RegisterForDeathNotifications(
79 power_manager_binder,
80 base::Bind(&PowerManagerClient::OnPowerManagerDied,
81 weak_ptr_factory_.GetWeakPtr()));
82 power_manager_ = interface_cast<IPowerManager>(power_manager_binder);
83
84 return true;
85 }
86
CreateWakeLock(const std::string & tag,const std::string & package)87 std::unique_ptr<WakeLock> PowerManagerClient::CreateWakeLock(
88 const std::string& tag,
89 const std::string& package) {
90 std::unique_ptr<WakeLock> lock(new WakeLock(tag, package, this));
91 if (!lock->Init())
92 lock.reset();
93 return lock;
94 }
95
Suspend(base::TimeDelta event_uptime,SuspendReason reason,int flags)96 bool PowerManagerClient::Suspend(base::TimeDelta event_uptime,
97 SuspendReason reason,
98 int flags) {
99 DCHECK(power_manager_.get());
100 status_t status = power_manager_->goToSleep(
101 event_uptime.InMilliseconds(), static_cast<int>(reason), flags);
102 if (status != OK) {
103 LOG(ERROR) << "Suspend request failed with status " << status;
104 return false;
105 }
106 return true;
107 }
108
ShutDown(ShutdownReason reason)109 bool PowerManagerClient::ShutDown(ShutdownReason reason) {
110 DCHECK(power_manager_.get());
111 status_t status = power_manager_->shutdown(false /* confirm */,
112 ShutdownReasonToString16(reason),
113 false /* wait */);
114 if (status != OK) {
115 LOG(ERROR) << "Shutdown request failed with status " << status;
116 return false;
117 }
118 return true;
119 }
120
Reboot(RebootReason reason)121 bool PowerManagerClient::Reboot(RebootReason reason) {
122 DCHECK(power_manager_.get());
123 status_t status = power_manager_->reboot(false /* confirm */,
124 RebootReasonToString16(reason),
125 false /* wait */);
126 if (status != OK) {
127 LOG(ERROR) << "Reboot request failed with status " << status;
128 return false;
129 }
130 return true;
131 }
132
OnPowerManagerDied()133 void PowerManagerClient::OnPowerManagerDied() {
134 LOG(WARNING) << "Power manager died";
135 power_manager_.clear();
136 // TODO: Try to get a new handle periodically; also consider notifying
137 // previously-created WakeLock objects so they can reacquire locks.
138 }
139
140 } // namespace android
141