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 "KeyEvent-JNI" 18 19 #include "JNIHelp.h" 20 21 #include <android_runtime/AndroidRuntime.h> 22 #include <android_runtime/Log.h> 23 #include <utils/Log.h> 24 #include <input/Input.h> 25 #include <ScopedUtfChars.h> 26 #include "android_view_KeyEvent.h" 27 28 #include "core_jni_helpers.h" 29 30 namespace android { 31 32 // ---------------------------------------------------------------------------- 33 34 static struct { 35 jclass clazz; 36 37 jmethodID obtain; 38 jmethodID recycle; 39 40 jfieldID mDeviceId; 41 jfieldID mSource; 42 jfieldID mMetaState; 43 jfieldID mAction; 44 jfieldID mKeyCode; 45 jfieldID mScanCode; 46 jfieldID mRepeatCount; 47 jfieldID mFlags; 48 jfieldID mDownTime; 49 jfieldID mEventTime; 50 jfieldID mCharacters; 51 } gKeyEventClassInfo; 52 53 // ---------------------------------------------------------------------------- 54 55 jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { 56 jobject eventObj = env->CallStaticObjectMethod(gKeyEventClassInfo.clazz, 57 gKeyEventClassInfo.obtain, 58 nanoseconds_to_milliseconds(event->getDownTime()), 59 nanoseconds_to_milliseconds(event->getEventTime()), 60 event->getAction(), 61 event->getKeyCode(), 62 event->getRepeatCount(), 63 event->getMetaState(), 64 event->getDeviceId(), 65 event->getScanCode(), 66 event->getFlags(), 67 event->getSource(), 68 NULL); 69 if (env->ExceptionCheck()) { 70 ALOGE("An exception occurred while obtaining a key event."); 71 LOGE_EX(env); 72 env->ExceptionClear(); 73 return NULL; 74 } 75 return eventObj; 76 } 77 78 status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, 79 KeyEvent* event) { 80 jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId); 81 jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource); 82 jint metaState = env->GetIntField(eventObj, gKeyEventClassInfo.mMetaState); 83 jint action = env->GetIntField(eventObj, gKeyEventClassInfo.mAction); 84 jint keyCode = env->GetIntField(eventObj, gKeyEventClassInfo.mKeyCode); 85 jint scanCode = env->GetIntField(eventObj, gKeyEventClassInfo.mScanCode); 86 jint repeatCount = env->GetIntField(eventObj, gKeyEventClassInfo.mRepeatCount); 87 jint flags = env->GetIntField(eventObj, gKeyEventClassInfo.mFlags); 88 jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime); 89 jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime); 90 91 event->initialize(deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, 92 milliseconds_to_nanoseconds(downTime), 93 milliseconds_to_nanoseconds(eventTime)); 94 return OK; 95 } 96 97 status_t android_view_KeyEvent_recycle(JNIEnv* env, jobject eventObj) { 98 env->CallVoidMethod(eventObj, gKeyEventClassInfo.recycle); 99 if (env->ExceptionCheck()) { 100 ALOGW("An exception occurred while recycling a key event."); 101 LOGW_EX(env); 102 env->ExceptionClear(); 103 return UNKNOWN_ERROR; 104 } 105 return OK; 106 } 107 108 static jstring android_view_KeyEvent_nativeKeyCodeToString(JNIEnv* env, jobject clazz, 109 jint keyCode) { 110 return env->NewStringUTF(KeyEvent::getLabel(keyCode)); 111 } 112 113 static jint android_view_KeyEvent_nativeKeyCodeFromString(JNIEnv* env, jobject clazz, 114 jstring label) { 115 ScopedUtfChars keyLabel(env, label); 116 return KeyEvent::getKeyCodeFromLabel(keyLabel.c_str()); 117 } 118 119 120 // ---------------------------------------------------------------------------- 121 122 static const JNINativeMethod g_methods[] = { 123 { "nativeKeyCodeToString", "(I)Ljava/lang/String;", 124 (void*)android_view_KeyEvent_nativeKeyCodeToString}, 125 { "nativeKeyCodeFromString", "(Ljava/lang/String;)I", 126 (void*)android_view_KeyEvent_nativeKeyCodeFromString}, 127 }; 128 129 int register_android_view_KeyEvent(JNIEnv* env) { 130 jclass clazz = FindClassOrDie(env, "android/view/KeyEvent"); 131 gKeyEventClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); 132 133 gKeyEventClassInfo.obtain = GetStaticMethodIDOrDie(env, gKeyEventClassInfo.clazz, 134 "obtain", "(JJIIIIIIIILjava/lang/String;)Landroid/view/KeyEvent;"); 135 gKeyEventClassInfo.recycle = GetMethodIDOrDie(env, gKeyEventClassInfo.clazz, 136 "recycle", "()V"); 137 138 gKeyEventClassInfo.mDeviceId = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mDeviceId", "I"); 139 gKeyEventClassInfo.mSource = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mSource", "I"); 140 gKeyEventClassInfo.mMetaState = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mMetaState", 141 "I"); 142 gKeyEventClassInfo.mAction = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mAction", "I"); 143 gKeyEventClassInfo.mKeyCode = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mKeyCode", "I"); 144 gKeyEventClassInfo.mScanCode = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mScanCode", "I"); 145 gKeyEventClassInfo.mRepeatCount = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mRepeatCount", 146 "I"); 147 gKeyEventClassInfo.mFlags = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mFlags", "I"); 148 gKeyEventClassInfo.mDownTime = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mDownTime", "J"); 149 gKeyEventClassInfo.mEventTime = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mEventTime", 150 "J"); 151 gKeyEventClassInfo.mCharacters = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mCharacters", 152 "Ljava/lang/String;"); 153 154 return RegisterMethodsOrDie(env, "android/view/KeyEvent", g_methods, NELEM(g_methods)); 155 } 156 157 } // namespace android 158