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 <android/hardware/power/1.1/IPower.h>
22 #include <android/hardware/power/Boost.h>
23 #include <android/hardware/power/IPower.h>
24 #include <android/hardware/power/Mode.h>
25 #include <android/system/suspend/1.0/ISystemSuspend.h>
26 #include <android/system/suspend/ISuspendControlService.h>
27 #include <nativehelper/JNIHelp.h>
28 #include "jni.h"
29 
30 #include <nativehelper/ScopedUtfChars.h>
31 
32 #include <limits.h>
33 
34 #include <android-base/chrono_utils.h>
35 #include <android_runtime/AndroidRuntime.h>
36 #include <android_runtime/Log.h>
37 #include <binder/IServiceManager.h>
38 #include <gui/SurfaceComposerClient.h>
39 #include <hardware/power.h>
40 #include <hardware_legacy/power.h>
41 #include <hidl/ServiceManagement.h>
42 #include <utils/Timers.h>
43 #include <utils/misc.h>
44 #include <utils/String8.h>
45 #include <utils/Log.h>
46 
47 #include "com_android_server_power_PowerManagerService.h"
48 
49 using android::hardware::Return;
50 using android::hardware::Void;
51 using android::hardware::power::Boost;
52 using android::hardware::power::Mode;
53 using android::hardware::power::V1_0::PowerHint;
54 using android::hardware::power::V1_0::Feature;
55 using android::String8;
56 using android::system::suspend::V1_0::ISystemSuspend;
57 using android::system::suspend::V1_0::IWakeLock;
58 using android::system::suspend::V1_0::WakeLockType;
59 using android::system::suspend::ISuspendControlService;
60 using IPowerV1_1 = android::hardware::power::V1_1::IPower;
61 using IPowerV1_0 = android::hardware::power::V1_0::IPower;
62 using IPowerAidl = android::hardware::power::IPower;
63 
64 namespace android {
65 
66 // ----------------------------------------------------------------------------
67 
68 static struct {
69     jmethodID userActivityFromNative;
70 } gPowerManagerServiceClassInfo;
71 
72 // ----------------------------------------------------------------------------
73 
74 static jobject gPowerManagerServiceObj;
75 static sp<IPowerV1_0> gPowerHalHidlV1_0_ = nullptr;
76 static sp<IPowerV1_1> gPowerHalHidlV1_1_ = nullptr;
77 static sp<IPowerAidl> gPowerHalAidl_ = nullptr;
78 static std::mutex gPowerHalMutex;
79 
80 enum class HalVersion {
81     NONE,
82     HIDL_1_0,
83     HIDL_1_1,
84     AIDL,
85 };
86 
87 static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];
88 
89 // Throttling interval for user activity calls.
90 static const nsecs_t MIN_TIME_BETWEEN_USERACTIVITIES = 100 * 1000000L; // 100ms
91 
92 // ----------------------------------------------------------------------------
93 
checkAndClearExceptionFromCallback(JNIEnv * env,const char * methodName)94 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
95     if (env->ExceptionCheck()) {
96         ALOGE("An exception was thrown by callback '%s'.", methodName);
97         LOGE_EX(env);
98         env->ExceptionClear();
99         return true;
100     }
101     return false;
102 }
103 
104 // Check validity of current handle to the power HAL service, and connect to it if necessary.
105 // The caller must be holding gPowerHalMutex.
connectPowerHalLocked()106 static HalVersion connectPowerHalLocked() {
107     static bool gPowerHalHidlExists = true;
108     static bool gPowerHalAidlExists = true;
109     if (!gPowerHalHidlExists && !gPowerHalAidlExists) {
110         return HalVersion::NONE;
111     }
112     if (gPowerHalAidlExists) {
113         if (!gPowerHalAidl_) {
114             gPowerHalAidl_ = waitForVintfService<IPowerAidl>();
115         }
116         if (gPowerHalAidl_) {
117             ALOGV("Successfully connected to Power HAL AIDL service.");
118             return HalVersion::AIDL;
119         } else {
120             gPowerHalAidlExists = false;
121         }
122     }
123     if (gPowerHalHidlExists && gPowerHalHidlV1_0_ == nullptr) {
124         gPowerHalHidlV1_0_ = IPowerV1_0::getService();
125         if (gPowerHalHidlV1_0_) {
126             ALOGV("Successfully connected to Power HAL HIDL 1.0 service.");
127             // Try cast to powerHAL HIDL V1_1
128             gPowerHalHidlV1_1_ = IPowerV1_1::castFrom(gPowerHalHidlV1_0_);
129             if (gPowerHalHidlV1_1_) {
130                 ALOGV("Successfully connected to Power HAL HIDL 1.1 service.");
131             }
132         } else {
133             ALOGV("Couldn't load power HAL HIDL service");
134             gPowerHalHidlExists = false;
135             return HalVersion::NONE;
136         }
137     }
138     if (gPowerHalHidlV1_1_) {
139         return HalVersion::HIDL_1_1;
140     } else if (gPowerHalHidlV1_0_) {
141         return HalVersion::HIDL_1_0;
142     }
143     return HalVersion::NONE;
144 }
145 
146 // Retrieve a copy of PowerHAL HIDL V1_0
getPowerHalHidlV1_0()147 sp<IPowerV1_0> getPowerHalHidlV1_0() {
148     std::lock_guard<std::mutex> lock(gPowerHalMutex);
149     HalVersion halVersion = connectPowerHalLocked();
150     if (halVersion == HalVersion::HIDL_1_0 || halVersion == HalVersion::HIDL_1_1) {
151         return gPowerHalHidlV1_0_;
152     }
153 
154     return nullptr;
155 }
156 
157 // Retrieve a copy of PowerHAL HIDL V1_1
getPowerHalHidlV1_1()158 sp<IPowerV1_1> getPowerHalHidlV1_1() {
159     std::lock_guard<std::mutex> lock(gPowerHalMutex);
160     if (connectPowerHalLocked() == HalVersion::HIDL_1_1) {
161         return gPowerHalHidlV1_1_;
162     }
163 
164     return nullptr;
165 }
166 
167 // Check if a call to a power HAL function failed; if so, log the failure and invalidate the
168 // current handle to the power HAL service.
processPowerHalReturn(bool isOk,const char * functionName)169 bool processPowerHalReturn(bool isOk, const char* functionName) {
170     if (!isOk) {
171         ALOGE("%s() failed: power HAL service not available.", functionName);
172         gPowerHalMutex.lock();
173         gPowerHalHidlV1_0_ = nullptr;
174         gPowerHalHidlV1_1_ = nullptr;
175         gPowerHalAidl_ = nullptr;
176         gPowerHalMutex.unlock();
177     }
178     return isOk;
179 }
180 
181 enum class HalSupport {
182     UNKNOWN = 0,
183     ON,
184     OFF,
185 };
186 
setPowerBoostWithHandle(sp<IPowerAidl> handle,Boost boost,int32_t durationMs)187 static void setPowerBoostWithHandle(sp<IPowerAidl> handle, Boost boost, int32_t durationMs) {
188     // Android framework only sends boost upto DISPLAY_UPDATE_IMMINENT.
189     // Need to increase the array size if more boost supported.
190     static std::array<std::atomic<HalSupport>,
191                       static_cast<int32_t>(Boost::DISPLAY_UPDATE_IMMINENT) + 1>
192             boostSupportedArray = {HalSupport::UNKNOWN};
193 
194     // Quick return if boost is not supported by HAL
195     if (boost > Boost::DISPLAY_UPDATE_IMMINENT ||
196         boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::OFF) {
197         ALOGV("Skipped setPowerBoost %s because HAL doesn't support it", toString(boost).c_str());
198         return;
199     }
200 
201     if (boostSupportedArray[static_cast<int32_t>(boost)] == HalSupport::UNKNOWN) {
202         bool isSupported = false;
203         handle->isBoostSupported(boost, &isSupported);
204         boostSupportedArray[static_cast<int32_t>(boost)] =
205             isSupported ? HalSupport::ON : HalSupport::OFF;
206         if (!isSupported) {
207             ALOGV("Skipped setPowerBoost %s because HAL doesn't support it",
208                   toString(boost).c_str());
209             return;
210         }
211     }
212 
213     auto ret = handle->setBoost(boost, durationMs);
214     processPowerHalReturn(ret.isOk(), "setPowerBoost");
215 }
216 
setPowerBoost(Boost boost,int32_t durationMs)217 static void setPowerBoost(Boost boost, int32_t durationMs) {
218     std::unique_lock<std::mutex> lock(gPowerHalMutex);
219     if (connectPowerHalLocked() != HalVersion::AIDL) {
220         ALOGV("Power HAL AIDL not available");
221         return;
222     }
223     sp<IPowerAidl> handle = gPowerHalAidl_;
224     lock.unlock();
225     setPowerBoostWithHandle(handle, boost, durationMs);
226 }
227 
setPowerModeWithHandle(sp<IPowerAidl> handle,Mode mode,bool enabled)228 static bool setPowerModeWithHandle(sp<IPowerAidl> handle, Mode mode, bool enabled) {
229     // Android framework only sends mode upto DISPLAY_INACTIVE.
230     // Need to increase the array if more mode supported.
231     static std::array<std::atomic<HalSupport>, static_cast<int32_t>(Mode::DISPLAY_INACTIVE) + 1>
232             modeSupportedArray = {HalSupport::UNKNOWN};
233 
234     // Quick return if mode is not supported by HAL
235     if (mode > Mode::DISPLAY_INACTIVE ||
236         modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::OFF) {
237         ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
238         return false;
239     }
240 
241     if (modeSupportedArray[static_cast<int32_t>(mode)] == HalSupport::UNKNOWN) {
242         bool isSupported = false;
243         handle->isModeSupported(mode, &isSupported);
244         modeSupportedArray[static_cast<int32_t>(mode)] =
245             isSupported ? HalSupport::ON : HalSupport::OFF;
246         if (!isSupported) {
247             ALOGV("Skipped setPowerMode %s because HAL doesn't support it", toString(mode).c_str());
248             return false;
249         }
250     }
251 
252     auto ret = handle->setMode(mode, enabled);
253     processPowerHalReturn(ret.isOk(), "setPowerMode");
254     return ret.isOk();
255 }
256 
setPowerMode(Mode mode,bool enabled)257 static bool setPowerMode(Mode mode, bool enabled) {
258     std::unique_lock<std::mutex> lock(gPowerHalMutex);
259     if (connectPowerHalLocked() != HalVersion::AIDL) {
260         ALOGV("Power HAL AIDL not available");
261         return false;
262     }
263     sp<IPowerAidl> handle = gPowerHalAidl_;
264     lock.unlock();
265     return setPowerModeWithHandle(handle, mode, enabled);
266 }
267 
sendPowerHint(PowerHint hintId,uint32_t data)268 static void sendPowerHint(PowerHint hintId, uint32_t data) {
269     std::unique_lock<std::mutex> lock(gPowerHalMutex);
270     switch (connectPowerHalLocked()) {
271         case HalVersion::NONE:
272             return;
273         case HalVersion::HIDL_1_0: {
274             sp<IPowerV1_0> handle = gPowerHalHidlV1_0_;
275             lock.unlock();
276             auto ret = handle->powerHint(hintId, data);
277             processPowerHalReturn(ret.isOk(), "powerHint");
278             break;
279         }
280         case HalVersion::HIDL_1_1: {
281             sp<IPowerV1_1> handle = gPowerHalHidlV1_1_;
282             lock.unlock();
283             auto ret = handle->powerHintAsync(hintId, data);
284             processPowerHalReturn(ret.isOk(), "powerHintAsync");
285             break;
286         }
287         case HalVersion::AIDL: {
288             if (hintId == PowerHint::INTERACTION) {
289                 sp<IPowerAidl> handle = gPowerHalAidl_;
290                 lock.unlock();
291                 setPowerBoostWithHandle(handle, Boost::INTERACTION, data);
292                 break;
293             } else if (hintId == PowerHint::LAUNCH) {
294                 sp<IPowerAidl> handle = gPowerHalAidl_;
295                 lock.unlock();
296                 setPowerModeWithHandle(handle, Mode::LAUNCH, static_cast<bool>(data));
297                 break;
298             } else if (hintId == PowerHint::LOW_POWER) {
299                 sp<IPowerAidl> handle = gPowerHalAidl_;
300                 lock.unlock();
301                 setPowerModeWithHandle(handle, Mode::LOW_POWER, static_cast<bool>(data));
302                 break;
303             } else if (hintId == PowerHint::SUSTAINED_PERFORMANCE) {
304                 sp<IPowerAidl> handle = gPowerHalAidl_;
305                 lock.unlock();
306                 setPowerModeWithHandle(handle, Mode::SUSTAINED_PERFORMANCE,
307                                        static_cast<bool>(data));
308                 break;
309             } else if (hintId == PowerHint::VR_MODE) {
310                 sp<IPowerAidl> handle = gPowerHalAidl_;
311                 lock.unlock();
312                 setPowerModeWithHandle(handle, Mode::VR, static_cast<bool>(data));
313                 break;
314             } else {
315                 ALOGE("Unsupported power hint: %s.", toString(hintId).c_str());
316                 return;
317             }
318         }
319         default: {
320             ALOGE("Unknown power HAL state");
321             return;
322         }
323     }
324     SurfaceComposerClient::notifyPowerHint(static_cast<int32_t>(hintId));
325 }
326 
android_server_PowerManagerService_userActivity(nsecs_t eventTime,int32_t eventType)327 void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
328     if (gPowerManagerServiceObj) {
329         // Throttle calls into user activity by event type.
330         // We're a little conservative about argument checking here in case the caller
331         // passes in bad data which could corrupt system state.
332         if (eventType >= 0 && eventType <= USER_ACTIVITY_EVENT_LAST) {
333             nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
334             if (eventTime > now) {
335                 eventTime = now;
336             }
337 
338             if (gLastEventTime[eventType] + MIN_TIME_BETWEEN_USERACTIVITIES > eventTime) {
339                 return;
340             }
341             gLastEventTime[eventType] = eventTime;
342 
343             // Tell the power HAL when user activity occurs.
344             sendPowerHint(PowerHint::INTERACTION, 0);
345         }
346 
347         JNIEnv* env = AndroidRuntime::getJNIEnv();
348 
349         env->CallVoidMethod(gPowerManagerServiceObj,
350                 gPowerManagerServiceClassInfo.userActivityFromNative,
351                 nanoseconds_to_milliseconds(eventTime), eventType, 0);
352         checkAndClearExceptionFromCallback(env, "userActivityFromNative");
353     }
354 }
355 
356 static sp<ISystemSuspend> gSuspendHal = nullptr;
357 static sp<ISuspendControlService> gSuspendControl = nullptr;
358 static sp<IWakeLock> gSuspendBlocker = nullptr;
359 static std::mutex gSuspendMutex;
360 
361 // Assume SystemSuspend HAL is always alive.
362 // TODO: Force device to restart if SystemSuspend HAL dies.
getSuspendHal()363 sp<ISystemSuspend> getSuspendHal() {
364     static std::once_flag suspendHalFlag;
365     std::call_once(suspendHalFlag, [](){
366         ::android::hardware::details::waitForHwService(ISystemSuspend::descriptor, "default");
367         gSuspendHal = ISystemSuspend::getService();
368         assert(gSuspendHal != nullptr);
369     });
370     return gSuspendHal;
371 }
372 
getSuspendControl()373 sp<ISuspendControlService> getSuspendControl() {
374     static std::once_flag suspendControlFlag;
375     std::call_once(suspendControlFlag, [](){
376         gSuspendControl = waitForService<ISuspendControlService>(String16("suspend_control"));
377         LOG_ALWAYS_FATAL_IF(gSuspendControl == nullptr);
378     });
379     return gSuspendControl;
380 }
381 
enableAutoSuspend()382 void enableAutoSuspend() {
383     static bool enabled = false;
384     if (!enabled) {
385         sp<ISuspendControlService> suspendControl = getSuspendControl();
386         suspendControl->enableAutosuspend(&enabled);
387     }
388 
389     {
390         std::lock_guard<std::mutex> lock(gSuspendMutex);
391         if (gSuspendBlocker) {
392             gSuspendBlocker->release();
393             gSuspendBlocker.clear();
394         }
395     }
396 }
397 
disableAutoSuspend()398 void disableAutoSuspend() {
399     std::lock_guard<std::mutex> lock(gSuspendMutex);
400     if (!gSuspendBlocker) {
401         sp<ISystemSuspend> suspendHal = getSuspendHal();
402         gSuspendBlocker = suspendHal->acquireWakeLock(WakeLockType::PARTIAL,
403                 "PowerManager.SuspendLockout");
404     }
405 }
406 
407 // ----------------------------------------------------------------------------
408 
nativeInit(JNIEnv * env,jobject obj)409 static void nativeInit(JNIEnv* env, jobject obj) {
410     gPowerManagerServiceObj = env->NewGlobalRef(obj);
411 
412     gPowerHalMutex.lock();
413     connectPowerHalLocked();
414     gPowerHalMutex.unlock();
415 }
416 
nativeAcquireSuspendBlocker(JNIEnv * env,jclass,jstring nameStr)417 static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
418     ScopedUtfChars name(env, nameStr);
419     acquire_wake_lock(PARTIAL_WAKE_LOCK, name.c_str());
420 }
421 
nativeReleaseSuspendBlocker(JNIEnv * env,jclass,jstring nameStr)422 static void nativeReleaseSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
423     ScopedUtfChars name(env, nameStr);
424     release_wake_lock(name.c_str());
425 }
426 
nativeSetInteractive(JNIEnv *,jclass,jboolean enable)427 static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
428     std::unique_lock<std::mutex> lock(gPowerHalMutex);
429     switch (connectPowerHalLocked()) {
430         case HalVersion::NONE:
431             return;
432         case HalVersion::HIDL_1_0:
433             FALLTHROUGH_INTENDED;
434         case HalVersion::HIDL_1_1: {
435             android::base::Timer t;
436             sp<IPowerV1_0> handle = gPowerHalHidlV1_0_;
437             lock.unlock();
438             auto ret = handle->setInteractive(enable);
439             processPowerHalReturn(ret.isOk(), "setInteractive");
440             if (t.duration() > 20ms) {
441                 ALOGD("Excessive delay in setInteractive(%s) while turning screen %s",
442                       enable ? "true" : "false", enable ? "on" : "off");
443             }
444             return;
445         }
446         case HalVersion::AIDL: {
447             sp<IPowerAidl> handle = gPowerHalAidl_;
448             lock.unlock();
449             setPowerModeWithHandle(handle, Mode::INTERACTIVE, enable);
450             return;
451         }
452         default: {
453             ALOGE("Unknown power HAL state");
454             return;
455         }
456     }
457 }
458 
nativeSetAutoSuspend(JNIEnv *,jclass,jboolean enable)459 static void nativeSetAutoSuspend(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
460     if (enable) {
461         android::base::Timer t;
462         enableAutoSuspend();
463         if (t.duration() > 100ms) {
464             ALOGD("Excessive delay in autosuspend_enable() while turning screen off");
465         }
466     } else {
467         android::base::Timer t;
468         disableAutoSuspend();
469         if (t.duration() > 100ms) {
470             ALOGD("Excessive delay in autosuspend_disable() while turning screen on");
471         }
472     }
473 }
474 
nativeSendPowerHint(JNIEnv *,jclass,jint hintId,jint data)475 static void nativeSendPowerHint(JNIEnv* /* env */, jclass /* clazz */, jint hintId, jint data) {
476     sendPowerHint(static_cast<PowerHint>(hintId), data);
477 }
478 
nativeSetPowerBoost(JNIEnv *,jclass,jint boost,jint durationMs)479 static void nativeSetPowerBoost(JNIEnv* /* env */, jclass /* clazz */, jint boost,
480                                 jint durationMs) {
481     setPowerBoost(static_cast<Boost>(boost), durationMs);
482 }
483 
nativeSetPowerMode(JNIEnv *,jclass,jint mode,jboolean enabled)484 static jboolean nativeSetPowerMode(JNIEnv* /* env */, jclass /* clazz */, jint mode,
485                                    jboolean enabled) {
486     return setPowerMode(static_cast<Mode>(mode), enabled);
487 }
488 
nativeSetFeature(JNIEnv *,jclass,jint featureId,jint data)489 static void nativeSetFeature(JNIEnv* /* env */, jclass /* clazz */, jint featureId, jint data) {
490     std::unique_lock<std::mutex> lock(gPowerHalMutex);
491     switch (connectPowerHalLocked()) {
492         case HalVersion::NONE:
493             return;
494         case HalVersion::HIDL_1_0:
495             FALLTHROUGH_INTENDED;
496         case HalVersion::HIDL_1_1: {
497             sp<IPowerV1_0> handle = gPowerHalHidlV1_0_;
498             lock.unlock();
499             auto ret = handle->setFeature(static_cast<Feature>(featureId), static_cast<bool>(data));
500             processPowerHalReturn(ret.isOk(), "setFeature");
501             return;
502         }
503         case HalVersion::AIDL: {
504             sp<IPowerAidl> handle = gPowerHalAidl_;
505             lock.unlock();
506             setPowerModeWithHandle(handle, Mode::DOUBLE_TAP_TO_WAKE, static_cast<bool>(data));
507             return;
508         }
509         default: {
510             ALOGE("Unknown power HAL state");
511             return;
512         }
513     }
514 }
515 
nativeForceSuspend(JNIEnv *,jclass)516 static bool nativeForceSuspend(JNIEnv* /* env */, jclass /* clazz */) {
517     bool retval = false;
518     getSuspendControl()->forceSuspend(&retval);
519     return retval;
520 }
521 
522 // ----------------------------------------------------------------------------
523 
524 static const JNINativeMethod gPowerManagerServiceMethods[] = {
525         /* name, signature, funcPtr */
526         {"nativeInit", "()V", (void*)nativeInit},
527         {"nativeAcquireSuspendBlocker", "(Ljava/lang/String;)V",
528          (void*)nativeAcquireSuspendBlocker},
529         {"nativeForceSuspend", "()Z", (void*)nativeForceSuspend},
530         {"nativeReleaseSuspendBlocker", "(Ljava/lang/String;)V",
531          (void*)nativeReleaseSuspendBlocker},
532         {"nativeSetInteractive", "(Z)V", (void*)nativeSetInteractive},
533         {"nativeSetAutoSuspend", "(Z)V", (void*)nativeSetAutoSuspend},
534         {"nativeSendPowerHint", "(II)V", (void*)nativeSendPowerHint},
535         {"nativeSetPowerBoost", "(II)V", (void*)nativeSetPowerBoost},
536         {"nativeSetPowerMode", "(IZ)Z", (void*)nativeSetPowerMode},
537         {"nativeSetFeature", "(II)V", (void*)nativeSetFeature},
538 };
539 
540 #define FIND_CLASS(var, className) \
541         var = env->FindClass(className); \
542         LOG_FATAL_IF(! (var), "Unable to find class " className);
543 
544 #define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
545         var = env->GetMethodID(clazz, methodName, methodDescriptor); \
546         LOG_FATAL_IF(! (var), "Unable to find method " methodName);
547 
548 #define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
549         var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
550         LOG_FATAL_IF(! (var), "Unable to find field " fieldName);
551 
register_android_server_PowerManagerService(JNIEnv * env)552 int register_android_server_PowerManagerService(JNIEnv* env) {
553     int res = jniRegisterNativeMethods(env, "com/android/server/power/PowerManagerService",
554             gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
555     (void) res;  // Faked use when LOG_NDEBUG.
556     LOG_FATAL_IF(res < 0, "Unable to register native methods.");
557 
558     // Callbacks
559 
560     jclass clazz;
561     FIND_CLASS(clazz, "com/android/server/power/PowerManagerService");
562 
563     GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivityFromNative, clazz,
564             "userActivityFromNative", "(JII)V");
565 
566     // Initialize
567     for (int i = 0; i <= USER_ACTIVITY_EVENT_LAST; i++) {
568         gLastEventTime[i] = LLONG_MIN;
569     }
570     gPowerManagerServiceObj = NULL;
571     return 0;
572 }
573 
574 } /* namespace android */
575