diff options
author | Jeff Brown <jeffbrown@google.com> | 2010-07-02 15:37:36 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2010-07-03 19:23:01 -0700 |
commit | 00fa7bdd69f0868fd17ea7c881c771d785b2fbbd (patch) | |
tree | 6fff8ad404e57af316c6ce5a20020dc209eb3cc6 /services/jni | |
parent | 8ecfb60a8e74dfcd51bbf3f236d5f414a4d5ac7d (diff) | |
download | frameworks_base-00fa7bdd69f0868fd17ea7c881c771d785b2fbbd.zip frameworks_base-00fa7bdd69f0868fd17ea7c881c771d785b2fbbd.tar.gz frameworks_base-00fa7bdd69f0868fd17ea7c881c771d785b2fbbd.tar.bz2 |
More native input dispatch work.
Removed old input dispatch code.
Refactored the policy callbacks.
Pushed a tiny bit of the power manager state down to native.
Fixed long press on MENU.
Made the virtual key detection and cancelation a bit more precise.
Change-Id: I5d8c1062f7ea0ab3b54c6fadb058c4d5f5a9e02e
Diffstat (limited to 'services/jni')
-rw-r--r-- | services/jni/Android.mk | 2 | ||||
-rw-r--r-- | services/jni/com_android_server_InputManager.cpp | 164 | ||||
-rw-r--r-- | services/jni/com_android_server_KeyInputQueue.cpp | 358 | ||||
-rw-r--r-- | services/jni/com_android_server_PowerManagerService.cpp | 142 | ||||
-rw-r--r-- | services/jni/com_android_server_PowerManagerService.h | 42 | ||||
-rw-r--r-- | services/jni/onload.cpp | 4 |
6 files changed, 265 insertions, 447 deletions
diff --git a/services/jni/Android.mk b/services/jni/Android.mk index 499ca86..0cf36b3 100644 --- a/services/jni/Android.mk +++ b/services/jni/Android.mk @@ -4,9 +4,9 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ com_android_server_AlarmManagerService.cpp \ com_android_server_BatteryService.cpp \ - com_android_server_KeyInputQueue.cpp \ com_android_server_InputManager.cpp \ com_android_server_LightsService.cpp \ + com_android_server_PowerManagerService.cpp \ com_android_server_SensorService.cpp \ com_android_server_SystemServer.cpp \ com_android_server_VibratorService.cpp \ diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp index d0f856b..fc901f4 100644 --- a/services/jni/com_android_server_InputManager.cpp +++ b/services/jni/com_android_server_InputManager.cpp @@ -40,6 +40,7 @@ #include "../../core/jni/android_view_KeyEvent.h" #include "../../core/jni/android_view_MotionEvent.h" #include "../../core/jni/android_view_InputChannel.h" +#include "com_android_server_PowerManagerService.h" namespace android { @@ -107,16 +108,6 @@ enum { LAST_SYSTEM_WINDOW = 2999, }; -enum { - POWER_MANAGER_OTHER_EVENT = 0, - POWER_MANAGER_CHEEK_EVENT = 1, - POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either - // up events or LONG_TOUCH events. - POWER_MANAGER_LONG_TOUCH_EVENT = 3, - POWER_MANAGER_TOUCH_UP_EVENT = 4, - POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events. -}; - // Delay between reporting long touch events to the power manager. const nsecs_t EVENT_IGNORE_DURATION = 300 * 1000000LL; // 300 ms @@ -133,20 +124,16 @@ const nsecs_t MIN_INPUT_DISPATCHING_TIMEOUT = 1000 * 1000000LL; // 1 sec static struct { jclass clazz; - jmethodID isScreenOn; - jmethodID isScreenBright; jmethodID notifyConfigurationChanged; jmethodID notifyLidSwitchChanged; jmethodID notifyInputChannelBroken; jmethodID notifyInputChannelANR; jmethodID notifyInputChannelRecoveredFromANR; jmethodID notifyANR; - jmethodID virtualKeyFeedback; + jmethodID virtualKeyDownFeedback; jmethodID interceptKeyBeforeQueueing; jmethodID interceptKeyBeforeDispatching; jmethodID checkInjectEventsPermission; - jmethodID goToSleep; - jmethodID pokeUserActivity; jmethodID notifyAppSwitchComing; jmethodID filterTouchEvents; jmethodID filterJumpyTouchEvents; @@ -228,9 +215,7 @@ public: virtual bool getDisplayInfo(int32_t displayId, int32_t* width, int32_t* height, int32_t* orientation); - virtual void virtualKeyFeedback(nsecs_t when, int32_t deviceId, - int32_t action, int32_t flags, int32_t keyCode, - int32_t scanCode, int32_t metaState, nsecs_t downTime); + virtual void virtualKeyDownFeedback(); virtual int32_t interceptKey(nsecs_t when, int32_t deviceId, bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags); virtual int32_t interceptTrackball(nsecs_t when, bool buttonChanged, bool buttonDown, @@ -321,7 +306,7 @@ private: int32_t mDisplayWidth, mDisplayHeight; int32_t mDisplayOrientation; - // Callbacks. + // Power manager interactions. bool isScreenOn(); bool isScreenBright(); @@ -369,9 +354,9 @@ private: void releaseTouchedWindowLd(); - int32_t identifyTrackballEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, + int32_t waitForTrackballEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets); - int32_t identifyTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, + int32_t waitForTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets); bool interceptKeyBeforeDispatching(const InputTarget& target, @@ -391,6 +376,7 @@ private: } static bool isAppSwitchKey(int32_t keyCode); + static bool isPolicyKey(int32_t keyCode, bool isScreenOn); static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName); }; @@ -422,6 +408,36 @@ bool NativeInputManager::isAppSwitchKey(int32_t keyCode) { return keyCode == KEYCODE_HOME || keyCode == KEYCODE_ENDCALL; } +bool NativeInputManager::isPolicyKey(int32_t keyCode, bool isScreenOn) { + // Special keys that the WindowManagerPolicy might care about. + switch (keyCode) { + case KEYCODE_VOLUME_UP: + case KEYCODE_VOLUME_DOWN: + case KEYCODE_ENDCALL: + case KEYCODE_POWER: + case KEYCODE_CALL: + case KEYCODE_HOME: + case KEYCODE_MENU: + case KEYCODE_SEARCH: + // media keys + case KEYCODE_HEADSETHOOK: + case KEYCODE_MEDIA_PLAY_PAUSE: + case KEYCODE_MEDIA_STOP: + case KEYCODE_MEDIA_NEXT: + case KEYCODE_MEDIA_PREVIOUS: + case KEYCODE_MEDIA_REWIND: + case KEYCODE_MEDIA_FAST_FORWARD: + return true; + default: + // We need to pass all keys to the policy in the following cases: + // - screen is off + // - keyguard is visible + // - policy is performing key chording + //return ! isScreenOn || keyguardVisible || chording; + return true; // XXX stubbed out for now + } +} + bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { if (env->ExceptionCheck()) { LOGE("An exception was thrown by callback '%s'.", methodName); @@ -546,39 +562,22 @@ bool NativeInputManager::getDisplayInfo(int32_t displayId, } bool NativeInputManager::isScreenOn() { - JNIEnv* env = jniEnv(); - - jboolean result = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.isScreenOn); - if (checkAndClearExceptionFromCallback(env, "isScreenOn")) { - return true; - } - return result; + return android_server_PowerManagerService_isScreenOn(); } bool NativeInputManager::isScreenBright() { - JNIEnv* env = jniEnv(); - - jboolean result = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.isScreenBright); - if (checkAndClearExceptionFromCallback(env, "isScreenBright")) { - return true; - } - return result; + return android_server_PowerManagerService_isScreenBright(); } -void NativeInputManager::virtualKeyFeedback(nsecs_t when, int32_t deviceId, - int32_t action, int32_t flags, int32_t keyCode, - int32_t scanCode, int32_t metaState, nsecs_t downTime) { +void NativeInputManager::virtualKeyDownFeedback() { #if DEBUG_INPUT_READER_POLICY - LOGD("virtualKeyFeedback - when=%lld, deviceId=%d, action=%d, flags=%d, keyCode=%d, " - "scanCode=%d, metaState=%d, downTime=%lld", - when, deviceId, action, flags, keyCode, scanCode, metaState, downTime); + LOGD("virtualKeyDownFeedback"); #endif JNIEnv* env = jniEnv(); - env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyFeedback, - when, deviceId, action, flags, keyCode, scanCode, metaState, downTime); - checkAndClearExceptionFromCallback(env, "virtualKeyFeedback"); + env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyDownFeedback); + checkAndClearExceptionFromCallback(env, "virtualKeyDownFeedback"); } int32_t NativeInputManager::interceptKey(nsecs_t when, @@ -593,16 +592,21 @@ int32_t NativeInputManager::interceptKey(nsecs_t when, const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2; const int32_t WM_ACTION_GO_TO_SLEEP = 4; - JNIEnv* env = jniEnv(); - bool isScreenOn = this->isScreenOn(); bool isScreenBright = this->isScreenBright(); - jint wmActions = env->CallIntMethod(mCallbacksObj, - gCallbacksClassInfo.interceptKeyBeforeQueueing, - deviceId, EV_KEY, scanCode, keyCode, policyFlags, down ? 1 : 0, when, isScreenOn); - if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) { - wmActions = 0; + jint wmActions = 0; + if (isPolicyKey(keyCode, isScreenOn)) { + JNIEnv* env = jniEnv(); + + wmActions = env->CallIntMethod(mCallbacksObj, + gCallbacksClassInfo.interceptKeyBeforeQueueing, + when, keyCode, down, policyFlags, isScreenOn); + if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) { + wmActions = 0; + } + } else { + wmActions = WM_ACTION_PASS_TO_USER; } int32_t actions = InputReaderPolicyInterface::ACTION_NONE; @@ -617,8 +621,7 @@ int32_t NativeInputManager::interceptKey(nsecs_t when, } if (wmActions & WM_ACTION_GO_TO_SLEEP) { - env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.goToSleep, when); - checkAndClearExceptionFromCallback(env, "goToSleep"); + android_server_PowerManagerService_goToSleep(when); } if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) { @@ -629,6 +632,8 @@ int32_t NativeInputManager::interceptKey(nsecs_t when, actions |= InputReaderPolicyInterface::ACTION_DISPATCH; if (down && isAppSwitchKey(keyCode)) { + JNIEnv* env = jniEnv(); + env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyAppSwitchComing); checkAndClearExceptionFromCallback(env, "notifyAppSwitchComing"); @@ -1531,11 +1536,13 @@ int32_t NativeInputManager::waitForKeyEventTargets(KeyEvent* keyEvent, uint32_t windowType = focusedWindow->layoutParamsType; } // release lock - const InputTarget& target = outTargets.top(); - bool consumed = interceptKeyBeforeDispatching(target, keyEvent, policyFlags); - if (consumed) { - outTargets.clear(); - return INPUT_EVENT_INJECTION_SUCCEEDED; + if (isPolicyKey(keyEvent->getKeyCode(), isScreenOn())) { + const InputTarget& target = outTargets.top(); + bool consumed = interceptKeyBeforeDispatching(target, keyEvent, policyFlags); + if (consumed) { + outTargets.clear(); + return INPUT_EVENT_INJECTION_SUCCEEDED; + } } pokeUserActivityIfNeeded(windowType, POWER_MANAGER_BUTTON_EVENT); @@ -1552,11 +1559,11 @@ int32_t NativeInputManager::waitForMotionEventTargets(MotionEvent* motionEvent, switch (motionEvent->getNature()) { case INPUT_EVENT_NATURE_TRACKBALL: - return identifyTrackballEventTargets(motionEvent, policyFlags, injectorPid, injectorUid, + return waitForTrackballEventTargets(motionEvent, policyFlags, injectorPid, injectorUid, outTargets); case INPUT_EVENT_NATURE_TOUCH: - return identifyTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid, + return waitForTouchEventTargets(motionEvent, policyFlags, injectorPid, injectorUid, outTargets); default: @@ -1565,11 +1572,11 @@ int32_t NativeInputManager::waitForMotionEventTargets(MotionEvent* motionEvent, } } -int32_t NativeInputManager::identifyTrackballEventTargets(MotionEvent* motionEvent, +int32_t NativeInputManager::waitForTrackballEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets) { #if DEBUG_INPUT_DISPATCHER_POLICY - LOGD("identifyTrackballEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d", + LOGD("waitForTrackballEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d", policyFlags, injectorPid, injectorUid); #endif @@ -1591,11 +1598,11 @@ int32_t NativeInputManager::identifyTrackballEventTargets(MotionEvent* motionEve return INPUT_EVENT_INJECTION_SUCCEEDED; } -int32_t NativeInputManager::identifyTouchEventTargets(MotionEvent* motionEvent, +int32_t NativeInputManager::waitForTouchEventTargets(MotionEvent* motionEvent, uint32_t policyFlags, int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets) { #if DEBUG_INPUT_DISPATCHER_POLICY - LOGD("identifyTouchEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d", + LOGD("waitForTouchEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d", policyFlags, injectorPid, injectorUid); #endif @@ -1642,8 +1649,8 @@ bool NativeInputManager::interceptKeyBeforeDispatching(const InputTarget& target if (inputChannelObj) { jboolean consumed = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.interceptKeyBeforeDispatching, - inputChannelObj, keyEvent->getKeyCode(), keyEvent->getMetaState(), - keyEvent->getAction() == KEY_EVENT_ACTION_DOWN, + inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(), + keyEvent->getKeyCode(), keyEvent->getMetaState(), keyEvent->getRepeatCount(), policyFlags); bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching"); @@ -1665,10 +1672,7 @@ void NativeInputManager::pokeUserActivityIfNeeded(int32_t windowType, int32_t ev } void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) { - JNIEnv* env = jniEnv(); - env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.pokeUserActivity, - eventTime, eventType); - checkAndClearExceptionFromCallback(env, "pokeUserActivity"); + android_server_PowerManagerService_userActivity(eventTime, eventType); } void NativeInputManager::dumpDispatchStateLd() { @@ -2082,12 +2086,6 @@ int register_android_server_InputManager(JNIEnv* env) { FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks"); - GET_METHOD_ID(gCallbacksClassInfo.isScreenOn, gCallbacksClassInfo.clazz, - "isScreenOn", "()Z"); - - GET_METHOD_ID(gCallbacksClassInfo.isScreenBright, gCallbacksClassInfo.clazz, - "isScreenBright", "()Z"); - GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz, "notifyConfigurationChanged", "(JIII)V"); @@ -2106,24 +2104,18 @@ int register_android_server_InputManager(JNIEnv* env) { GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz, "notifyANR", "(Ljava/lang/Object;)J"); - GET_METHOD_ID(gCallbacksClassInfo.virtualKeyFeedback, gCallbacksClassInfo.clazz, - "virtualKeyFeedback", "(JIIIIIIJ)V"); + GET_METHOD_ID(gCallbacksClassInfo.virtualKeyDownFeedback, gCallbacksClassInfo.clazz, + "virtualKeyDownFeedback", "()V"); GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz, - "interceptKeyBeforeQueueing", "(IIIIIIJZ)I"); + "interceptKeyBeforeQueueing", "(JIZIZ)I"); GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz, - "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIZII)Z"); + "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIIIII)Z"); GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz, "checkInjectEventsPermission", "(II)Z"); - GET_METHOD_ID(gCallbacksClassInfo.goToSleep, gCallbacksClassInfo.clazz, - "goToSleep", "(J)V"); - - GET_METHOD_ID(gCallbacksClassInfo.pokeUserActivity, gCallbacksClassInfo.clazz, - "pokeUserActivity", "(JI)V"); - GET_METHOD_ID(gCallbacksClassInfo.notifyAppSwitchComing, gCallbacksClassInfo.clazz, "notifyAppSwitchComing", "()V"); diff --git a/services/jni/com_android_server_KeyInputQueue.cpp b/services/jni/com_android_server_KeyInputQueue.cpp deleted file mode 100644 index f9e3585..0000000 --- a/services/jni/com_android_server_KeyInputQueue.cpp +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "Input" - -#include "jni.h" -#include "JNIHelp.h" -#include <utils/misc.h> -#include <utils/Log.h> - -#include <ui/EventHub.h> -#include <utils/threads.h> - -#include <stdio.h> - -namespace android { - -// ---------------------------------------------------------------------------- - -static struct input_offsets_t -{ - jfieldID mMinValue; - jfieldID mMaxValue; - jfieldID mFlat; - jfieldID mFuzz; - - jfieldID mDeviceId; - jfieldID mType; - jfieldID mScancode; - jfieldID mKeycode; - jfieldID mFlags; - jfieldID mValue; - jfieldID mWhen; -} gInputOffsets; - -// ---------------------------------------------------------------------------- - -static Mutex gLock; -static sp<EventHub> gHub; - -static jboolean -android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz, - jobject event) -{ - gLock.lock(); - sp<EventHub> hub = gHub; - if (hub == NULL) { - hub = new EventHub; - gHub = hub; - } - gLock.unlock(); - - int32_t deviceId; - int32_t type; - int32_t scancode, keycode; - uint32_t flags; - int32_t value; - nsecs_t when; - bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode, - &flags, &value, &when); - - env->SetIntField(event, gInputOffsets.mDeviceId, (jint)deviceId); - env->SetIntField(event, gInputOffsets.mType, (jint)type); - env->SetIntField(event, gInputOffsets.mScancode, (jint)scancode); - env->SetIntField(event, gInputOffsets.mKeycode, (jint)keycode); - env->SetIntField(event, gInputOffsets.mFlags, (jint)flags); - env->SetIntField(event, gInputOffsets.mValue, value); - env->SetLongField(event, gInputOffsets.mWhen, - (jlong)(nanoseconds_to_milliseconds(when))); - - return res; -} - -static jint -android_server_KeyInputQueue_getDeviceClasses(JNIEnv* env, jobject clazz, - jint deviceId) -{ - jint classes = 0; - gLock.lock(); - if (gHub != NULL) classes = gHub->getDeviceClasses(deviceId); - gLock.unlock(); - return classes; -} - -static jstring -android_server_KeyInputQueue_getDeviceName(JNIEnv* env, jobject clazz, - jint deviceId) -{ - String8 name; - gLock.lock(); - if (gHub != NULL) name = gHub->getDeviceName(deviceId); - gLock.unlock(); - - if (name.size() > 0) { - return env->NewStringUTF(name.string()); - } - return NULL; -} - -static void -android_server_KeyInputQueue_addExcludedDevice(JNIEnv* env, jobject clazz, - jstring deviceName) -{ - gLock.lock(); - sp<EventHub> hub = gHub; - if (hub == NULL) { - hub = new EventHub; - gHub = hub; - } - gLock.unlock(); - - const char* nameStr = env->GetStringUTFChars(deviceName, NULL); - gHub->addExcludedDevice(nameStr); - env->ReleaseStringUTFChars(deviceName, nameStr); -} - -static jboolean -android_server_KeyInputQueue_getAbsoluteInfo(JNIEnv* env, jobject clazz, - jint deviceId, jint axis, - jobject info) -{ - int32_t minValue, maxValue, flat, fuzz; - int res = -1; - gLock.lock(); - if (gHub != NULL) { - res = gHub->getAbsoluteInfo(deviceId, axis, - &minValue, &maxValue, &flat, &fuzz); - } - gLock.unlock(); - - if (res < 0) return JNI_FALSE; - - env->SetIntField(info, gInputOffsets.mMinValue, (jint)minValue); - env->SetIntField(info, gInputOffsets.mMaxValue, (jint)maxValue); - env->SetIntField(info, gInputOffsets.mFlat, (jint)flat); - env->SetIntField(info, gInputOffsets.mFuzz, (jint)fuzz); - return JNI_TRUE; -} - -static jint -android_server_KeyInputQueue_getSwitchState(JNIEnv* env, jobject clazz, - jint sw) -{ - jint st = -1; - gLock.lock(); - if (gHub != NULL) st = gHub->getSwitchState(-1, -1, sw); - gLock.unlock(); - - return st; -} - -static jint -android_server_KeyInputQueue_getSwitchStateDevice(JNIEnv* env, jobject clazz, - jint deviceId, jint sw) -{ - jint st = -1; - gLock.lock(); - if (gHub != NULL) st = gHub->getSwitchState(deviceId, -1, sw); - gLock.unlock(); - - return st; -} - -static jint -android_server_KeyInputQueue_getScancodeState(JNIEnv* env, jobject clazz, - jint sw) -{ - jint st = -1; - gLock.lock(); - if (gHub != NULL) st = gHub->getScanCodeState(0, -1, sw); - gLock.unlock(); - - return st; -} - -static jint -android_server_KeyInputQueue_getScancodeStateDevice(JNIEnv* env, jobject clazz, - jint deviceId, jint sw) -{ - jint st = -1; - gLock.lock(); - if (gHub != NULL) st = gHub->getScanCodeState(deviceId, -1, sw); - gLock.unlock(); - - return st; -} - -static jint -android_server_KeyInputQueue_getKeycodeState(JNIEnv* env, jobject clazz, - jint sw) -{ - jint st = -1; - gLock.lock(); - if (gHub != NULL) st = gHub->getKeyCodeState(0, -1, sw); - gLock.unlock(); - - return st; -} - -static jint -android_server_KeyInputQueue_getKeycodeStateDevice(JNIEnv* env, jobject clazz, - jint deviceId, jint sw) -{ - jint st = -1; - gLock.lock(); - if (gHub != NULL) st = gHub->getKeyCodeState(deviceId,-1, sw); - gLock.unlock(); - - return st; -} - -static jint -android_server_KeyInputQueue_scancodeToKeycode(JNIEnv* env, jobject clazz, - jint deviceId, jint scancode) -{ - jint res = 0; - gLock.lock(); - if (gHub != NULL) { - int32_t keycode; - uint32_t flags; - gHub->scancodeToKeycode(deviceId, scancode, &keycode, &flags); - res = keycode; - } - gLock.unlock(); - - return res; -} - -static jboolean -android_server_KeyInputQueue_hasKeys(JNIEnv* env, jobject clazz, - jintArray keyCodes, jbooleanArray outFlags) -{ - jboolean ret = JNI_FALSE; - - int32_t* codes = env->GetIntArrayElements(keyCodes, NULL); - uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL); - jsize numCodes = env->GetArrayLength(keyCodes); - if (numCodes == env->GetArrayLength(outFlags)) { - gLock.lock(); - if (gHub != NULL) ret = gHub->hasKeys(numCodes, codes, flags); - gLock.unlock(); - } - - env->ReleaseBooleanArrayElements(outFlags, flags, 0); - env->ReleaseIntArrayElements(keyCodes, codes, 0); - return ret; -} - -// ---------------------------------------------------------------------------- - -/* - * JNI registration. - */ -static JNINativeMethod gInputMethods[] = { - /* name, signature, funcPtr */ - { "readEvent", "(Landroid/view/RawInputEvent;)Z", - (void*) android_server_KeyInputQueue_readEvent }, - { "getDeviceClasses", "(I)I", - (void*) android_server_KeyInputQueue_getDeviceClasses }, - { "getDeviceName", "(I)Ljava/lang/String;", - (void*) android_server_KeyInputQueue_getDeviceName }, - { "addExcludedDevice", "(Ljava/lang/String;)V", - (void*) android_server_KeyInputQueue_addExcludedDevice }, - { "getAbsoluteInfo", "(IILcom/android/server/InputDevice$AbsoluteInfo;)Z", - (void*) android_server_KeyInputQueue_getAbsoluteInfo }, - { "getSwitchState", "(I)I", - (void*) android_server_KeyInputQueue_getSwitchState }, - { "getSwitchState", "(II)I", - (void*) android_server_KeyInputQueue_getSwitchStateDevice }, - { "nativeGetScancodeState", "(I)I", - (void*) android_server_KeyInputQueue_getScancodeState }, - { "nativeGetScancodeState", "(II)I", - (void*) android_server_KeyInputQueue_getScancodeStateDevice }, - { "nativeGetKeycodeState", "(I)I", - (void*) android_server_KeyInputQueue_getKeycodeState }, - { "nativeGetKeycodeState", "(II)I", - (void*) android_server_KeyInputQueue_getKeycodeStateDevice }, - { "hasKeys", "([I[Z)Z", - (void*) android_server_KeyInputQueue_hasKeys }, - { "scancodeToKeycode", "(II)I", - (void*) android_server_KeyInputQueue_scancodeToKeycode }, -}; - -int register_android_server_KeyInputQueue(JNIEnv* env) -{ - jclass input = env->FindClass("com/android/server/KeyInputQueue"); - LOG_FATAL_IF(input == NULL, "Unable to find class com/android/server/KeyInputQueue"); - int res = jniRegisterNativeMethods(env, "com/android/server/KeyInputQueue", - gInputMethods, NELEM(gInputMethods)); - - jclass absoluteInfo = env->FindClass("com/android/server/InputDevice$AbsoluteInfo"); - LOG_FATAL_IF(absoluteInfo == NULL, "Unable to find class com/android/server/InputDevice$AbsoluteInfo"); - - gInputOffsets.mMinValue - = env->GetFieldID(absoluteInfo, "minValue", "I"); - LOG_FATAL_IF(gInputOffsets.mMinValue == NULL, "Unable to find InputDevice.AbsoluteInfo.minValue"); - - gInputOffsets.mMaxValue - = env->GetFieldID(absoluteInfo, "maxValue", "I"); - LOG_FATAL_IF(gInputOffsets.mMaxValue == NULL, "Unable to find InputDevice.AbsoluteInfo.maxValue"); - - gInputOffsets.mFlat - = env->GetFieldID(absoluteInfo, "flat", "I"); - LOG_FATAL_IF(gInputOffsets.mFlat == NULL, "Unable to find InputDevice.AbsoluteInfo.flat"); - - gInputOffsets.mFuzz - = env->GetFieldID(absoluteInfo, "fuzz", "I"); - LOG_FATAL_IF(gInputOffsets.mFuzz == NULL, "Unable to find InputDevice.AbsoluteInfo.fuzz"); - - jclass inputEvent = env->FindClass("android/view/RawInputEvent"); - LOG_FATAL_IF(inputEvent == NULL, "Unable to find class android/view/RawInputEvent"); - - gInputOffsets.mDeviceId - = env->GetFieldID(inputEvent, "deviceId", "I"); - LOG_FATAL_IF(gInputOffsets.mDeviceId == NULL, "Unable to find RawInputEvent.deviceId"); - - gInputOffsets.mType - = env->GetFieldID(inputEvent, "type", "I"); - LOG_FATAL_IF(gInputOffsets.mType == NULL, "Unable to find RawInputEvent.type"); - - gInputOffsets.mScancode - = env->GetFieldID(inputEvent, "scancode", "I"); - LOG_FATAL_IF(gInputOffsets.mScancode == NULL, "Unable to find RawInputEvent.scancode"); - - gInputOffsets.mKeycode - = env->GetFieldID(inputEvent, "keycode", "I"); - LOG_FATAL_IF(gInputOffsets.mKeycode == NULL, "Unable to find RawInputEvent.keycode"); - - gInputOffsets.mFlags - = env->GetFieldID(inputEvent, "flags", "I"); - LOG_FATAL_IF(gInputOffsets.mFlags == NULL, "Unable to find RawInputEvent.flags"); - - gInputOffsets.mValue - = env->GetFieldID(inputEvent, "value", "I"); - LOG_FATAL_IF(gInputOffsets.mValue == NULL, "Unable to find RawInputEvent.value"); - - gInputOffsets.mWhen - = env->GetFieldID(inputEvent, "when", "J"); - LOG_FATAL_IF(gInputOffsets.mWhen == NULL, "Unable to find RawInputEvent.when"); - - return res; -} - -}; // namespace android - diff --git a/services/jni/com_android_server_PowerManagerService.cpp b/services/jni/com_android_server_PowerManagerService.cpp new file mode 100644 index 0000000..b80dbc5 --- /dev/null +++ b/services/jni/com_android_server_PowerManagerService.cpp @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "PowerManagerService-JNI" + +//#define LOG_NDEBUG 0 + +#include "JNIHelp.h" +#include "jni.h" +#include <limits.h> +#include <android_runtime/AndroidRuntime.h> +#include "com_android_server_PowerManagerService.h" + +namespace android { + +// ---------------------------------------------------------------------------- + +static struct { + jclass clazz; + + jmethodID goToSleep; + jmethodID userActivity; +} gPowerManagerServiceClassInfo; + +// ---------------------------------------------------------------------------- + +static jobject gPowerManagerServiceObj; + +static Mutex gPowerManagerLock; +static bool gScreenOn; +static bool gScreenBright; + +// ---------------------------------------------------------------------------- + +static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { + if (env->ExceptionCheck()) { + LOGE("An exception was thrown by callback '%s'.", methodName); + LOGE_EX(env); + env->ExceptionClear(); + return true; + } + return false; +} + +bool android_server_PowerManagerService_isScreenOn() { + AutoMutex _l(gPowerManagerLock); + return gScreenOn; +} + +bool android_server_PowerManagerService_isScreenBright() { + AutoMutex _l(gPowerManagerLock); + return gScreenBright; +} + +void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) { + if (gPowerManagerServiceObj) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + + env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.userActivity, + nanoseconds_to_milliseconds(eventTime), false, eventType, false); + checkAndClearExceptionFromCallback(env, "userActivity"); + } +} + +void android_server_PowerManagerService_goToSleep(nsecs_t eventTime) { + if (gPowerManagerServiceObj) { + JNIEnv* env = AndroidRuntime::getJNIEnv(); + + env->CallVoidMethod(gPowerManagerServiceObj, gPowerManagerServiceClassInfo.goToSleep, + nanoseconds_to_milliseconds(eventTime)); + checkAndClearExceptionFromCallback(env, "goToSleep"); + } +} + +// ---------------------------------------------------------------------------- + +static void android_server_PowerManagerService_nativeInit(JNIEnv* env, jobject obj) { + gPowerManagerServiceObj = env->NewGlobalRef(obj); +} + +static void android_server_PowerManagerService_nativeSetPowerState(JNIEnv* env, + jobject serviceObj, jboolean screenOn, jboolean screenBright) { + AutoMutex _l(gPowerManagerLock); + gScreenOn = screenOn; + gScreenBright = screenBright; +} + +// ---------------------------------------------------------------------------- + +static JNINativeMethod gPowerManagerServiceMethods[] = { + /* name, signature, funcPtr */ + { "nativeInit", "()V", + (void*) android_server_PowerManagerService_nativeInit }, + { "nativeSetPowerState", "(ZZ)V", + (void*) android_server_PowerManagerService_nativeSetPowerState }, +}; + +#define FIND_CLASS(var, className) \ + var = env->FindClass(className); \ + LOG_FATAL_IF(! var, "Unable to find class " className); \ + var = jclass(env->NewGlobalRef(var)); + +#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ + var = env->GetMethodID(clazz, methodName, methodDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find method " methodName); + +#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ + var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ + LOG_FATAL_IF(! var, "Unable to find field " fieldName); + +int register_android_server_PowerManagerService(JNIEnv* env) { + int res = jniRegisterNativeMethods(env, "com/android/server/PowerManagerService", + gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods)); + LOG_FATAL_IF(res < 0, "Unable to register native methods."); + + // Callbacks + + FIND_CLASS(gPowerManagerServiceClassInfo.clazz, "com/android/server/PowerManagerService"); + + GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleep, gPowerManagerServiceClassInfo.clazz, + "goToSleep", "(J)V"); + + GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivity, gPowerManagerServiceClassInfo.clazz, + "userActivity", "(JZIZ)V"); + + return 0; +} + +} /* namespace android */ diff --git a/services/jni/com_android_server_PowerManagerService.h b/services/jni/com_android_server_PowerManagerService.h new file mode 100644 index 0000000..9b05f38 --- /dev/null +++ b/services/jni/com_android_server_PowerManagerService.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_SERVER_POWER_MANAGER_SERVICE_H +#define _ANDROID_SERVER_POWER_MANAGER_SERVICE_H + +#include "JNIHelp.h" +#include "jni.h" + +namespace android { + +enum { + POWER_MANAGER_OTHER_EVENT = 0, + POWER_MANAGER_CHEEK_EVENT = 1, + POWER_MANAGER_TOUCH_EVENT = 2, // touch events are TOUCH for 300ms, and then either + // up events or LONG_TOUCH events. + POWER_MANAGER_LONG_TOUCH_EVENT = 3, + POWER_MANAGER_TOUCH_UP_EVENT = 4, + POWER_MANAGER_BUTTON_EVENT = 5, // Button and trackball events. +}; + +extern bool android_server_PowerManagerService_isScreenOn(); +extern bool android_server_PowerManagerService_isScreenBright(); +extern void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType); +extern void android_server_PowerManagerService_goToSleep(nsecs_t eventTime); + +} // namespace android + +#endif // _ANDROID_SERVER_POWER_MANAGER_SERVICE_H diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp index a1a6838..1a2d8b6 100644 --- a/services/jni/onload.cpp +++ b/services/jni/onload.cpp @@ -6,9 +6,9 @@ namespace android { int register_android_server_AlarmManagerService(JNIEnv* env); int register_android_server_BatteryService(JNIEnv* env); -int register_android_server_KeyInputQueue(JNIEnv* env); int register_android_server_InputManager(JNIEnv* env); int register_android_server_LightsService(JNIEnv* env); +int register_android_server_PowerManagerService(JNIEnv* env); int register_android_server_SensorService(JNIEnv* env); int register_android_server_VibratorService(JNIEnv* env); int register_android_server_SystemServer(JNIEnv* env); @@ -28,7 +28,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) } LOG_ASSERT(env, "Could not retrieve the env!"); - register_android_server_KeyInputQueue(env); + register_android_server_PowerManagerService(env); register_android_server_InputManager(env); register_android_server_LightsService(env); register_android_server_AlarmManagerService(env); |