• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 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_TAG "PowerManagerService-JNI"
18 
19 //#define LOG_NDEBUG 0
20 
21 #include "JNIHelp.h"
22 #include "jni.h"
23 
24 #include <limits.h>
25 
26 #include <android_runtime/AndroidRuntime.h>
27 #include <utils/Timers.h>
28 #include <surfaceflinger/ISurfaceComposer.h>
29 #include <surfaceflinger/SurfaceComposerClient.h>
30 
31 #include "com_android_server_PowerManagerService.h"
32 
33 namespace android {
34 
35 // ----------------------------------------------------------------------------
36 
37 static struct {
38     jclass clazz;
39 
40     jmethodID goToSleep;
41     jmethodID userActivity;
42 } gPowerManagerServiceClassInfo;
43 
44 // ----------------------------------------------------------------------------
45 
46 static jobject gPowerManagerServiceObj;
47 
48 static Mutex gPowerManagerLock;
49 static bool gScreenOn;
50 static bool gScreenBright;
51 
52 static nsecs_t gLastEventTime[POWER_MANAGER_LAST_EVENT + 1];
53 
54 // Throttling interval for user activity calls.
55 static const nsecs_t MIN_TIME_BETWEEN_USERACTIVITIES = 500 * 1000000L; // 500ms
56 
57 // ----------------------------------------------------------------------------
58 
checkAndClearExceptionFromCallback(JNIEnv * env,const char * methodName)59 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
60     if (env->ExceptionCheck()) {
61         LOGE("An exception was thrown by callback '%s'.", methodName);
62         LOGE_EX(env);
63         env->ExceptionClear();
64         return true;
65     }
66     return false;
67 }
68 
android_server_PowerManagerService_isScreenOn()69 bool android_server_PowerManagerService_isScreenOn() {
70     AutoMutex _l(gPowerManagerLock);
71     return gScreenOn;
72 }
73 
android_server_PowerManagerService_isScreenBright()74 bool android_server_PowerManagerService_isScreenBright() {
75     AutoMutex _l(gPowerManagerLock);
76     return gScreenBright;
77 }
78 
android_server_PowerManagerService_userActivity(nsecs_t eventTime,int32_t eventType)79 void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
80     if (gPowerManagerServiceObj) {
81         // Throttle calls into user activity by event type.
82         // We're a little conservative about argument checking here in case the caller
83         // passes in bad data which could corrupt system state.
84         if (eventType >= 0 && eventType <= POWER_MANAGER_LAST_EVENT) {
85             nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
86             if (eventTime > now) {
87                 eventTime = now;
88             }
89 
90             if (gLastEventTime[eventType] + MIN_TIME_BETWEEN_USERACTIVITIES > eventTime) {
91                 return;
92             }
93             gLastEventTime[eventType] = eventTime;
94         }
95 
96         JNIEnv* env = AndroidRuntime::getJNIEnv();
97 
98         env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.userActivity,
99                 nanoseconds_to_milliseconds(eventTime), false, eventType, false);
100         checkAndClearExceptionFromCallback(env, "userActivity");
101     }
102 }
103 
android_server_PowerManagerService_goToSleep(nsecs_t eventTime)104 void android_server_PowerManagerService_goToSleep(nsecs_t eventTime) {
105     if (gPowerManagerServiceObj) {
106         JNIEnv* env = AndroidRuntime::getJNIEnv();
107 
108         env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.goToSleep,
109                 nanoseconds_to_milliseconds(eventTime));
110         checkAndClearExceptionFromCallback(env, "goToSleep");
111     }
112 }
113 
114 // ----------------------------------------------------------------------------
115 
android_server_PowerManagerService_nativeInit(JNIEnv * env,jobject obj)116 static void android_server_PowerManagerService_nativeInit(JNIEnv* env, jobject obj) {
117     gPowerManagerServiceObj = env->NewGlobalRef(obj);
118 }
119 
android_server_PowerManagerService_nativeSetPowerState(JNIEnv * env,jobject serviceObj,jboolean screenOn,jboolean screenBright)120 static void android_server_PowerManagerService_nativeSetPowerState(JNIEnv* env,
121         jobject serviceObj, jboolean screenOn, jboolean screenBright) {
122     AutoMutex _l(gPowerManagerLock);
123     gScreenOn = screenOn;
124     gScreenBright = screenBright;
125 }
126 
android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation(JNIEnv * env,jobject obj,jint mode)127 static void android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation(JNIEnv* env,
128         jobject obj, jint mode) {
129     sp<ISurfaceComposer> s(ComposerService::getComposerService());
130     s->turnElectronBeamOff(mode);
131 }
132 
133 // ----------------------------------------------------------------------------
134 
135 static JNINativeMethod gPowerManagerServiceMethods[] = {
136     /* name, signature, funcPtr */
137     { "nativeInit", "()V",
138             (void*) android_server_PowerManagerService_nativeInit },
139     { "nativeSetPowerState", "(ZZ)V",
140             (void*) android_server_PowerManagerService_nativeSetPowerState },
141     { "nativeStartSurfaceFlingerAnimation", "(I)V",
142             (void*) android_server_PowerManagerService_nativeStartSurfaceFlingerAnimation },
143 };
144 
145 #define FIND_CLASS(var, className) \
146         var = env->FindClass(className); \
147         LOG_FATAL_IF(! var, "Unable to find class " className); \
148         var = jclass(env->NewGlobalRef(var));
149 
150 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
151         var = env->GetMethodID(clazz, methodName, methodDescriptor); \
152         LOG_FATAL_IF(! var, "Unable to find method " methodName);
153 
154 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
155         var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
156         LOG_FATAL_IF(! var, "Unable to find field " fieldName);
157 
register_android_server_PowerManagerService(JNIEnv * env)158 int register_android_server_PowerManagerService(JNIEnv* env) {
159     int res = jniRegisterNativeMethods(env, "com/android/server/PowerManagerService",
160             gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
161     LOG_FATAL_IF(res < 0, "Unable to register native methods.");
162 
163     // Callbacks
164 
165     FIND_CLASS(gPowerManagerServiceClassInfo.clazz, "com/android/server/PowerManagerService");
166 
167     GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, gPowerManagerServiceClassInfo.clazz,
168             "goToSleep", "(J)V");
169 
170     GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivity, gPowerManagerServiceClassInfo.clazz,
171             "userActivity", "(JZIZ)V");
172 
173     // Initialize
174     for (int i = 0; i < POWER_MANAGER_LAST_EVENT; i++) {
175         gLastEventTime[i] = LLONG_MIN;
176     }
177     gScreenOn = true;
178     gScreenBright = true;
179     return 0;
180 }
181 
182 } /* namespace android */
183