/*
 * Copyright (C) 2015 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 "AWakeLock"
#include <utils/Log.h>

#include "ADebug.h"
#include "AWakeLock.h"

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <powermanager/PowerManager.h>


namespace android {

AWakeLock::AWakeLock() :
    mPowerManager(NULL),
    mWakeLockToken(NULL),
    mWakeLockCount(0),
    mDeathRecipient(new PMDeathRecipient(this)) {}

AWakeLock::~AWakeLock() {
    if (mPowerManager != NULL) {
        sp<IBinder> binder = mPowerManager->asBinder();
        binder->unlinkToDeath(mDeathRecipient);
    }
    clearPowerManager();
}

bool AWakeLock::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("AWakeLock"), String16("media"));
            IPCThreadState::self()->restoreCallingIdentity(token);
            if (status == NO_ERROR) {
                mWakeLockToken = binder;
                mWakeLockCount++;
                return true;
            }
        }
    } else {
        mWakeLockCount++;
        return true;
    }
    return false;
}

void AWakeLock::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 AWakeLock::clearPowerManager() {
    release(true);
    mPowerManager.clear();
}

void AWakeLock::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) {
    if (mWakeLock != NULL) {
        mWakeLock->clearPowerManager();
    }
}

}  // namespace android
