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//#define LOG_NDEBUG 0 18#define LOG_TAG "AWakeLock" 19#include <utils/Log.h> 20 21#include "ADebug.h" 22#include "AWakeLock.h" 23 24#include <binder/IPCThreadState.h> 25#include <binder/IServiceManager.h> 26#include <powermanager/PowerManager.h> 27 28 29namespace android { 30 31AWakeLock::AWakeLock() : 32 mPowerManager(NULL), 33 mWakeLockToken(NULL), 34 mWakeLockCount(0), 35 mDeathRecipient(new PMDeathRecipient(this)) {} 36 37AWakeLock::~AWakeLock() { 38 if (mPowerManager != NULL) { 39 sp<IBinder> binder = IInterface::asBinder(mPowerManager); 40 binder->unlinkToDeath(mDeathRecipient); 41 } 42 clearPowerManager(); 43} 44 45bool AWakeLock::acquire() { 46 if (mWakeLockCount == 0) { 47 CHECK(mWakeLockToken == NULL); 48 if (mPowerManager == NULL) { 49 // use checkService() to avoid blocking if power service is not up yet 50 sp<IBinder> binder = 51 defaultServiceManager()->checkService(String16("power")); 52 if (binder == NULL) { 53 ALOGW("could not get the power manager service"); 54 } else { 55 mPowerManager = interface_cast<IPowerManager>(binder); 56 binder->linkToDeath(mDeathRecipient); 57 } 58 } 59 if (mPowerManager != NULL) { 60 sp<IBinder> binder = new BBinder(); 61 int64_t token = IPCThreadState::self()->clearCallingIdentity(); 62 status_t status = mPowerManager->acquireWakeLock( 63 POWERMANAGER_PARTIAL_WAKE_LOCK, 64 binder, String16("AWakeLock"), String16("media")); 65 IPCThreadState::self()->restoreCallingIdentity(token); 66 if (status == NO_ERROR) { 67 mWakeLockToken = binder; 68 mWakeLockCount++; 69 return true; 70 } 71 } 72 } else { 73 mWakeLockCount++; 74 return true; 75 } 76 return false; 77} 78 79void AWakeLock::release(bool force) { 80 if (mWakeLockCount == 0) { 81 return; 82 } 83 if (force) { 84 // Force wakelock release below by setting reference count to 1. 85 mWakeLockCount = 1; 86 } 87 if (--mWakeLockCount == 0) { 88 CHECK(mWakeLockToken != NULL); 89 if (mPowerManager != NULL) { 90 int64_t token = IPCThreadState::self()->clearCallingIdentity(); 91 mPowerManager->releaseWakeLock(mWakeLockToken, 0 /* flags */); 92 IPCThreadState::self()->restoreCallingIdentity(token); 93 } 94 mWakeLockToken.clear(); 95 } 96} 97 98void AWakeLock::clearPowerManager() { 99 release(true); 100 mPowerManager.clear(); 101} 102 103void AWakeLock::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) { 104 if (mWakeLock != NULL) { 105 mWakeLock->clearPowerManager(); 106 } 107} 108 109} // namespace android 110