135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang/*
235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang * Copyright (C) 2015 The Android Open Source Project
335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang *
435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang * Licensed under the Apache License, Version 2.0 (the "License");
535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang * you may not use this file except in compliance with the License.
635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang * You may obtain a copy of the License at
735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang *
835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang *      http://www.apache.org/licenses/LICENSE-2.0
935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang *
1035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang * Unless required by applicable law or agreed to in writing, software
1135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang * distributed under the License is distributed on an "AS IS" BASIS,
1235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang * See the License for the specific language governing permissions and
1435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang * limitations under the License.
1535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang */
1635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
1735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang//#define LOG_NDEBUG 0
1835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang#define LOG_TAG "AWakeLock"
1935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang#include <utils/Log.h>
2035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
2135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang#include "ADebug.h"
2235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang#include "AWakeLock.h"
2335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
2435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang#include <binder/IPCThreadState.h>
2535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang#include <binder/IServiceManager.h>
2635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang#include <powermanager/PowerManager.h>
2735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
2835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
2935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiangnamespace android {
3035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
3135d5af131c9d4962e935082f204ccd6a2130861cWeiyin JiangAWakeLock::AWakeLock() :
3235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    mPowerManager(NULL),
3335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    mWakeLockToken(NULL),
3435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    mWakeLockCount(0),
3535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    mDeathRecipient(new PMDeathRecipient(this)) {}
3635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
3735d5af131c9d4962e935082f204ccd6a2130861cWeiyin JiangAWakeLock::~AWakeLock() {
3835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    if (mPowerManager != NULL) {
3935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        sp<IBinder> binder = mPowerManager->asBinder();
4035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        binder->unlinkToDeath(mDeathRecipient);
4135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    }
4235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    clearPowerManager();
4335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang}
4435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
4535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiangbool AWakeLock::acquire() {
4635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    if (mWakeLockCount == 0) {
4735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        CHECK(mWakeLockToken == NULL);
4835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        if (mPowerManager == NULL) {
4935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            // use checkService() to avoid blocking if power service is not up yet
5035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            sp<IBinder> binder =
5135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang                defaultServiceManager()->checkService(String16("power"));
5235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            if (binder == NULL) {
5335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang                ALOGW("could not get the power manager service");
5435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            } else {
5535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang                mPowerManager = interface_cast<IPowerManager>(binder);
5635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang                binder->linkToDeath(mDeathRecipient);
5735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            }
5835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        }
5935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        if (mPowerManager != NULL) {
6035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            sp<IBinder> binder = new BBinder();
6135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            int64_t token = IPCThreadState::self()->clearCallingIdentity();
6235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            status_t status = mPowerManager->acquireWakeLock(
6335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang                    POWERMANAGER_PARTIAL_WAKE_LOCK,
6435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang                    binder, String16("AWakeLock"), String16("media"));
6535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            IPCThreadState::self()->restoreCallingIdentity(token);
6635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            if (status == NO_ERROR) {
6735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang                mWakeLockToken = binder;
6835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang                mWakeLockCount++;
6935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang                return true;
7035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            }
7135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        }
7235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    } else {
7335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        mWakeLockCount++;
7435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        return true;
7535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    }
7635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    return false;
7735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang}
7835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
7935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiangvoid AWakeLock::release(bool force) {
8035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    if (mWakeLockCount == 0) {
8135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        return;
8235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    }
8335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    if (force) {
8435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        // Force wakelock release below by setting reference count to 1.
8535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        mWakeLockCount = 1;
8635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    }
8735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    if (--mWakeLockCount == 0) {
8835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        CHECK(mWakeLockToken != NULL);
8935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        if (mPowerManager != NULL) {
9035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            int64_t token = IPCThreadState::self()->clearCallingIdentity();
9135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            mPowerManager->releaseWakeLock(mWakeLockToken, 0 /* flags */);
9235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang            IPCThreadState::self()->restoreCallingIdentity(token);
9335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        }
9435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        mWakeLockToken.clear();
9535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    }
9635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang}
9735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
9835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiangvoid AWakeLock::clearPowerManager() {
9935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    release(true);
10035d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    mPowerManager.clear();
10135d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang}
10235d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
10335d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiangvoid AWakeLock::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) {
10435d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    if (mWakeLock != NULL) {
10535d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang        mWakeLock->clearPowerManager();
10635d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang    }
10735d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang}
10835d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang
10935d5af131c9d4962e935082f204ccd6a2130861cWeiyin Jiang}  // namespace android
110