1*ec779b8eSAndroid Build Coastguard Worker /*
2*ec779b8eSAndroid Build Coastguard Worker * Copyright (C) 2015 The Android Open Source Project
3*ec779b8eSAndroid Build Coastguard Worker *
4*ec779b8eSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*ec779b8eSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*ec779b8eSAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*ec779b8eSAndroid Build Coastguard Worker *
8*ec779b8eSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*ec779b8eSAndroid Build Coastguard Worker *
10*ec779b8eSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*ec779b8eSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*ec779b8eSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*ec779b8eSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*ec779b8eSAndroid Build Coastguard Worker * limitations under the License.
15*ec779b8eSAndroid Build Coastguard Worker */
16*ec779b8eSAndroid Build Coastguard Worker
17*ec779b8eSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
18*ec779b8eSAndroid Build Coastguard Worker #define LOG_TAG "AWakeLock"
19*ec779b8eSAndroid Build Coastguard Worker #include <utils/Log.h>
20*ec779b8eSAndroid Build Coastguard Worker
21*ec779b8eSAndroid Build Coastguard Worker #include "AWakeLock.h"
22*ec779b8eSAndroid Build Coastguard Worker
23*ec779b8eSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
24*ec779b8eSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
25*ec779b8eSAndroid Build Coastguard Worker #include <media/stagefright/foundation/ADebug.h>
26*ec779b8eSAndroid Build Coastguard Worker #include <powermanager/PowerManager.h>
27*ec779b8eSAndroid Build Coastguard Worker
28*ec779b8eSAndroid Build Coastguard Worker
29*ec779b8eSAndroid Build Coastguard Worker namespace android {
30*ec779b8eSAndroid Build Coastguard Worker
31*ec779b8eSAndroid Build Coastguard Worker const int32_t INVALID_DISPLAY_ID = -1;
32*ec779b8eSAndroid Build Coastguard Worker
AWakeLock()33*ec779b8eSAndroid Build Coastguard Worker AWakeLock::AWakeLock() :
34*ec779b8eSAndroid Build Coastguard Worker mPowerManager(NULL),
35*ec779b8eSAndroid Build Coastguard Worker mWakeLockToken(NULL),
36*ec779b8eSAndroid Build Coastguard Worker mWakeLockCount(0),
37*ec779b8eSAndroid Build Coastguard Worker mDeathRecipient(new PMDeathRecipient(this)){}
38*ec779b8eSAndroid Build Coastguard Worker
~AWakeLock()39*ec779b8eSAndroid Build Coastguard Worker AWakeLock::~AWakeLock() {
40*ec779b8eSAndroid Build Coastguard Worker if (mPowerManager != NULL) {
41*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = IInterface::asBinder(mPowerManager);
42*ec779b8eSAndroid Build Coastguard Worker binder->unlinkToDeath(mDeathRecipient);
43*ec779b8eSAndroid Build Coastguard Worker }
44*ec779b8eSAndroid Build Coastguard Worker clearPowerManager();
45*ec779b8eSAndroid Build Coastguard Worker }
46*ec779b8eSAndroid Build Coastguard Worker
acquire()47*ec779b8eSAndroid Build Coastguard Worker bool AWakeLock::acquire() {
48*ec779b8eSAndroid Build Coastguard Worker if (mWakeLockCount == 0) {
49*ec779b8eSAndroid Build Coastguard Worker CHECK(mWakeLockToken == NULL);
50*ec779b8eSAndroid Build Coastguard Worker if (mPowerManager == NULL) {
51*ec779b8eSAndroid Build Coastguard Worker // use checkService() to avoid blocking if power service is not up yet
52*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder =
53*ec779b8eSAndroid Build Coastguard Worker defaultServiceManager()->checkService(String16("power"));
54*ec779b8eSAndroid Build Coastguard Worker if (binder == NULL) {
55*ec779b8eSAndroid Build Coastguard Worker ALOGW("could not get the power manager service");
56*ec779b8eSAndroid Build Coastguard Worker } else {
57*ec779b8eSAndroid Build Coastguard Worker mPowerManager = interface_cast<os::IPowerManager>(binder);
58*ec779b8eSAndroid Build Coastguard Worker binder->linkToDeath(mDeathRecipient);
59*ec779b8eSAndroid Build Coastguard Worker }
60*ec779b8eSAndroid Build Coastguard Worker }
61*ec779b8eSAndroid Build Coastguard Worker if (mPowerManager != NULL) {
62*ec779b8eSAndroid Build Coastguard Worker sp<IBinder> binder = new BBinder();
63*ec779b8eSAndroid Build Coastguard Worker int64_t token = IPCThreadState::self()->clearCallingIdentity();
64*ec779b8eSAndroid Build Coastguard Worker binder::Status status = mPowerManager->acquireWakeLock(
65*ec779b8eSAndroid Build Coastguard Worker binder,
66*ec779b8eSAndroid Build Coastguard Worker /*flags= */ POWERMANAGER_PARTIAL_WAKE_LOCK,
67*ec779b8eSAndroid Build Coastguard Worker /*tag=*/ String16("AWakeLock"),
68*ec779b8eSAndroid Build Coastguard Worker /*packageName=*/ String16("media"),
69*ec779b8eSAndroid Build Coastguard Worker /*ws=*/ {},
70*ec779b8eSAndroid Build Coastguard Worker /*historyTag=*/ {},
71*ec779b8eSAndroid Build Coastguard Worker /*displayId=*/ INVALID_DISPLAY_ID,
72*ec779b8eSAndroid Build Coastguard Worker /*callback=*/NULL);
73*ec779b8eSAndroid Build Coastguard Worker IPCThreadState::self()->restoreCallingIdentity(token);
74*ec779b8eSAndroid Build Coastguard Worker if (status.isOk()) {
75*ec779b8eSAndroid Build Coastguard Worker mWakeLockToken = binder;
76*ec779b8eSAndroid Build Coastguard Worker mWakeLockCount++;
77*ec779b8eSAndroid Build Coastguard Worker ALOGI("AwakeLock acquired");
78*ec779b8eSAndroid Build Coastguard Worker return true;
79*ec779b8eSAndroid Build Coastguard Worker }
80*ec779b8eSAndroid Build Coastguard Worker }
81*ec779b8eSAndroid Build Coastguard Worker } else {
82*ec779b8eSAndroid Build Coastguard Worker mWakeLockCount++;
83*ec779b8eSAndroid Build Coastguard Worker return true;
84*ec779b8eSAndroid Build Coastguard Worker }
85*ec779b8eSAndroid Build Coastguard Worker return false;
86*ec779b8eSAndroid Build Coastguard Worker }
87*ec779b8eSAndroid Build Coastguard Worker
release(bool force)88*ec779b8eSAndroid Build Coastguard Worker void AWakeLock::release(bool force) {
89*ec779b8eSAndroid Build Coastguard Worker if (mWakeLockCount == 0) {
90*ec779b8eSAndroid Build Coastguard Worker return;
91*ec779b8eSAndroid Build Coastguard Worker }
92*ec779b8eSAndroid Build Coastguard Worker if (force) {
93*ec779b8eSAndroid Build Coastguard Worker // Force wakelock release below by setting reference count to 1.
94*ec779b8eSAndroid Build Coastguard Worker mWakeLockCount = 1;
95*ec779b8eSAndroid Build Coastguard Worker }
96*ec779b8eSAndroid Build Coastguard Worker if (--mWakeLockCount == 0) {
97*ec779b8eSAndroid Build Coastguard Worker CHECK(mWakeLockToken != NULL);
98*ec779b8eSAndroid Build Coastguard Worker if (mPowerManager != NULL) {
99*ec779b8eSAndroid Build Coastguard Worker int64_t token = IPCThreadState::self()->clearCallingIdentity();
100*ec779b8eSAndroid Build Coastguard Worker mPowerManager->releaseWakeLock(mWakeLockToken, 0 /* flags */);
101*ec779b8eSAndroid Build Coastguard Worker IPCThreadState::self()->restoreCallingIdentity(token);
102*ec779b8eSAndroid Build Coastguard Worker }
103*ec779b8eSAndroid Build Coastguard Worker mWakeLockToken.clear();
104*ec779b8eSAndroid Build Coastguard Worker ALOGI("AwakeLock released");
105*ec779b8eSAndroid Build Coastguard Worker }
106*ec779b8eSAndroid Build Coastguard Worker }
107*ec779b8eSAndroid Build Coastguard Worker
clearPowerManager()108*ec779b8eSAndroid Build Coastguard Worker void AWakeLock::clearPowerManager() {
109*ec779b8eSAndroid Build Coastguard Worker release(true);
110*ec779b8eSAndroid Build Coastguard Worker mPowerManager.clear();
111*ec779b8eSAndroid Build Coastguard Worker }
112*ec779b8eSAndroid Build Coastguard Worker
binderDied(const wp<IBinder> & who __unused)113*ec779b8eSAndroid Build Coastguard Worker void AWakeLock::PMDeathRecipient::binderDied(const wp<IBinder>& who __unused) {
114*ec779b8eSAndroid Build Coastguard Worker if (mWakeLock != NULL) {
115*ec779b8eSAndroid Build Coastguard Worker mWakeLock->clearPowerManager();
116*ec779b8eSAndroid Build Coastguard Worker }
117*ec779b8eSAndroid Build Coastguard Worker }
118*ec779b8eSAndroid Build Coastguard Worker
119*ec779b8eSAndroid Build Coastguard Worker } // namespace android
120