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 27namespace android { 28namespace { 29 30// Returns the string corresponding to |reason|. Values are hardcoded in 31// core/java/android/os/PowerManager.java. 32String16 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. 46String16 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 60PowerManagerClient::PowerManagerClient() 61 : weak_ptr_factory_(this) {} 62 63PowerManagerClient::~PowerManagerClient() { 64 if (power_manager_.get()) { 65 BinderWrapper::Get()->UnregisterForDeathNotifications( 66 IInterface::asBinder(power_manager_)); 67 } 68} 69 70bool 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 87std::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 96bool 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 109bool 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 121bool 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 133void 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