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 "power_manager.h" 18 19 #include <base/files/file_util.h> 20 #include <base/logging.h> 21 #include <base/sys_info.h> 22 #include <binderwrapper/binder_wrapper.h> 23 #include <cutils/android_reboot.h> 24 #include <nativepower/constants.h> 25 #include <powermanager/IPowerManager.h> 26 #include <utils/Errors.h> 27 #include <utils/String8.h> 28 29 namespace android { 30 namespace { 31 32 // Path to real sysfs file that can be written to change the power state. 33 const char kDefaultPowerStatePath[] = "/sys/power/state"; 34 35 } // namespace 36 37 const char PowerManager::kRebootPrefix[] = "reboot,"; 38 const char PowerManager::kShutdownPrefix[] = "shutdown,"; 39 const char PowerManager::kPowerStateSuspend[] = "mem"; 40 41 PowerManager::PowerManager() 42 : power_state_path_(kDefaultPowerStatePath) {} 43 44 PowerManager::~PowerManager() = default; 45 46 bool PowerManager::Init() { 47 if (!property_setter_) 48 property_setter_.reset(new SystemPropertySetter()); 49 if (!wake_lock_manager_) { 50 wake_lock_manager_.reset(new WakeLockManager()); 51 if (!static_cast<WakeLockManager*>(wake_lock_manager_.get())->Init()) 52 return false; 53 } 54 55 LOG(INFO) << "Registering with service manager as \"" 56 << kPowerManagerServiceName << "\""; 57 return BinderWrapper::Get()->RegisterService(kPowerManagerServiceName, this); 58 } 59 60 status_t PowerManager::acquireWakeLock(int flags, 61 const sp<IBinder>& lock, 62 const String16& tag, 63 const String16& packageName, 64 bool isOneWay) { 65 return AddWakeLockRequest(lock, tag, packageName, 66 BinderWrapper::Get()->GetCallingUid()) 67 ? OK 68 : UNKNOWN_ERROR; 69 } 70 71 status_t PowerManager::acquireWakeLockWithUid(int flags, 72 const sp<IBinder>& lock, 73 const String16& tag, 74 const String16& packageName, 75 int uid, 76 bool isOneWay) { 77 return AddWakeLockRequest(lock, tag, packageName, static_cast<uid_t>(uid)) 78 ? OK 79 : UNKNOWN_ERROR; 80 } 81 82 status_t PowerManager::releaseWakeLock(const sp<IBinder>& lock, 83 int flags, 84 bool isOneWay) { 85 return wake_lock_manager_->RemoveRequest(lock) ? OK : UNKNOWN_ERROR; 86 } 87 88 status_t PowerManager::updateWakeLockUids(const sp<IBinder>& lock, 89 int len, 90 const int* uids, 91 bool isOneWay) { 92 NOTIMPLEMENTED() << "updateWakeLockUids: lock=" << lock.get() 93 << " len=" << len; 94 return OK; 95 } 96 97 status_t PowerManager::powerHint(int hintId, int data) { 98 NOTIMPLEMENTED() << "powerHint: hintId=" << hintId << " data=" << data; 99 return OK; 100 } 101 102 status_t PowerManager::goToSleep(int64_t event_time_ms, int reason, int flags) { 103 if (event_time_ms < last_resume_uptime_.InMilliseconds()) { 104 LOG(WARNING) << "Ignoring request to suspend in response to event at " 105 << event_time_ms << " preceding last resume time " 106 << last_resume_uptime_.InMilliseconds(); 107 return BAD_VALUE; 108 } 109 110 LOG(INFO) << "Suspending immediately for event at " << event_time_ms 111 << " (reason=" << reason << " flags=" << flags << ")"; 112 if (base::WriteFile(power_state_path_, kPowerStateSuspend, 113 strlen(kPowerStateSuspend)) != 114 static_cast<int>(strlen(kPowerStateSuspend))) { 115 PLOG(ERROR) << "Failed to write \"" << kPowerStateSuspend << "\" to " 116 << power_state_path_.value(); 117 return UNKNOWN_ERROR; 118 } 119 120 last_resume_uptime_ = base::SysInfo::Uptime(); 121 LOG(INFO) << "Resumed from suspend at " 122 << last_resume_uptime_.InMilliseconds(); 123 return OK; 124 } 125 126 status_t PowerManager::reboot(bool confirm, const String16& reason, bool wait) { 127 const std::string reason_str(String8(reason).string()); 128 if (!(reason_str.empty() || reason_str == kRebootReasonRecovery)) { 129 LOG(WARNING) << "Ignoring reboot request with invalid reason \"" 130 << reason_str << "\""; 131 return BAD_VALUE; 132 } 133 134 LOG(INFO) << "Rebooting with reason \"" << reason_str << "\""; 135 if (!property_setter_->SetProperty(ANDROID_RB_PROPERTY, 136 kRebootPrefix + reason_str)) { 137 return UNKNOWN_ERROR; 138 } 139 return OK; 140 } 141 142 status_t PowerManager::shutdown(bool confirm, 143 const String16& reason, 144 bool wait) { 145 const std::string reason_str(String8(reason).string()); 146 if (!(reason_str.empty() || reason_str == kShutdownReasonUserRequested)) { 147 LOG(WARNING) << "Ignoring shutdown request with invalid reason \"" 148 << reason_str << "\""; 149 return BAD_VALUE; 150 } 151 152 LOG(INFO) << "Shutting down with reason \"" << reason_str << "\""; 153 if (!property_setter_->SetProperty(ANDROID_RB_PROPERTY, 154 kShutdownPrefix + reason_str)) { 155 return UNKNOWN_ERROR; 156 } 157 return OK; 158 } 159 160 status_t PowerManager::crash(const String16& message) { 161 NOTIMPLEMENTED() << "crash: message=" << message; 162 return OK; 163 } 164 165 bool PowerManager::AddWakeLockRequest(const sp<IBinder>& lock, 166 const String16& tag, 167 const String16& packageName, 168 int uid) { 169 return wake_lock_manager_->AddRequest(lock, String8(tag).string(), 170 String8(packageName).string(), uid); 171 } 172 173 } // namespace android 174