146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown/* 246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Copyright (C) 2010 The Android Open Source Project 346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * you may not use this file except in compliance with the License. 646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * You may obtain a copy of the License at 746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * 1046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * Unless required by applicable law or agreed to in writing, software 1146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * See the License for the specific language governing permissions and 1446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown * limitations under the License. 1546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown */ 1646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define LOG_TAG "KeyEvent-JNI" 1846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "JNIHelp.h" 2046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 2146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <android_runtime/AndroidRuntime.h> 2287eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include <android_runtime/Log.h> 2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <utils/Log.h> 249d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brown#include <input/Input.h> 25337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright#include <ScopedUtfChars.h> 2646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_view_KeyEvent.h" 2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android { 2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic struct { 3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jclass clazz; 3446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 351f2451007c660091b7b090c1ea332f9044515d2dJeff Brown jmethodID obtain; 361f2451007c660091b7b090c1ea332f9044515d2dJeff Brown jmethodID recycle; 3746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 38c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jfieldID mDeviceId; 39c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jfieldID mSource; 4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mMetaState; 4146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mAction; 4246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mKeyCode; 4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mScanCode; 4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mRepeatCount; 4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mFlags; 4646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mDownTime; 4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mEventTime; 4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mCharacters; 4946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gKeyEventClassInfo; 5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 5246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 5346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownjobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { 541f2451007c660091b7b090c1ea332f9044515d2dJeff Brown jobject eventObj = env->CallStaticObjectMethod(gKeyEventClassInfo.clazz, 551f2451007c660091b7b090c1ea332f9044515d2dJeff Brown gKeyEventClassInfo.obtain, 5646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nanoseconds_to_milliseconds(event->getDownTime()), 5746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nanoseconds_to_milliseconds(event->getEventTime()), 5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getAction(), 5946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getKeyCode(), 6046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getRepeatCount(), 6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getMetaState(), 6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getDeviceId(), 6346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getScanCode(), 64c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown event->getFlags(), 651f2451007c660091b7b090c1ea332f9044515d2dJeff Brown event->getSource(), 661f2451007c660091b7b090c1ea332f9044515d2dJeff Brown NULL); 671f2451007c660091b7b090c1ea332f9044515d2dJeff Brown if (env->ExceptionCheck()) { 683762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("An exception occurred while obtaining a key event."); 691f2451007c660091b7b090c1ea332f9044515d2dJeff Brown LOGE_EX(env); 701f2451007c660091b7b090c1ea332f9044515d2dJeff Brown env->ExceptionClear(); 711f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return NULL; 721f2451007c660091b7b090c1ea332f9044515d2dJeff Brown } 731f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return eventObj; 7446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 7546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 761f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, 7746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown KeyEvent* event) { 78c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId); 79c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource); 8046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint metaState = env->GetIntField(eventObj, gKeyEventClassInfo.mMetaState); 8146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint action = env->GetIntField(eventObj, gKeyEventClassInfo.mAction); 8246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint keyCode = env->GetIntField(eventObj, gKeyEventClassInfo.mKeyCode); 8346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint scanCode = env->GetIntField(eventObj, gKeyEventClassInfo.mScanCode); 8446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint repeatCount = env->GetIntField(eventObj, gKeyEventClassInfo.mRepeatCount); 8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint flags = env->GetIntField(eventObj, gKeyEventClassInfo.mFlags); 8646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime); 8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime); 8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 89c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown event->initialize(deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, 9046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown milliseconds_to_nanoseconds(downTime), 9146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown milliseconds_to_nanoseconds(eventTime)); 921f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return OK; 931f2451007c660091b7b090c1ea332f9044515d2dJeff Brown} 941f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 951f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_KeyEvent_recycle(JNIEnv* env, jobject eventObj) { 961f2451007c660091b7b090c1ea332f9044515d2dJeff Brown env->CallVoidMethod(eventObj, gKeyEventClassInfo.recycle); 971f2451007c660091b7b090c1ea332f9044515d2dJeff Brown if (env->ExceptionCheck()) { 988564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("An exception occurred while recycling a key event."); 991f2451007c660091b7b090c1ea332f9044515d2dJeff Brown LOGW_EX(env); 1001f2451007c660091b7b090c1ea332f9044515d2dJeff Brown env->ExceptionClear(); 1011f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return UNKNOWN_ERROR; 1021f2451007c660091b7b090c1ea332f9044515d2dJeff Brown } 1031f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return OK; 10446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 10546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 106337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wrightstatic jstring android_view_KeyEvent_nativeKeyCodeToString(JNIEnv* env, jobject clazz, 107337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright jint keyCode) { 108337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright return env->NewStringUTF(KeyEvent::getLabel(keyCode)); 1093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 1103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 111337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wrightstatic jint android_view_KeyEvent_nativeKeyCodeFromString(JNIEnv* env, jobject clazz, 112337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright jstring label) { 113337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright ScopedUtfChars keyLabel(env, label); 114337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright return KeyEvent::getKeyCodeFromLabel(keyLabel.c_str()); 1153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 1163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 1171f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 11846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 11946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1203c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic const JNINativeMethod g_methods[] = { 121337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright { "nativeKeyCodeToString", "(I)Ljava/lang/String;", 122337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright (void*)android_view_KeyEvent_nativeKeyCodeToString}, 123337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright { "nativeKeyCodeFromString", "(Ljava/lang/String;)I", 124337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright (void*)android_view_KeyEvent_nativeKeyCodeFromString}, 1253c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}; 1263c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 12746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define FIND_CLASS(var, className) \ 12846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = env->FindClass(className); \ 12946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); \ 13046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = jclass(env->NewGlobalRef(var)); 13146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1321f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \ 1331f2451007c660091b7b090c1ea332f9044515d2dJeff Brown var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \ 1341f2451007c660091b7b090c1ea332f9044515d2dJeff Brown LOG_FATAL_IF(! var, "Unable to find static method" methodName); 1351f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 13646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \ 13746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = env->GetMethodID(clazz, methodName, fieldDescriptor); \ 13846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown LOG_FATAL_IF(! var, "Unable to find method" methodName); 13946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 14046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 14146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 14246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown LOG_FATAL_IF(! var, "Unable to find field " fieldName); 14346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 14446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint register_android_view_KeyEvent(JNIEnv* env) { 145c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent"); 1461f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 1471f2451007c660091b7b090c1ea332f9044515d2dJeff Brown GET_STATIC_METHOD_ID(gKeyEventClassInfo.obtain, gKeyEventClassInfo.clazz, 1481f2451007c660091b7b090c1ea332f9044515d2dJeff Brown "obtain", "(JJIIIIIIIILjava/lang/String;)Landroid/view/KeyEvent;"); 1491f2451007c660091b7b090c1ea332f9044515d2dJeff Brown GET_METHOD_ID(gKeyEventClassInfo.recycle, gKeyEventClassInfo.clazz, 1501f2451007c660091b7b090c1ea332f9044515d2dJeff Brown "recycle", "()V"); 15146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 152c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mDeviceId, gKeyEventClassInfo.clazz, 153c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown "mDeviceId", "I"); 154c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mSource, gKeyEventClassInfo.clazz, 155c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown "mSource", "I"); 15646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mMetaState, gKeyEventClassInfo.clazz, 15746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mMetaState", "I"); 15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mAction, gKeyEventClassInfo.clazz, 15946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mAction", "I"); 16046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mKeyCode, gKeyEventClassInfo.clazz, 16146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mKeyCode", "I"); 16246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mScanCode, gKeyEventClassInfo.clazz, 16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mScanCode", "I"); 16446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mRepeatCount, gKeyEventClassInfo.clazz, 16546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mRepeatCount", "I"); 16646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mFlags, gKeyEventClassInfo.clazz, 16746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mFlags", "I"); 16846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mDownTime, gKeyEventClassInfo.clazz, 16946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mDownTime", "J"); 17046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mEventTime, gKeyEventClassInfo.clazz, 17146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mEventTime", "J"); 17246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mCharacters, gKeyEventClassInfo.clazz, 17346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mCharacters", "Ljava/lang/String;"); 17446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1753c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return AndroidRuntime::registerNativeMethods( 176c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown env, "android/view/KeyEvent", g_methods, NELEM(g_methods)); 17746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 17846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 17946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android 180