Home | History | Annotate | Download | only in jni
      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 <nativehelper/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 <nativehelper/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