android_view_KeyEvent.cpp revision 87eac99a21772ae56018cb81db6966557b459554
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>
2546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#include "android_view_KeyEvent.h"
2646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownnamespace android {
2846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
2946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
3046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
3146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownstatic struct {
3246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jclass clazz;
3346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
341f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    jmethodID obtain;
351f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    jmethodID recycle;
3646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
37c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    jfieldID mDeviceId;
38c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    jfieldID mSource;
3946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mMetaState;
4046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mAction;
4146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mKeyCode;
4246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mScanCode;
4346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mRepeatCount;
4446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mFlags;
4546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mDownTime;
4646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mEventTime;
4746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jfieldID mCharacters;
4846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} gKeyEventClassInfo;
4946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
5146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
5246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownjobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) {
531f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    jobject eventObj = env->CallStaticObjectMethod(gKeyEventClassInfo.clazz,
541f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            gKeyEventClassInfo.obtain,
5546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            nanoseconds_to_milliseconds(event->getDownTime()),
5646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            nanoseconds_to_milliseconds(event->getEventTime()),
5746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getAction(),
5846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getKeyCode(),
5946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getRepeatCount(),
6046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getMetaState(),
6146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getDeviceId(),
6246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            event->getScanCode(),
63c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            event->getFlags(),
641f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            event->getSource(),
651f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            NULL);
661f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    if (env->ExceptionCheck()) {
673762c311729fe9f3af085c14c5c1fb471d994c03Steve Block        ALOGE("An exception occurred while obtaining a key event.");
681f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        LOGE_EX(env);
691f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        env->ExceptionClear();
701f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        return NULL;
711f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    }
721f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    return eventObj;
7346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
7446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
751f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj,
7646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        KeyEvent* event) {
77c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId);
78c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource);
7946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint metaState = env->GetIntField(eventObj, gKeyEventClassInfo.mMetaState);
8046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint action = env->GetIntField(eventObj, gKeyEventClassInfo.mAction);
8146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint keyCode = env->GetIntField(eventObj, gKeyEventClassInfo.mKeyCode);
8246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint scanCode = env->GetIntField(eventObj, gKeyEventClassInfo.mScanCode);
8346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint repeatCount = env->GetIntField(eventObj, gKeyEventClassInfo.mRepeatCount);
8446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jint flags = env->GetIntField(eventObj, gKeyEventClassInfo.mFlags);
8546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime);
8646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime);
8746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
88c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    event->initialize(deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount,
8946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            milliseconds_to_nanoseconds(downTime),
9046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            milliseconds_to_nanoseconds(eventTime));
911f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    return OK;
921f2451007c660091b7b090c1ea332f9044515d2dJeff Brown}
931f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
941f2451007c660091b7b090c1ea332f9044515d2dJeff Brownstatus_t android_view_KeyEvent_recycle(JNIEnv* env, jobject eventObj) {
951f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    env->CallVoidMethod(eventObj, gKeyEventClassInfo.recycle);
961f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    if (env->ExceptionCheck()) {
978564c8da817a845353d213acd8636b76f567b234Steve Block        ALOGW("An exception occurred while recycling a key event.");
981f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        LOGW_EX(env);
991f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        env->ExceptionClear();
1001f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        return UNKNOWN_ERROR;
1011f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    }
1021f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    return OK;
10346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
10446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1053c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic jboolean native_isSystemKey(JNIEnv* env, jobject clazz, jint keyCode) {
1063c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return KeyEvent::isSystemKey(keyCode);
1073c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
1083c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1093c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic jboolean native_hasDefaultAction(JNIEnv* env, jobject clazz, jint keyCode) {
1103c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return KeyEvent::hasDefaultAction(keyCode);
1113c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn}
1123c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
1131f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
11446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown// ----------------------------------------------------------------------------
11546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1163c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackbornstatic const JNINativeMethod g_methods[] = {
1173c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    { "native_isSystemKey", "(I)Z", (void*)native_isSystemKey },
1183c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    { "native_hasDefaultAction", "(I)Z", (void*)native_hasDefaultAction },
1193c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn};
1203c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn
12146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define FIND_CLASS(var, className) \
12246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->FindClass(className); \
12346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find class " className); \
12446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = jclass(env->NewGlobalRef(var));
12546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1261f2451007c660091b7b090c1ea332f9044515d2dJeff Brown#define GET_STATIC_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
1271f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        var = env->GetStaticMethodID(clazz, methodName, fieldDescriptor); \
1281f2451007c660091b7b090c1ea332f9044515d2dJeff Brown        LOG_FATAL_IF(! var, "Unable to find static method" methodName);
1291f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
13046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
13146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
13246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find method" methodName);
13346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
13446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
13546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
13646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
13746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
13846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brownint register_android_view_KeyEvent(JNIEnv* env) {
139c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1401f2451007c660091b7b090c1ea332f9044515d2dJeff Brown
1411f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    GET_STATIC_METHOD_ID(gKeyEventClassInfo.obtain, gKeyEventClassInfo.clazz,
1421f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            "obtain", "(JJIIIIIIIILjava/lang/String;)Landroid/view/KeyEvent;");
1431f2451007c660091b7b090c1ea332f9044515d2dJeff Brown    GET_METHOD_ID(gKeyEventClassInfo.recycle, gKeyEventClassInfo.clazz,
1441f2451007c660091b7b090c1ea332f9044515d2dJeff Brown            "recycle", "()V");
14546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
146c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mDeviceId, gKeyEventClassInfo.clazz,
147c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            "mDeviceId", "I");
148c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mSource, gKeyEventClassInfo.clazz,
149c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown            "mSource", "I");
15046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mMetaState, gKeyEventClassInfo.clazz,
15146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mMetaState", "I");
15246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mAction, gKeyEventClassInfo.clazz,
15346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mAction", "I");
15446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mKeyCode, gKeyEventClassInfo.clazz,
15546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mKeyCode", "I");
15646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mScanCode, gKeyEventClassInfo.clazz,
15746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mScanCode", "I");
15846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mRepeatCount, gKeyEventClassInfo.clazz,
15946b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mRepeatCount", "I");
16046b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mFlags, gKeyEventClassInfo.clazz,
16146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mFlags", "I");
16246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mDownTime, gKeyEventClassInfo.clazz,
16346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mDownTime", "J");
16446b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mEventTime, gKeyEventClassInfo.clazz,
16546b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mEventTime", "J");
16646b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown    GET_FIELD_ID(gKeyEventClassInfo.mCharacters, gKeyEventClassInfo.clazz,
16746b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown            "mCharacters", "Ljava/lang/String;");
16846b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
1693c80a4a044865bdf1289c7896baffa1c082d835cDianne Hackborn    return AndroidRuntime::registerNativeMethods(
170c5ed5910c9ef066cec6a13bbb404ec57b1e92637Jeff Brown        env, "android/view/KeyEvent", g_methods, NELEM(g_methods));
17146b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown}
17246b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown
17346b9ac0ae2162309774a7478cd9d4e578747bfc2Jeff Brown} // namespace android
174