android_view_KeyEvent.cpp revision 8564c8da817a845353d213acd8636b76f567b234
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> 2246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <utils/Log.h> 2346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include <ui/Input.h> 2446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_view_KeyEvent.h" 2546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 2646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android { 2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic struct { 3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jclass clazz; 3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 331f2451007c660091b7b090c1ea332f9044515d2dJeff Brown jmethodID obtain; 341f2451007c660091b7b090c1ea332f9044515d2dJeff Brown jmethodID recycle; 3546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 36c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jfieldID mDeviceId; 37c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jfieldID mSource; 3846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mMetaState; 3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mAction; 4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mKeyCode; 4146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mScanCode; 4246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mRepeatCount; 4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mFlags; 4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mDownTime; 4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mEventTime; 4646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mCharacters; 4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gKeyEventClassInfo; 4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 4946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownjobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { 521f2451007c660091b7b090c1ea332f9044515d2dJeff Brown jobject eventObj = env->CallStaticObjectMethod(gKeyEventClassInfo.clazz, 531f2451007c660091b7b090c1ea332f9044515d2dJeff Brown gKeyEventClassInfo.obtain, 5446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nanoseconds_to_milliseconds(event->getDownTime()), 5546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nanoseconds_to_milliseconds(event->getEventTime()), 5646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getAction(), 5746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getKeyCode(), 5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getRepeatCount(), 5946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getMetaState(), 6046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getDeviceId(), 6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getScanCode(), 62c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown event->getFlags(), 631f2451007c660091b7b090c1ea332f9044515d2dJeff Brown event->getSource(), 641f2451007c660091b7b090c1ea332f9044515d2dJeff Brown NULL); 651f2451007c660091b7b090c1ea332f9044515d2dJeff Brown if (env->ExceptionCheck()) { 661f2451007c660091b7b090c1ea332f9044515d2dJeff Brown LOGE("An exception occurred while obtaining a key event."); 671f2451007c660091b7b090c1ea332f9044515d2dJeff Brown LOGE_EX(env); 681f2451007c660091b7b090c1ea332f9044515d2dJeff Brown env->ExceptionClear(); 691f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return NULL; 701f2451007c660091b7b090c1ea332f9044515d2dJeff Brown } 711f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return eventObj; 7246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 7346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 741f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, 7546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown KeyEvent* event) { 76c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId); 77c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource); 7846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint metaState = env->GetIntField(eventObj, gKeyEventClassInfo.mMetaState); 7946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint action = env->GetIntField(eventObj, gKeyEventClassInfo.mAction); 8046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint keyCode = env->GetIntField(eventObj, gKeyEventClassInfo.mKeyCode); 8146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint scanCode = env->GetIntField(eventObj, gKeyEventClassInfo.mScanCode); 8246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint repeatCount = env->GetIntField(eventObj, gKeyEventClassInfo.mRepeatCount); 8346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint flags = env->GetIntField(eventObj, gKeyEventClassInfo.mFlags); 8446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime); 8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime); 8646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 87c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown event->initialize(deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, 8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown milliseconds_to_nanoseconds(downTime), 8946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown milliseconds_to_nanoseconds(eventTime)); 901f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return OK; 911f2451007c660091b7b090c1ea332f9044515d2dJeff Brown} 921f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 931f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_KeyEvent_recycle(JNIEnv* env, jobject eventObj) { 941f2451007c660091b7b090c1ea332f9044515d2dJeff Brown env->CallVoidMethod(eventObj, gKeyEventClassInfo.recycle); 951f2451007c660091b7b090c1ea332f9044515d2dJeff Brown if (env->ExceptionCheck()) { 968564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("An exception occurred while recycling a key event."); 971f2451007c660091b7b090c1ea332f9044515d2dJeff Brown LOGW_EX(env); 981f2451007c660091b7b090c1ea332f9044515d2dJeff Brown env->ExceptionClear(); 991f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return UNKNOWN_ERROR; 1001f2451007c660091b7b090c1ea332f9044515d2dJeff Brown } 1011f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return OK; 10246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 10346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1043c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic jboolean native_isSystemKey(JNIEnv* env, jobject clazz, jint keyCode) { 1053c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return KeyEvent::isSystemKey(keyCode); 1063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 1073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 1083c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic jboolean native_hasDefaultAction(JNIEnv* env, jobject clazz, jint keyCode) { 1093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return KeyEvent::hasDefaultAction(keyCode); 1103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 1113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 1121f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 11346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 11446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1153c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic const JNINativeMethod g_methods[] = { 1163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn { "native_isSystemKey", "(I)Z", (void*)native_isSystemKey }, 1173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn { "native_hasDefaultAction", "(I)Z", (void*)native_hasDefaultAction }, 1183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}; 1193c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 12046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define FIND_CLASS(var, className) \ 12146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = env->FindClass(className); \ 12246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); \ 12346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = jclass(env->NewGlobalRef(var)); 12446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1251f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \ 1261f2451007c660091b7b090c1ea332f9044515d2dJeff Brown var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \ 1271f2451007c660091b7b090c1ea332f9044515d2dJeff Brown LOG_FATAL_IF(! var, "Unable to find static method" methodName); 1281f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 12946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \ 13046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = env->GetMethodID(clazz, methodName, fieldDescriptor); \ 13146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown LOG_FATAL_IF(! var, "Unable to find method" methodName); 13246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 13346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ 13446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ 13546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown LOG_FATAL_IF(! var, "Unable to find field " fieldName); 13646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 13746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint register_android_view_KeyEvent(JNIEnv* env) { 138c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent"); 1391f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 1401f2451007c660091b7b090c1ea332f9044515d2dJeff Brown GET_STATIC_METHOD_ID(gKeyEventClassInfo.obtain, gKeyEventClassInfo.clazz, 1411f2451007c660091b7b090c1ea332f9044515d2dJeff Brown "obtain", "(JJIIIIIIIILjava/lang/String;)Landroid/view/KeyEvent;"); 1421f2451007c660091b7b090c1ea332f9044515d2dJeff Brown GET_METHOD_ID(gKeyEventClassInfo.recycle, gKeyEventClassInfo.clazz, 1431f2451007c660091b7b090c1ea332f9044515d2dJeff Brown "recycle", "()V"); 14446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 145c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mDeviceId, gKeyEventClassInfo.clazz, 146c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown "mDeviceId", "I"); 147c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mSource, gKeyEventClassInfo.clazz, 148c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown "mSource", "I"); 14946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mMetaState, gKeyEventClassInfo.clazz, 15046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mMetaState", "I"); 15146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mAction, gKeyEventClassInfo.clazz, 15246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mAction", "I"); 15346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mKeyCode, gKeyEventClassInfo.clazz, 15446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mKeyCode", "I"); 15546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mScanCode, gKeyEventClassInfo.clazz, 15646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mScanCode", "I"); 15746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mRepeatCount, gKeyEventClassInfo.clazz, 15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mRepeatCount", "I"); 15946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mFlags, gKeyEventClassInfo.clazz, 16046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mFlags", "I"); 16146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mDownTime, gKeyEventClassInfo.clazz, 16246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mDownTime", "J"); 16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mEventTime, gKeyEventClassInfo.clazz, 16446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mEventTime", "J"); 16546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown GET_FIELD_ID(gKeyEventClassInfo.mCharacters, gKeyEventClassInfo.clazz, 16646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown "mCharacters", "Ljava/lang/String;"); 16746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1683c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn return AndroidRuntime::registerNativeMethods( 169c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown env, "android/view/KeyEvent", g_methods, NELEM(g_methods)); 17046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 17146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 17246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android 173