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 "AWakeLock.h" 22 23 #include <binder/IPCThreadState.h> 24 #include <binder/IServiceManager.h> 25 #include <media/stagefright/foundation/ADebug.h> 26 #include <powermanager/PowerManager.h> 27 28 29 namespace android { 30 31 AWakeLock::AWakeLock() : 32 mPowerManager(NULL), 33 mWakeLockToken(NULL), 34 mWakeLockCount(0), 35 mDeathRecipient(new PMDeathRecipient(this)) {} 36 37 AWakeLock::~AWakeLock() { 38 if (mPowerManager != NULL) { 39 sp<IBinder> binder = IInterface::asBinder(mPowerManager); 40 binder->unlinkToDeath(mDeathRecipient); 41 } 42 clearPowerManager(); 43 } 44 45 bool 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 79 void 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 98 void AWakeLock::clearPowerManager() { 99 release(true); 100 mPowerManager.clear(); 101 } 102 103 void AWakeLock::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) { 104 if (mWakeLock != NULL) { 105 mWakeLock->clearPowerManager(); 106 } 107 } 108 109 } // namespace android 110