1 /*
2  * Copyright 2017 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 "JWakeLock"
19 #include <utils/Log.h>
20 
21 #include "JWakeLock.h"
22 
23 #include <media/stagefright/foundation/ADebug.h>
24 
25 namespace android {
26 
JWakeLock(const sp<JObjectHolder> & context)27 JWakeLock::JWakeLock(const sp<JObjectHolder> &context) :
28     mWakeLockCount(0),
29     mWakeLock(NULL),
30     mContext(context) {}
31 
~JWakeLock()32 JWakeLock::~JWakeLock() {
33     clearJavaWakeLock();
34 }
35 
acquire()36 bool JWakeLock::acquire() {
37     if (mWakeLockCount == 0) {
38         if (mWakeLock == NULL) {
39             JNIEnv *env = JavaVMHelper::getJNIEnv();
40             jclass jContextCls = env->FindClass("android/content/Context");
41             jclass jPowerManagerCls = env->FindClass("android/os/PowerManager");
42 
43             jmethodID jGetSystemService = env->GetMethodID(jContextCls,
44                     "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
45             jobject javaPowerManagerObj = env->CallObjectMethod(mContext->getJObject(),
46                     jGetSystemService, env->NewStringUTF("power"));
47 
48             jfieldID jPARTIAL_WAKE_LOCK = env->GetStaticFieldID(jPowerManagerCls,
49                     "PARTIAL_WAKE_LOCK", "I");
50             jint PARTIAL_WAKE_LOCK = env->GetStaticIntField(jPowerManagerCls, jPARTIAL_WAKE_LOCK);
51 
52             jmethodID jNewWakeLock = env->GetMethodID(jPowerManagerCls,
53                     "newWakeLock", "(ILjava/lang/String;)Landroid/os/PowerManager$WakeLock;");
54             jobject javaWakeLock = env->CallObjectMethod(javaPowerManagerObj,
55                     jNewWakeLock, PARTIAL_WAKE_LOCK, env->NewStringUTF("JWakeLock"));
56             mWakeLock = new JObjectHolder(javaWakeLock);
57             env->DeleteLocalRef(javaPowerManagerObj);
58             env->DeleteLocalRef(javaWakeLock);
59         }
60         if (mWakeLock != NULL) {
61             JNIEnv *env = JavaVMHelper::getJNIEnv();
62             jclass wakeLockCls = env->FindClass("android/os/PowerManager$WakeLock");
63             jmethodID jAcquire = env->GetMethodID(wakeLockCls, "acquire", "()V");
64             env->CallVoidMethod(mWakeLock->getJObject(), jAcquire);
65             mWakeLockCount++;
66             return true;
67         }
68     } else {
69         mWakeLockCount++;
70         return true;
71     }
72     return false;
73 }
74 
release(bool force)75 void JWakeLock::release(bool force) {
76     if (mWakeLockCount == 0) {
77         return;
78     }
79     if (force) {
80         // Force wakelock release below by setting reference count to 1.
81         mWakeLockCount = 1;
82     }
83     if (--mWakeLockCount == 0) {
84         if (mWakeLock != NULL) {
85             JNIEnv *env = JavaVMHelper::getJNIEnv();
86             jclass wakeLockCls = env->FindClass("android/os/PowerManager$WakeLock");
87             jmethodID jRelease = env->GetMethodID(wakeLockCls, "release", "()V");
88             env->CallVoidMethod(mWakeLock->getJObject(), jRelease);
89         }
90     }
91 }
92 
clearJavaWakeLock()93 void JWakeLock::clearJavaWakeLock() {
94     release(true);
95 }
96 
97 }  // namespace android
98