| /* |
| * Copyright 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| //#define LOG_NDEBUG 0 |
| #define LOG_TAG "JWakeLock" |
| #include <utils/Log.h> |
| |
| #include "JWakeLock.h" |
| |
| #include <binder/IPCThreadState.h> |
| #include <binder/IServiceManager.h> |
| #include <media/stagefright/foundation/ADebug.h> |
| #include <powermanager/PowerManager.h> |
| |
| |
| namespace android { |
| |
| //TODO: use JAVA PowerManager, instead of binder |
| JWakeLock::JWakeLock() : |
| mPowerManager(NULL), |
| mWakeLockToken(NULL), |
| mWakeLockCount(0), |
| mDeathRecipient(new PMDeathRecipient(this)) {} |
| |
| JWakeLock::~JWakeLock() { |
| if (mPowerManager != NULL) { |
| sp<IBinder> binder = IInterface::asBinder(mPowerManager); |
| binder->unlinkToDeath(mDeathRecipient); |
| } |
| clearPowerManager(); |
| } |
| |
| bool JWakeLock::acquire() { |
| if (mWakeLockCount == 0) { |
| CHECK(mWakeLockToken == NULL); |
| if (mPowerManager == NULL) { |
| // use checkService() to avoid blocking if power service is not up yet |
| sp<IBinder> binder = |
| defaultServiceManager()->checkService(String16("power")); |
| if (binder == NULL) { |
| ALOGW("could not get the power manager service"); |
| } else { |
| mPowerManager = interface_cast<IPowerManager>(binder); |
| binder->linkToDeath(mDeathRecipient); |
| } |
| } |
| if (mPowerManager != NULL) { |
| sp<IBinder> binder = new BBinder(); |
| int64_t token = IPCThreadState::self()->clearCallingIdentity(); |
| status_t status = mPowerManager->acquireWakeLock( |
| POWERMANAGER_PARTIAL_WAKE_LOCK, |
| binder, String16("JWakeLock"), String16("media")); |
| IPCThreadState::self()->restoreCallingIdentity(token); |
| if (status == NO_ERROR) { |
| mWakeLockToken = binder; |
| mWakeLockCount++; |
| return true; |
| } |
| } |
| } else { |
| mWakeLockCount++; |
| return true; |
| } |
| return false; |
| } |
| |
| void JWakeLock::release(bool force) { |
| if (mWakeLockCount == 0) { |
| return; |
| } |
| if (force) { |
| // Force wakelock release below by setting reference count to 1. |
| mWakeLockCount = 1; |
| } |
| if (--mWakeLockCount == 0) { |
| CHECK(mWakeLockToken != NULL); |
| if (mPowerManager != NULL) { |
| int64_t token = IPCThreadState::self()->clearCallingIdentity(); |
| mPowerManager->releaseWakeLock(mWakeLockToken, 0 /* flags */); |
| IPCThreadState::self()->restoreCallingIdentity(token); |
| } |
| mWakeLockToken.clear(); |
| } |
| } |
| |
| void JWakeLock::clearPowerManager() { |
| release(true); |
| mPowerManager.clear(); |
| } |
| |
| void JWakeLock::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) { |
| if (mWakeLock != NULL) { |
| mWakeLock->clearPowerManager(); |
| } |
| } |
| |
| } // namespace android |