blob: 63830d59c24ab6c5a6122155486aa264514b0d81 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2007 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 "Input"
18
19#include "jni.h"
20#include "JNIHelp.h"
21#include <utils/misc.h>
22#include <utils/Log.h>
23
24#include <ui/EventHub.h>
25#include <utils/threads.h>
26
27#include <stdio.h>
28
29namespace android {
30
31// ----------------------------------------------------------------------------
32
33static struct input_offsets_t
34{
35 jfieldID mMinValue;
36 jfieldID mMaxValue;
37 jfieldID mFlat;
38 jfieldID mFuzz;
39
40 jfieldID mDeviceId;
41 jfieldID mType;
42 jfieldID mScancode;
43 jfieldID mKeycode;
44 jfieldID mFlags;
45 jfieldID mValue;
46 jfieldID mWhen;
47} gInputOffsets;
48
49// ----------------------------------------------------------------------------
50
51static Mutex gLock;
52static sp<EventHub> gHub;
53
54static jboolean
55android_server_KeyInputQueue_readEvent(JNIEnv* env, jobject clazz,
56 jobject event)
57{
58 gLock.lock();
59 sp<EventHub> hub = gHub;
60 if (hub == NULL) {
61 hub = new EventHub;
62 gHub = hub;
63 }
64 gLock.unlock();
65
66 int32_t deviceId;
67 int32_t type;
68 int32_t scancode, keycode;
69 uint32_t flags;
70 int32_t value;
71 nsecs_t when;
72 bool res = hub->getEvent(&deviceId, &type, &scancode, &keycode,
73 &flags, &value, &when);
74
75 env->SetIntField(event, gInputOffsets.mDeviceId, (jint)deviceId);
76 env->SetIntField(event, gInputOffsets.mType, (jint)type);
77 env->SetIntField(event, gInputOffsets.mScancode, (jint)scancode);
78 env->SetIntField(event, gInputOffsets.mKeycode, (jint)keycode);
79 env->SetIntField(event, gInputOffsets.mFlags, (jint)flags);
80 env->SetIntField(event, gInputOffsets.mValue, value);
81 env->SetLongField(event, gInputOffsets.mWhen,
82 (jlong)(nanoseconds_to_milliseconds(when)));
83
84 return res;
85}
86
87static jint
88android_server_KeyInputQueue_getDeviceClasses(JNIEnv* env, jobject clazz,
89 jint deviceId)
90{
91 jint classes = 0;
92 gLock.lock();
93 if (gHub != NULL) classes = gHub->getDeviceClasses(deviceId);
94 gLock.unlock();
95 return classes;
96}
97
98static jstring
99android_server_KeyInputQueue_getDeviceName(JNIEnv* env, jobject clazz,
100 jint deviceId)
101{
102 String8 name;
103 gLock.lock();
104 if (gHub != NULL) name = gHub->getDeviceName(deviceId);
105 gLock.unlock();
106
107 if (name.size() > 0) {
108 return env->NewStringUTF(name.string());
109 }
110 return NULL;
111}
112
113static jboolean
114android_server_KeyInputQueue_getAbsoluteInfo(JNIEnv* env, jobject clazz,
115 jint deviceId, jint axis,
116 jobject info)
117{
118 int32_t minValue, maxValue, flat, fuzz;
119 int res = -1;
120 gLock.lock();
121 if (gHub != NULL) {
122 res = gHub->getAbsoluteInfo(deviceId, axis,
123 &minValue, &maxValue, &flat, &fuzz);
124 }
125 gLock.unlock();
126
127 if (res < 0) return JNI_FALSE;
128
129 env->SetIntField(info, gInputOffsets.mMinValue, (jint)minValue);
130 env->SetIntField(info, gInputOffsets.mMaxValue, (jint)maxValue);
131 env->SetIntField(info, gInputOffsets.mFlat, (jint)flat);
132 env->SetIntField(info, gInputOffsets.mFuzz, (jint)fuzz);
133 return JNI_TRUE;
134}
135
136static jint
137android_server_KeyInputQueue_getSwitchState(JNIEnv* env, jobject clazz,
138 jint sw)
139{
140 jint st = -1;
141 gLock.lock();
142 if (gHub != NULL) st = gHub->getSwitchState(sw);
143 gLock.unlock();
144
145 return st;
146}
147
148static jint
149android_server_KeyInputQueue_getSwitchStateDevice(JNIEnv* env, jobject clazz,
150 jint deviceId, jint sw)
151{
152 jint st = -1;
153 gLock.lock();
154 if (gHub != NULL) st = gHub->getSwitchState(deviceId, sw);
155 gLock.unlock();
156
157 return st;
158}
159
160static jint
161android_server_KeyInputQueue_getScancodeState(JNIEnv* env, jobject clazz,
162 jint sw)
163{
164 jint st = -1;
165 gLock.lock();
166 if (gHub != NULL) st = gHub->getScancodeState(sw);
167 gLock.unlock();
168
169 return st;
170}
171
172static jint
173android_server_KeyInputQueue_getScancodeStateDevice(JNIEnv* env, jobject clazz,
174 jint deviceId, jint sw)
175{
176 jint st = -1;
177 gLock.lock();
178 if (gHub != NULL) st = gHub->getScancodeState(deviceId, sw);
179 gLock.unlock();
180
181 return st;
182}
183
184static jint
185android_server_KeyInputQueue_getKeycodeState(JNIEnv* env, jobject clazz,
186 jint sw)
187{
188 jint st = -1;
189 gLock.lock();
190 if (gHub != NULL) st = gHub->getKeycodeState(sw);
191 gLock.unlock();
192
193 return st;
194}
195
196static jint
197android_server_KeyInputQueue_getKeycodeStateDevice(JNIEnv* env, jobject clazz,
198 jint deviceId, jint sw)
199{
200 jint st = -1;
201 gLock.lock();
202 if (gHub != NULL) st = gHub->getKeycodeState(deviceId, sw);
203 gLock.unlock();
204
205 return st;
206}
207
208static jboolean
209android_server_KeyInputQueue_hasKeys(JNIEnv* env, jobject clazz,
210 jintArray keyCodes, jbooleanArray outFlags)
211{
212 jboolean ret = JNI_FALSE;
213
214 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
215 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
216 size_t numCodes = env->GetArrayLength(keyCodes);
217 if (numCodes == env->GetArrayLength(outFlags)) {
218 gLock.lock();
219 if (gHub != NULL) ret = gHub->hasKeys(numCodes, codes, flags);
220 gLock.unlock();
221 }
222
223 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
224 env->ReleaseIntArrayElements(keyCodes, codes, 0);
225 return ret;
226}
227
228// ----------------------------------------------------------------------------
229
230/*
231 * JNI registration.
232 */
233static JNINativeMethod gInputMethods[] = {
234 /* name, signature, funcPtr */
235 { "readEvent", "(Landroid/view/RawInputEvent;)Z",
236 (void*) android_server_KeyInputQueue_readEvent },
237 { "getDeviceClasses", "(I)I",
238 (void*) android_server_KeyInputQueue_getDeviceClasses },
239 { "getDeviceName", "(I)Ljava/lang/String;",
240 (void*) android_server_KeyInputQueue_getDeviceName },
241 { "getAbsoluteInfo", "(IILcom/android/server/InputDevice$AbsoluteInfo;)Z",
242 (void*) android_server_KeyInputQueue_getAbsoluteInfo },
243 { "getSwitchState", "(I)I",
244 (void*) android_server_KeyInputQueue_getSwitchState },
245 { "getSwitchState", "(II)I",
246 (void*) android_server_KeyInputQueue_getSwitchStateDevice },
247 { "getScancodeState", "(I)I",
248 (void*) android_server_KeyInputQueue_getScancodeState },
249 { "getScancodeState", "(II)I",
250 (void*) android_server_KeyInputQueue_getScancodeStateDevice },
251 { "getKeycodeState", "(I)I",
252 (void*) android_server_KeyInputQueue_getKeycodeState },
253 { "getKeycodeState", "(II)I",
254 (void*) android_server_KeyInputQueue_getKeycodeStateDevice },
255 { "hasKeys", "([I[Z)Z",
256 (void*) android_server_KeyInputQueue_hasKeys },
257};
258
259int register_android_server_KeyInputQueue(JNIEnv* env)
260{
261 jclass input = env->FindClass("com/android/server/KeyInputQueue");
262 LOG_FATAL_IF(input == NULL, "Unable to find class com/android/server/KeyInputQueue");
263 int res = jniRegisterNativeMethods(env, "com/android/server/KeyInputQueue",
264 gInputMethods, NELEM(gInputMethods));
265
266 jclass absoluteInfo = env->FindClass("com/android/server/InputDevice$AbsoluteInfo");
267 LOG_FATAL_IF(absoluteInfo == NULL, "Unable to find class com/android/server/InputDevice$AbsoluteInfo");
268
269 gInputOffsets.mMinValue
270 = env->GetFieldID(absoluteInfo, "minValue", "I");
271 LOG_FATAL_IF(gInputOffsets.mMinValue == NULL, "Unable to find InputDevice.AbsoluteInfo.minValue");
272
273 gInputOffsets.mMaxValue
274 = env->GetFieldID(absoluteInfo, "maxValue", "I");
275 LOG_FATAL_IF(gInputOffsets.mMaxValue == NULL, "Unable to find InputDevice.AbsoluteInfo.maxValue");
276
277 gInputOffsets.mFlat
278 = env->GetFieldID(absoluteInfo, "flat", "I");
279 LOG_FATAL_IF(gInputOffsets.mFlat == NULL, "Unable to find InputDevice.AbsoluteInfo.flat");
280
281 gInputOffsets.mFuzz
282 = env->GetFieldID(absoluteInfo, "fuzz", "I");
283 LOG_FATAL_IF(gInputOffsets.mFuzz == NULL, "Unable to find InputDevice.AbsoluteInfo.fuzz");
284
285 jclass inputEvent = env->FindClass("android/view/RawInputEvent");
286 LOG_FATAL_IF(inputEvent == NULL, "Unable to find class android/view/RawInputEvent");
287
288 gInputOffsets.mDeviceId
289 = env->GetFieldID(inputEvent, "deviceId", "I");
290 LOG_FATAL_IF(gInputOffsets.mDeviceId == NULL, "Unable to find RawInputEvent.deviceId");
291
292 gInputOffsets.mType
293 = env->GetFieldID(inputEvent, "type", "I");
294 LOG_FATAL_IF(gInputOffsets.mType == NULL, "Unable to find RawInputEvent.type");
295
296 gInputOffsets.mScancode
297 = env->GetFieldID(inputEvent, "scancode", "I");
298 LOG_FATAL_IF(gInputOffsets.mScancode == NULL, "Unable to find RawInputEvent.scancode");
299
300 gInputOffsets.mKeycode
301 = env->GetFieldID(inputEvent, "keycode", "I");
302 LOG_FATAL_IF(gInputOffsets.mKeycode == NULL, "Unable to find RawInputEvent.keycode");
303
304 gInputOffsets.mFlags
305 = env->GetFieldID(inputEvent, "flags", "I");
306 LOG_FATAL_IF(gInputOffsets.mFlags == NULL, "Unable to find RawInputEvent.flags");
307
308 gInputOffsets.mValue
309 = env->GetFieldID(inputEvent, "value", "I");
310 LOG_FATAL_IF(gInputOffsets.mValue == NULL, "Unable to find RawInputEvent.value");
311
312 gInputOffsets.mWhen
313 = env->GetFieldID(inputEvent, "when", "J");
314 LOG_FATAL_IF(gInputOffsets.mWhen == NULL, "Unable to find RawInputEvent.when");
315
316 return res;
317}
318
319}; // namespace android
320