blob: e5519a752c393b24863b633c5ec054af3bd7224f [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
Andreas Gampe987f79f2014-11-18 17:29:46 -080029#include "core_jni_helpers.h"
30
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031namespace android {
32
Jeff Brown6b53e8d2010-11-10 16:03:06 -080033static struct {
34 jclass clazz;
Jeff Brown9f25b7f2012-04-10 14:30:49 -070035 jmethodID ctor;
36} gKeyCharacterMapClassInfo;
37
38static struct {
39 jclass clazz;
Jeff Brown6b53e8d2010-11-10 16:03:06 -080040} gKeyEventClassInfo;
41
Jeff Brown49ed71d2010-12-06 17:13:33 -080042static struct {
Jeff Brown49ed71d2010-12-06 17:13:33 -080043 jfieldID keyCode;
44 jfieldID metaState;
45} gFallbackActionClassInfo;
46
47
Jeff Brown9f25b7f2012-04-10 14:30:49 -070048class NativeKeyCharacterMap {
49public:
50 NativeKeyCharacterMap(int32_t deviceId, const sp<KeyCharacterMap>& map) :
51 mDeviceId(deviceId), mMap(map) {
Jeff Brown6b53e8d2010-11-10 16:03:06 -080052 }
Jeff Brown1e08fe92011-11-15 17:48:10 -080053
Jeff Brown9f25b7f2012-04-10 14:30:49 -070054 ~NativeKeyCharacterMap() {
55 }
56
57 inline int32_t getDeviceId() const {
58 return mDeviceId;
59 }
60
61 inline const sp<KeyCharacterMap>& getMap() const {
62 return mMap;
63 }
64
65private:
66 int32_t mDeviceId;
67 sp<KeyCharacterMap> mMap;
68};
69
70
71jobject android_view_KeyCharacterMap_create(JNIEnv* env, int32_t deviceId,
72 const sp<KeyCharacterMap>& kcm) {
73 NativeKeyCharacterMap* map = new NativeKeyCharacterMap(deviceId,
74 kcm.get() ? kcm : KeyCharacterMap::empty());
75 if (!map) {
76 return NULL;
77 }
78
79 return env->NewObject(gKeyCharacterMapClassInfo.clazz, gKeyCharacterMapClassInfo.ctor,
Ashok Bhat0c3f9212014-01-08 14:15:02 +000080 reinterpret_cast<jlong>(map));
Jeff Brown9f25b7f2012-04-10 14:30:49 -070081}
82
Ashok Bhat0c3f9212014-01-08 14:15:02 +000083static jlong nativeReadFromParcel(JNIEnv *env, jobject clazz, jobject parcelObj) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -070084 Parcel* parcel = parcelForJavaObject(env, parcelObj);
85 if (!parcel) {
86 return 0;
87 }
88
89 int32_t deviceId = parcel->readInt32();
90 if (parcel->errorCheck()) {
91 return 0;
92 }
93
94 sp<KeyCharacterMap> kcm = KeyCharacterMap::readFromParcel(parcel);
95 if (!kcm.get()) {
96 return 0;
97 }
98
99 NativeKeyCharacterMap* map = new NativeKeyCharacterMap(deviceId, kcm);
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000100 return reinterpret_cast<jlong>(map);
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700101}
102
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000103static void nativeWriteToParcel(JNIEnv* env, jobject clazz, jlong ptr, jobject parcelObj) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700104 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
105 Parcel* parcel = parcelForJavaObject(env, parcelObj);
106 if (parcel) {
107 parcel->writeInt32(map->getDeviceId());
108 map->getMap()->writeToParcel(parcel);
109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110}
111
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000112static void nativeDispose(JNIEnv *env, jobject clazz, jlong ptr) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700113 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800114 delete map;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115}
116
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000117static jchar nativeGetCharacter(JNIEnv *env, jobject clazz, jlong ptr,
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800118 jint keyCode, jint metaState) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700119 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
120 return map->getMap()->getCharacter(keyCode, metaState);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121}
122
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000123static jboolean nativeGetFallbackAction(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800124 jint metaState, jobject fallbackActionObj) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700125 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800126 KeyCharacterMap::FallbackAction fallbackAction;
127
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700128 bool result = map->getMap()->getFallbackAction(keyCode, metaState, &fallbackAction);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800129 if (result) {
130 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.keyCode,
131 fallbackAction.keyCode);
132 env->SetIntField(fallbackActionObj, gFallbackActionClassInfo.metaState,
133 fallbackAction.metaState);
134 }
135 return result;
136}
137
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000138static jchar nativeGetNumber(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700139 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
140 return map->getMap()->getNumber(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800141}
142
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000143static jchar nativeGetMatch(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode,
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800144 jcharArray charsArray, jint metaState) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700145 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800147 jsize numChars = env->GetArrayLength(charsArray);
148 jchar* chars = static_cast<jchar*>(env->GetPrimitiveArrayCritical(charsArray, NULL));
149 if (!chars) {
150 return 0;
151 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800152
Dan Albert66987492014-11-20 11:41:21 -0800153 char16_t result = map->getMap()->getMatch(
154 keyCode, reinterpret_cast<char16_t*>(chars), size_t(numChars),
155 metaState);
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800156
157 env->ReleasePrimitiveArrayCritical(charsArray, chars, JNI_ABORT);
158 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159}
160
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000161static jchar nativeGetDisplayLabel(JNIEnv *env, jobject clazz, jlong ptr, jint keyCode) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700162 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
163 return map->getMap()->getDisplayLabel(keyCode);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164}
165
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000166static jint nativeGetKeyboardType(JNIEnv *env, jobject clazz, jlong ptr) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700167 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
168 return map->getMap()->getKeyboardType();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800169}
170
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000171static jobjectArray nativeGetEvents(JNIEnv *env, jobject clazz, jlong ptr,
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800172 jcharArray charsArray) {
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700173 NativeKeyCharacterMap* map = reinterpret_cast<NativeKeyCharacterMap*>(ptr);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800174
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800175 jchar* chars = env->GetCharArrayElements(charsArray, NULL);
176 if (!chars) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800177 return NULL;
178 }
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800179 jsize numChars = env->GetArrayLength(charsArray);
180
181 Vector<KeyEvent> events;
182 jobjectArray result = NULL;
Dan Albert66987492014-11-20 11:41:21 -0800183 if (map->getMap()->getEvents(map->getDeviceId(),
184 reinterpret_cast<char16_t*>(chars),
185 size_t(numChars), events)) {
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800186 result = env->NewObjectArray(jsize(events.size()), gKeyEventClassInfo.clazz, NULL);
187 if (result) {
188 for (size_t i = 0; i < events.size(); i++) {
189 jobject keyEventObj = android_view_KeyEvent_fromNative(env, &events.itemAt(i));
190 if (!keyEventObj) break; // threw OOM exception
191 env->SetObjectArrayElement(result, jsize(i), keyEventObj);
192 env->DeleteLocalRef(keyEventObj);
193 }
194 }
195 }
196
197 env->ReleaseCharArrayElements(charsArray, chars, JNI_ABORT);
198 return result;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800199}
200
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202/*
203 * JNI registration.
204 */
205
Daniel Micay76f6a862015-09-19 17:31:01 -0400206static const JNINativeMethod g_methods[] = {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 /* name, signature, funcPtr */
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000208 { "nativeReadFromParcel", "(Landroid/os/Parcel;)J",
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700209 (void*)nativeReadFromParcel },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000210 { "nativeWriteToParcel", "(JLandroid/os/Parcel;)V",
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700211 (void*)nativeWriteToParcel },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000212 { "nativeDispose", "(J)V",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800213 (void*)nativeDispose },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000214 { "nativeGetCharacter", "(JII)C",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800215 (void*)nativeGetCharacter },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000216 { "nativeGetFallbackAction", "(JIILandroid/view/KeyCharacterMap$FallbackAction;)Z",
Jeff Brown49ed71d2010-12-06 17:13:33 -0800217 (void*)nativeGetFallbackAction },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000218 { "nativeGetNumber", "(JI)C",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800219 (void*)nativeGetNumber },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000220 { "nativeGetMatch", "(JI[CI)C",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800221 (void*)nativeGetMatch },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000222 { "nativeGetDisplayLabel", "(JI)C",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800223 (void*)nativeGetDisplayLabel },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000224 { "nativeGetKeyboardType", "(J)I",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800225 (void*)nativeGetKeyboardType },
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000226 { "nativeGetEvents", "(J[C)[Landroid/view/KeyEvent;",
Jeff Brown6b53e8d2010-11-10 16:03:06 -0800227 (void*)nativeGetEvents },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228};
229
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700230int register_android_view_KeyCharacterMap(JNIEnv* env)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800231{
Andreas Gampe987f79f2014-11-18 17:29:46 -0800232 gKeyCharacterMapClassInfo.clazz = FindClassOrDie(env, "android/view/KeyCharacterMap");
233 gKeyCharacterMapClassInfo.clazz = MakeGlobalRefOrDie(env, gKeyCharacterMapClassInfo.clazz);
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700234
Andreas Gampe987f79f2014-11-18 17:29:46 -0800235 gKeyCharacterMapClassInfo.ctor = GetMethodIDOrDie(env, gKeyCharacterMapClassInfo.clazz,
Ashok Bhat0c3f9212014-01-08 14:15:02 +0000236 "<init>", "(J)V");
Jeff Brown9f25b7f2012-04-10 14:30:49 -0700237
Andreas Gampe987f79f2014-11-18 17:29:46 -0800238 gKeyEventClassInfo.clazz = FindClassOrDie(env, "android/view/KeyEvent");
239 gKeyEventClassInfo.clazz = MakeGlobalRefOrDie(env, gKeyEventClassInfo.clazz);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800240
Andreas Gampe987f79f2014-11-18 17:29:46 -0800241 jclass clazz = FindClassOrDie(env, "android/view/KeyCharacterMap$FallbackAction");
Jeff Brown49ed71d2010-12-06 17:13:33 -0800242
Andreas Gampe987f79f2014-11-18 17:29:46 -0800243 gFallbackActionClassInfo.keyCode = GetFieldIDOrDie(env, clazz, "keyCode", "I");
244 gFallbackActionClassInfo.metaState = GetFieldIDOrDie(env, clazz, "metaState", "I");
Jeff Brown49ed71d2010-12-06 17:13:33 -0800245
Andreas Gampe987f79f2014-11-18 17:29:46 -0800246 return RegisterMethodsOrDie(env, "android/view/KeyCharacterMap", g_methods, NELEM(g_methods));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800247}
248
249}; // namespace android