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 28987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe#include "core_jni_helpers.h" 29987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android { 3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 3446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic struct { 3546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jclass clazz; 3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 371f2451007c660091b7b090c1ea332f9044515d2dJeff Brown jmethodID obtain; 381f2451007c660091b7b090c1ea332f9044515d2dJeff Brown jmethodID recycle; 3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 40c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jfieldID mDeviceId; 41c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jfieldID mSource; 4246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mMetaState; 4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mAction; 4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mKeyCode; 4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mScanCode; 4646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mRepeatCount; 4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mFlags; 4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mDownTime; 4946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mEventTime; 5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jfieldID mCharacters; 5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gKeyEventClassInfo; 5246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 5346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 5446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 5546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownjobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { 561f2451007c660091b7b090c1ea332f9044515d2dJeff Brown jobject eventObj = env->CallStaticObjectMethod(gKeyEventClassInfo.clazz, 571f2451007c660091b7b090c1ea332f9044515d2dJeff Brown gKeyEventClassInfo.obtain, 5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nanoseconds_to_milliseconds(event->getDownTime()), 5946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown nanoseconds_to_milliseconds(event->getEventTime()), 6046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getAction(), 6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getKeyCode(), 6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getRepeatCount(), 6346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getMetaState(), 6446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getDeviceId(), 6546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown event->getScanCode(), 66c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown event->getFlags(), 671f2451007c660091b7b090c1ea332f9044515d2dJeff Brown event->getSource(), 681f2451007c660091b7b090c1ea332f9044515d2dJeff Brown NULL); 691f2451007c660091b7b090c1ea332f9044515d2dJeff Brown if (env->ExceptionCheck()) { 703762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("An exception occurred while obtaining a key event."); 711f2451007c660091b7b090c1ea332f9044515d2dJeff Brown LOGE_EX(env); 721f2451007c660091b7b090c1ea332f9044515d2dJeff Brown env->ExceptionClear(); 731f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return NULL; 741f2451007c660091b7b090c1ea332f9044515d2dJeff Brown } 751f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return eventObj; 7646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 7746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 781f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, 7946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown KeyEvent* event) { 80c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId); 81c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource); 8246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint metaState = env->GetIntField(eventObj, gKeyEventClassInfo.mMetaState); 8346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint action = env->GetIntField(eventObj, gKeyEventClassInfo.mAction); 8446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint keyCode = env->GetIntField(eventObj, gKeyEventClassInfo.mKeyCode); 8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint scanCode = env->GetIntField(eventObj, gKeyEventClassInfo.mScanCode); 8646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint repeatCount = env->GetIntField(eventObj, gKeyEventClassInfo.mRepeatCount); 8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jint flags = env->GetIntField(eventObj, gKeyEventClassInfo.mFlags); 8846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime); 8946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime); 9046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 91c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown event->initialize(deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, 9246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown milliseconds_to_nanoseconds(downTime), 9346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown milliseconds_to_nanoseconds(eventTime)); 941f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return OK; 951f2451007c660091b7b090c1ea332f9044515d2dJeff Brown} 961f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 971f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_KeyEvent_recycle(JNIEnv* env, jobject eventObj) { 981f2451007c660091b7b090c1ea332f9044515d2dJeff Brown env->CallVoidMethod(eventObj, gKeyEventClassInfo.recycle); 991f2451007c660091b7b090c1ea332f9044515d2dJeff Brown if (env->ExceptionCheck()) { 1008564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("An exception occurred while recycling a key event."); 1011f2451007c660091b7b090c1ea332f9044515d2dJeff Brown LOGW_EX(env); 1021f2451007c660091b7b090c1ea332f9044515d2dJeff Brown env->ExceptionClear(); 1031f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return UNKNOWN_ERROR; 1041f2451007c660091b7b090c1ea332f9044515d2dJeff Brown } 1051f2451007c660091b7b090c1ea332f9044515d2dJeff Brown return OK; 10646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 10746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 108337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wrightstatic jstring android_view_KeyEvent_nativeKeyCodeToString(JNIEnv* env, jobject clazz, 109337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright jint keyCode) { 110337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright return env->NewStringUTF(KeyEvent::getLabel(keyCode)); 1113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 1123c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 113337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wrightstatic jint android_view_KeyEvent_nativeKeyCodeFromString(JNIEnv* env, jobject clazz, 114337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright jstring label) { 115337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright ScopedUtfChars keyLabel(env, label); 116337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright return KeyEvent::getKeyCodeFromLabel(keyLabel.c_str()); 1173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn} 1183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 1191f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 12046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ---------------------------------------------------------------------------- 12146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 1223c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic const JNINativeMethod g_methods[] = { 123337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright { "nativeKeyCodeToString", "(I)Ljava/lang/String;", 124337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright (void*)android_view_KeyEvent_nativeKeyCodeToString}, 125337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright { "nativeKeyCodeFromString", "(Ljava/lang/String;)I", 126337d9d2edc262141f9b8f684e53aae5e47f0ae13Michael Wright (void*)android_view_KeyEvent_nativeKeyCodeFromString}, 1273c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}; 1283c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn 12946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint register_android_view_KeyEvent(JNIEnv* env) { 130987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe jclass clazz = FindClassOrDie(env, "android/view/KeyEvent"); 131987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); 1321f2451007c660091b7b090c1ea332f9044515d2dJeff Brown 133987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.obtain = GetStaticMethodIDOrDie(env, gKeyEventClassInfo.clazz, 1341f2451007c660091b7b090c1ea332f9044515d2dJeff Brown "obtain", "(JJIIIIIIIILjava/lang/String;)Landroid/view/KeyEvent;"); 135987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.recycle = GetMethodIDOrDie(env, gKeyEventClassInfo.clazz, 1361f2451007c660091b7b090c1ea332f9044515d2dJeff Brown "recycle", "()V"); 13746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 138987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mDeviceId = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mDeviceId", "I"); 139987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mSource = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mSource", "I"); 140987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mMetaState = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mMetaState", 141987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe "I"); 142987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mAction = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mAction", "I"); 143987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mKeyCode = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mKeyCode", "I"); 144987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mScanCode = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mScanCode", "I"); 145987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mRepeatCount = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mRepeatCount", 146987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe "I"); 147987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mFlags = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mFlags", "I"); 148987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mDownTime = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mDownTime", "J"); 149987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mEventTime = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mEventTime", 150987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe "J"); 151987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gKeyEventClassInfo.mCharacters = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mCharacters", 152987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe "Ljava/lang/String;"); 153987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 154987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe return RegisterMethodsOrDie(env, "android/view/KeyEvent", g_methods, NELEM(g_methods)); 15546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} 15646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown 15746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android 158