但是找不到 call 這個 function 的 java code.
找一下 c code,果然還有一堆,像:
./base/services/jni/com_android_server_PowerManagerService.cpp:40: jmethodID goToSleep;
./base/services/jni/com_android_server_PowerManagerService.cpp:104:void android_server_PowerManagerService_goToSleep(nsecs_t eventTime) {
./base/services/jni/com_android_server_PowerManagerService.cpp:108: env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.goToSleep,
./base/services/jni/com_android_server_PowerManagerService.cpp:110: checkAndClearExceptionFromCallback(env, "goToSleep");
./base/services/jni/com_android_server_PowerManagerService.cpp:167: GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, gPowerManagerServiceClassInfo.clazz,
./base/services/jni/com_android_server_PowerManagerService.cpp:168: "goToSleep", "(J)V");
./base/services/jni/com_android_server_PowerManagerService.h:30:extern void android_server_PowerManagerService_goToSleep(nsecs_t eventTime);
./base/services/jni/com_android_server_InputManager.cpp:899: android_server_PowerManagerService_goToSleep(when);
最後 com_android_server_InputManager.cpp 可能就是處理的地方 (因為 power button 被 implement 成一個 key)
這個 code 是..
void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
int32_t deviceId, int32_t action, int32_t &flags,
int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
...
...
if (wmActions & WM_ACTION_GO_TO_SLEEP) {
android_server_PowerManagerService_goToSleep(when);
}
...
所以找賦予 wmAction WM_ACTION_GO_TO_SLEEP 值的 code..
這個 const WM_ACTION_GO_TO_SLEEP 的定義有點糟,jni 和 java 都要定義一次,而且要確保一樣:
./base/core/java/android/view/WindowManagerPolicy.java:106: public final static int ACTION_GO_TO_SLEEP = 0x00000004;
..
./base/services/jni/com_android_server_InputManager.cpp:873: const int32_t WM_ACTION_GO_TO_SLEEP = 4;
到這邊就有點麻煩..
上面 com_android_server_InputManager.cpp 的 interceptKeyBeforeQueueing( ) 中,先去 call java :
JNIEnv* env = jniEnv();
jint wmActions = env->CallIntMethod(mCallbacksObj,
gCallbacksClassInfo.interceptKeyBeforeQueueing,
when, action, flags, keyCode, scanCode, policyFlags, isScreenOn);
這段code的 interceptKeyBeforeQueueing 是..FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks"); GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz, "interceptKeyBeforeQueueing", "(JIIIIIZ)I");
是 InputManager.java 的 interceptKeyBeforeQueuing