blob: 62d51296cbbf460a0ebda83f6ab1084926317810 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright 2006, 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
Jeff Brown9f25b7f2012-04-10 14:30:49 -070017#include <android_runtime/AndroidRuntime.h>
18
Jeff Brown9d3b1a42013-07-01 19:07:15 -070019#include <input/KeyCharacterMap.h>
20#include <input/Input.h>
Jeff Brown9f25b7f2012-04-10 14:30:49 -070021#include <binder/Parcel.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022
Jeff Brown6b53e8d2010-11-10 16:03:06 -080023#include <nativehelper/jni.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024#include <nativehelper/JNIHelp.h>
25
Jeff Brown9f25b7f2012-04-10 14:30:49 -070026#include "android_os_Parcel.h"
Jeff Brown6b53e8d2010-11-10 16:03:06 -080027#include "android_view_KeyEvent.h"
28
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029namespace android {
30
Jeff Brown6b53e8d2010-11-10 16:03:06 -080031static struct {
32 jclass clazz;
Jeff Brown9f25b7f2012-04-10 14:30:49 -070033 jmethodID ctor;
34} gKeyCharacterMapClassInfo;
35
36static struct {
37 jclass clazz;
Jeff Brown6b53e8d2010-11-10 16:03:06 -080038} gKeyEventClassInfo;
39
Jeff Brown49ed71d2010-12-06 17:13:33 -080040static struct {
Jeff Brown49ed71d2010-12-06 17:13:33 -080041 jfieldID keyCode;
42 jfieldID metaState;
43} gFallbackActionClassInfo;
44
45
Jeff Brown9f25b7f2012-04-10 14:30:49 -070046class NativeKeyCharacterMap {
47public:
48 NativeKeyCharacterMap(int32_t deviceId, const sp<KeyCharacterMap>& map) :
49 mDeviceId(deviceId), mMap(map) {
Jeff Brown6b53e8d2010-11-10 16:03:06 -080050 }
Jeff Brown1e08fe92011-11-15 17:48:10 -080051
Jeff Brown9f25b7f2012-04-10 14:30:49 -070052 ~NativeKeyCharacterMap() {
53 }
54
55 inline int32_t getDeviceId() const {
56 return mDeviceId;
57 }
58
59 inline const sp<KeyCharacterMap>& getMap() const {
60 return mMap;
61 }
62
63private:
64 int32_t mDeviceId;
65 sp<KeyCharacterMap> mMap;
66};
67
68
69jobject android_view_KeyCharacterMap_create(JNIEnv* env, int32_t deviceId,
70 const sp<KeyCharacterMap>& kcm) {
71 NativeKeyCharacterMap* map = new NativeKeyCharacterMap(deviceId,
72 kcm.get() ? kcm : KeyCharacterMap::empty());
73 if (!map) {
74 return NULL;
75 }
76
77 return env->NewObject(gKeyCharacterMapClassInfo.clazz, gKeyCharacterMapClassInfo.ctor,
Ashok Bhat0c3f9212014-01-08 14:15:02 +000078 reinterpret_cast<jlong>(map));
Jeff Brown9f25b7f2012-04-10 14:30:49 -070079}
80
Ashok Bhat0c3f9212014-01-08 14:15:02 +000081static jlong nativeReadFromParcel(JNIEnv *env, jobject clazz, jobject parcelObj) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -070082 Parcel* parcel = parcelForJavaObject(env, parcelObj);
83 if (!parcel) {
84 return 0;
85 }
86
87 int32_t deviceId = parcel->readInt32();
88 if (parcel->errorCheck()) {
89 return 0;
90 }
91
92 sp<KeyCharacterMap> kcm = KeyCharacterMap::readFromParcel(parcel);
93 if (!kcm.get()) {
94 return 0;
95 }
96
97 NativeKeyCharacterMap* map = new NativeKeyCharacterMap(deviceId, kcm);
Ashok Bhat0c3f9212014-01-08 14:15:02 +000098 return reinterpret_cast<jlong>(map);
Jeff Brown9f25b7f2012-04-10 14:30:49 -070099}
100
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000101static void nativeWriteToParcel(JNIEnv* env, jobject clazz, jlong ptr, jobject parcelObj) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700102 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
103 Parcel* parcel = parcelForJavaObject(env, parcelObj);
104 if (parcel) {
105 parcel->writeInt32(map->getDeviceId());
106 map->getMap()->writeToParcel(parcel);
107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108}
109
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000110static void nativeDispose(JNIEnv *env, jobject clazz, jlong ptr) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700111 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800112 delete map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113}
114
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000115static jchar nativeGetCharacter(JNIEnv *env, jobject clazz, jlong ptr,
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800116 jint keyCode, jint metaState) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700117 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
118 return map->getMap()->getCharacter(keyCode, metaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119}
120
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000121static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800122 jint metaState, jobject fallbackActionObj) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700123 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800124 KeyCharacterMap::FallbackAction fallbackAction;
125
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700126 bool result = map->getMap()->getFallbackAction(keyCode, metaState, &fallbackAction);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800127 if (result) {
128 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.keyCode,
129 fallbackAction.keyCode);
130 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.metaState,
131 fallbackAction.metaState);
132 }
133 return result;
134}
135
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000136static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700137 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
138 return map->getMap()->getNumber(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139}
140
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000141static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode,
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800142 jcharArray charsArray, jint metaState) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700143 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800145 jsize numChars = env->GetArrayLength(charsArray);
146 jchar* chars = static_cast<jchar*>(env->GetPrimitiveArrayCritical(charsArray, NULL));
147 if (!chars) {
148 return 0;
149 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700151 char16_t result = map->getMap()->getMatch(keyCode, chars, size_t(numChars), metaState);
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800152
153 env->ReleasePrimitiveArrayCritical(charsArray, chars, JNI_ABORT);
154 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800155}
156
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000157static jchar nativeGetDisplayLabel(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700158 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
159 return map->getMap()->getDisplayLabel(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160}
161
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000162static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jlong ptr) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700163 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
164 return map->getMap()->getKeyboardType();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165}
166
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000167static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jlong ptr,
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800168 jcharArray charsArray) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700169 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800170
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800171 jchar* chars = env->GetCharArrayElements(charsArray, NULL);
172 if (!chars) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800173 return NULL;
174 }
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800175 jsize numChars = env->GetArrayLength(charsArray);
176
177 Vector<KeyEvent> events;
178 jobjectArray result = NULL;
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700179 if (map->getMap()->getEvents(map->getDeviceId(), chars, size_t(numChars), events)) {
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800180 result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL);
181 if (result) {
182 for (size_t i = 0; i < events.size(); i++) {
183 jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i));
184 if (!keyEventObj) break; // threw OOM exception
185 env->SetObjectArrayElement(result, jsize(i), keyEventObj);
186 env->DeleteLocalRef(keyEventObj);
187 }
188 }
189 }
190
191 env->ReleaseCharArrayElements(charsArray, chars, JNI_ABORT);
192 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800193}
194
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800195
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800196/*
197 * JNI registration.
198 */
199
200static JNINativeMethod g_methods[] = {
201 /* name, signature, funcPtr */
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000202 { "nativeReadFromParcel", "(Landroid/os/Parcel;)J",
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700203 (void*)nativeReadFromParcel },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000204 { "nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700205 (void*)nativeWriteToParcel },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000206 { "nativeDispose", "(J)V",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800207 (void*)nativeDispose },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000208 { "nativeGetCharacter", "(JII)C",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800209 (void*)nativeGetCharacter },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000210 { "nativeGetFallbackAction", "(JIILandroid/view/KeyCharacterMap$FallbackAction;)Z",
Jeff Brown49ed71d2010-12-06 17:13:33 -0800211 (void*)nativeGetFallbackAction },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000212 { "nativeGetNumber", "(JI)C",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800213 (void*)nativeGetNumber },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000214 { "nativeGetMatch", "(JI[CI)C",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800215 (void*)nativeGetMatch },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000216 { "nativeGetDisplayLabel", "(JI)C",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800217 (void*)nativeGetDisplayLabel },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000218 { "nativeGetKeyboardType", "(J)I",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800219 (void*)nativeGetKeyboardType },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000220 { "nativeGetEvents", "(J[C)[Landroid/view/KeyEvent;",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800221 (void*)nativeGetEvents },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800222};
223
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800224#define FIND_CLASS(var, className) \
225 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800226 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800227
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700228#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
229 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
230 LOG_FATAL_IF(! var, "Unable to find method " methodName);
231
Jeff Brown49ed71d2010-12-06 17:13:33 -0800232#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
233 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
234 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
235
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700236int register_android_view_KeyCharacterMap(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800237{
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700238 FIND_CLASS(gKeyCharacterMapClassInfo.clazz, "android/view/KeyCharacterMap");
239 gKeyCharacterMapClassInfo.clazz = jclass(env->NewGlobalRef(gKeyCharacterMapClassInfo.clazz));
240
241 GET_METHOD_ID(gKeyCharacterMapClassInfo.ctor, gKeyCharacterMapClassInfo.clazz,
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000242 "<init>", "(J)V");
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700243
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800244 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800245 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800247 jclass clazz;
248 FIND_CLASS(clazz, "android/view/KeyCharacterMap$FallbackAction");
Jeff Brown49ed71d2010-12-06 17:13:33 -0800249
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800250 GET_FIELD_ID(gFallbackActionClassInfo.keyCode, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800251 "keyCode", "I");
252
Carl Shapiro17cc33a2011-03-05 20:53:16 -0800253 GET_FIELD_ID(gFallbackActionClassInfo.metaState, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800254 "metaState", "I");
255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800256 return AndroidRuntime::registerNativeMethods(env,
257 "android/view/KeyCharacterMap", g_methods, NELEM(g_methods));
258}
259
260}; // namespace android