blob: 1a6119a3794c60811c1273edf81a9b4e062361f6 [file] [log] [blame]
Jeff Brown46b9ac02010-04-22 18:58:52 -07001/*
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 "InputManager-JNI"
18
Jeff Brown9c3cda02010-06-15 01:31:58 -070019//#define LOG_NDEBUG 0
20
21// Log debug messages about InputReaderPolicy
22#define DEBUG_INPUT_READER_POLICY 1
23
24// Log debug messages about InputDispatcherPolicy
25#define DEBUG_INPUT_DISPATCHER_POLICY 1
26
27
Jeff Brown46b9ac02010-04-22 18:58:52 -070028#include "JNIHelp.h"
29#include "jni.h"
30#include <android_runtime/AndroidRuntime.h>
Jeff Brown9c3cda02010-06-15 01:31:58 -070031#include <ui/InputReader.h>
32#include <ui/InputDispatcher.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070033#include <ui/InputManager.h>
34#include <ui/InputTransport.h>
35#include <utils/Log.h>
36#include <utils/threads.h>
37#include "../../core/jni/android_view_KeyEvent.h"
38#include "../../core/jni/android_view_MotionEvent.h"
39#include "../../core/jni/android_view_InputChannel.h"
40#include "../../core/jni/android_view_InputTarget.h"
41
42namespace android {
43
Jeff Brown9c3cda02010-06-15 01:31:58 -070044// ----------------------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -070045
46static struct {
47 jclass clazz;
48
49 jmethodID isScreenOn;
50 jmethodID isScreenBright;
51 jmethodID notifyConfigurationChanged;
52 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070053 jmethodID notifyInputChannelBroken;
54 jmethodID notifyInputChannelANR;
55 jmethodID notifyInputChannelRecoveredFromANR;
Jeff Brown46b9ac02010-04-22 18:58:52 -070056 jmethodID virtualKeyFeedback;
57 jmethodID hackInterceptKey;
58 jmethodID goToSleep;
59 jmethodID pokeUserActivityForKey;
60 jmethodID notifyAppSwitchComing;
61 jmethodID filterTouchEvents;
62 jmethodID filterJumpyTouchEvents;
63 jmethodID getVirtualKeyDefinitions;
64 jmethodID getExcludedDeviceNames;
65 jmethodID getKeyEventTargets;
66 jmethodID getMotionEventTargets;
67} gCallbacksClassInfo;
68
69static struct {
70 jclass clazz;
71
72 jfieldID scanCode;
73 jfieldID centerX;
74 jfieldID centerY;
75 jfieldID width;
76 jfieldID height;
77} gVirtualKeyDefinitionClassInfo;
78
Jeff Brown7fbdc842010-06-17 20:52:56 -070079static struct {
80 jclass clazz;
81
82 jmethodID ctor;
83 jfieldID mArray;
84} gInputTargetListClassInfo;
85
Jeff Brown9c3cda02010-06-15 01:31:58 -070086// ----------------------------------------------------------------------------
87
88class NativeInputManager : public virtual RefBase,
89 public virtual InputReaderPolicyInterface,
90 public virtual InputDispatcherPolicyInterface {
91protected:
92 virtual ~NativeInputManager();
93
94public:
95 NativeInputManager(jobject callbacksObj);
96
97 inline sp<InputManager> getInputManager() const { return mInputManager; }
98
99 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
100 void setDisplayOrientation(int32_t displayId, int32_t orientation);
101
Jeff Brown7fbdc842010-06-17 20:52:56 -0700102 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
103 jweak inputChannelObjWeak);
104 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
105
Jeff Brown9c3cda02010-06-15 01:31:58 -0700106 /* --- InputReaderPolicyInterface implementation --- */
107
108 virtual bool getDisplayInfo(int32_t displayId,
109 int32_t* width, int32_t* height, int32_t* orientation);
110 virtual void virtualKeyFeedback(nsecs_t when, int32_t deviceId,
111 int32_t action, int32_t flags, int32_t keyCode,
112 int32_t scanCode, int32_t metaState, nsecs_t downTime);
113 virtual int32_t interceptKey(nsecs_t when, int32_t deviceId,
114 bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags);
115 virtual int32_t interceptTrackball(nsecs_t when, bool buttonChanged, bool buttonDown,
116 bool rolled);
117 virtual int32_t interceptTouch(nsecs_t when);
118 virtual int32_t interceptSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue);
119 virtual bool filterTouchEvents();
120 virtual bool filterJumpyTouchEvents();
121 virtual void getVirtualKeyDefinitions(const String8& deviceName,
122 Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions);
123 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
124
125 /* --- InputDispatcherPolicyInterface implementation --- */
126
127 virtual void notifyConfigurationChanged(nsecs_t when);
128 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700129 virtual bool notifyInputChannelANR(const sp<InputChannel>& inputChannel,
130 nsecs_t& outNewTimeout);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700131 virtual void notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel);
132 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brown7fbdc842010-06-17 20:52:56 -0700133 virtual int32_t getKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
134 int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets);
135 virtual int32_t getMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
136 int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700137
138private:
139 sp<InputManager> mInputManager;
140
141 jobject mCallbacksObj;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700142 jobject mReusableInputTargetListObj;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700143
144 // Cached filtering policies.
145 int32_t mFilterTouchEvents;
146 int32_t mFilterJumpyTouchEvents;
147
148 // Cached display state. (lock mDisplayLock)
149 Mutex mDisplayLock;
150 int32_t mDisplayWidth, mDisplayHeight;
151 int32_t mDisplayOrientation;
152
153 // Callbacks.
154 bool isScreenOn();
155 bool isScreenBright();
156
Jeff Brown7fbdc842010-06-17 20:52:56 -0700157 // Weak references to all currently registered input channels by receive fd.
158 Mutex mInputChannelRegistryLock;
159 KeyedVector<int, jweak> mInputChannelObjWeakByReceiveFd;
160
161 jobject getInputChannelObjLocal(JNIEnv* env, const sp<InputChannel>& inputChannel);
162
Jeff Brown9c3cda02010-06-15 01:31:58 -0700163 static inline JNIEnv* jniEnv() {
164 return AndroidRuntime::getJNIEnv();
165 }
166
167 static bool isAppSwitchKey(int32_t keyCode);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700168 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
169 static void populateInputTargets(JNIEnv* env, jobject inputTargetListObj,
170 Vector<InputTarget>& outTargets);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700171};
172
173// ----------------------------------------------------------------------------
174
175NativeInputManager::NativeInputManager(jobject callbacksObj) :
176 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
177 mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(-1) {
178 JNIEnv* env = jniEnv();
179
180 mCallbacksObj = env->NewGlobalRef(callbacksObj);
181
Jeff Brown7fbdc842010-06-17 20:52:56 -0700182 jobject inputTargetListObj = env->NewObject(gInputTargetListClassInfo.clazz,
183 gInputTargetListClassInfo.ctor);
184 mReusableInputTargetListObj = env->NewGlobalRef(inputTargetListObj);
185 env->DeleteLocalRef(inputTargetListObj);
186
Jeff Brown9c3cda02010-06-15 01:31:58 -0700187 sp<EventHub> eventHub = new EventHub();
188 mInputManager = new InputManager(eventHub, this, this);
189}
190
191NativeInputManager::~NativeInputManager() {
192 JNIEnv* env = jniEnv();
193
194 env->DeleteGlobalRef(mCallbacksObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700195 env->DeleteGlobalRef(mReusableInputTargetListObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700196}
197
198bool NativeInputManager::isAppSwitchKey(int32_t keyCode) {
199 return keyCode == KEYCODE_HOME || keyCode == KEYCODE_ENDCALL;
200}
201
Jeff Brown7fbdc842010-06-17 20:52:56 -0700202bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700203 if (env->ExceptionCheck()) {
204 LOGE("An exception was thrown by callback '%s'.", methodName);
205 LOGE_EX(env);
206 env->ExceptionClear();
207 return true;
208 }
209 return false;
210}
211
212void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
213 if (displayId == 0) {
214 AutoMutex _l(mDisplayLock);
215
216 mDisplayWidth = width;
217 mDisplayHeight = height;
218 }
219}
220
221void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
222 if (displayId == 0) {
223 AutoMutex _l(mDisplayLock);
224
225 mDisplayOrientation = orientation;
226 }
227}
228
Jeff Brown7fbdc842010-06-17 20:52:56 -0700229status_t NativeInputManager::registerInputChannel(JNIEnv* env,
230 const sp<InputChannel>& inputChannel, jobject inputChannelObj) {
231 jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
232 if (! inputChannelObjWeak) {
233 LOGE("Could not create weak reference for input channel.");
234 LOGE_EX(env);
235 return NO_MEMORY;
236 }
237
238 status_t status;
239 {
240 AutoMutex _l(mInputChannelRegistryLock);
241
242 ssize_t index = mInputChannelObjWeakByReceiveFd.indexOfKey(
243 inputChannel->getReceivePipeFd());
244 if (index >= 0) {
245 LOGE("Input channel object '%s' has already been registered",
246 inputChannel->getName().string());
247 status = INVALID_OPERATION;
248 goto DeleteWeakRef;
249 }
250
251 mInputChannelObjWeakByReceiveFd.add(inputChannel->getReceivePipeFd(),
252 inputChannelObjWeak);
253 }
254
255 status = mInputManager->registerInputChannel(inputChannel);
256 if (! status) {
257 return OK;
258 }
259
260 {
261 AutoMutex _l(mInputChannelRegistryLock);
262 mInputChannelObjWeakByReceiveFd.removeItem(inputChannel->getReceivePipeFd());
263 }
264
265DeleteWeakRef:
266 env->DeleteWeakGlobalRef(inputChannelObjWeak);
267 return status;
268}
269
270status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
271 const sp<InputChannel>& inputChannel) {
272 jweak inputChannelObjWeak;
273 {
274 AutoMutex _l(mInputChannelRegistryLock);
275
276 ssize_t index = mInputChannelObjWeakByReceiveFd.indexOfKey(
277 inputChannel->getReceivePipeFd());
278 if (index < 0) {
279 LOGE("Input channel object '%s' is not currently registered",
280 inputChannel->getName().string());
281 return INVALID_OPERATION;
282 }
283
284 inputChannelObjWeak = mInputChannelObjWeakByReceiveFd.valueAt(index);
285 mInputChannelObjWeakByReceiveFd.removeItemsAt(index);
286 }
287
288 env->DeleteWeakGlobalRef(inputChannelObjWeak);
289
290 return mInputManager->unregisterInputChannel(inputChannel);
291}
292
293jobject NativeInputManager::getInputChannelObjLocal(JNIEnv* env,
294 const sp<InputChannel>& inputChannel) {
295 {
296 AutoMutex _l(mInputChannelRegistryLock);
297
298 ssize_t index = mInputChannelObjWeakByReceiveFd.indexOfKey(
299 inputChannel->getReceivePipeFd());
300 if (index < 0) {
301 return NULL;
302 }
303
304 jweak inputChannelObjWeak = mInputChannelObjWeakByReceiveFd.valueAt(index);
305 return env->NewLocalRef(inputChannelObjWeak);
306 }
307}
308
Jeff Brown9c3cda02010-06-15 01:31:58 -0700309bool NativeInputManager::getDisplayInfo(int32_t displayId,
310 int32_t* width, int32_t* height, int32_t* orientation) {
311 bool result = false;
312 if (displayId == 0) {
313 AutoMutex _l(mDisplayLock);
314
315 if (mDisplayWidth > 0) {
316 *width = mDisplayWidth;
317 *height = mDisplayHeight;
318 *orientation = mDisplayOrientation;
319 result = true;
320 }
321 }
322 return result;
323}
324
325bool NativeInputManager::isScreenOn() {
326 JNIEnv* env = jniEnv();
327
328 jboolean result = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.isScreenOn);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700329 if (checkAndClearExceptionFromCallback(env, "isScreenOn")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700330 return true;
331 }
332 return result;
333}
334
335bool NativeInputManager::isScreenBright() {
336 JNIEnv* env = jniEnv();
337
338 jboolean result = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.isScreenBright);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700339 if (checkAndClearExceptionFromCallback(env, "isScreenBright")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700340 return true;
341 }
342 return result;
343}
344
345void NativeInputManager::virtualKeyFeedback(nsecs_t when, int32_t deviceId,
346 int32_t action, int32_t flags, int32_t keyCode,
347 int32_t scanCode, int32_t metaState, nsecs_t downTime) {
348#if DEBUG_INPUT_READER_POLICY
349 LOGD("virtualKeyFeedback - when=%lld, deviceId=%d, action=%d, flags=%d, keyCode=%d, "
350 "scanCode=%d, metaState=%d, downTime=%lld",
351 when, deviceId, action, flags, keyCode, scanCode, metaState, downTime);
352#endif
353
354 JNIEnv* env = jniEnv();
355
356 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.virtualKeyFeedback,
357 when, deviceId, action, flags, keyCode, scanCode, metaState, downTime);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700358 checkAndClearExceptionFromCallback(env, "virtualKeyFeedback");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700359}
360
361int32_t NativeInputManager::interceptKey(nsecs_t when,
362 int32_t deviceId, bool down, int32_t keyCode, int32_t scanCode, uint32_t policyFlags) {
363#if DEBUG_INPUT_READER_POLICY
364 LOGD("interceptKey - when=%lld, deviceId=%d, down=%d, keyCode=%d, scanCode=%d, "
365 "policyFlags=%d",
366 when, deviceId, down, keyCode, scanCode, policyFlags);
367#endif
368
369 const int32_t WM_ACTION_PASS_TO_USER = 1;
370 const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
371 const int32_t WM_ACTION_GO_TO_SLEEP = 4;
372
373 JNIEnv* env = jniEnv();
374
375 bool isScreenOn = this->isScreenOn();
376 bool isScreenBright = this->isScreenBright();
377
378 jint wmActions = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.hackInterceptKey,
379 deviceId, EV_KEY, scanCode, keyCode, policyFlags, down ? 1 : 0, when, isScreenOn);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700380 if (checkAndClearExceptionFromCallback(env, "hackInterceptKey")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700381 wmActions = 0;
382 }
383
384 int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
385 if (! isScreenOn) {
386 // Key presses and releases wake the device.
387 actions |= InputReaderPolicyInterface::ACTION_WOKE_HERE;
388 }
389
390 if (! isScreenBright) {
391 // Key presses and releases brighten the screen if dimmed.
392 actions |= InputReaderPolicyInterface::ACTION_BRIGHT_HERE;
393 }
394
395 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
396 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.goToSleep, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700397 checkAndClearExceptionFromCallback(env, "goToSleep");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700398 }
399
400 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
401 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.pokeUserActivityForKey, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700402 checkAndClearExceptionFromCallback(env, "pokeUserActivityForKey");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700403 }
404
405 if (wmActions & WM_ACTION_PASS_TO_USER) {
406 actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700407
Jeff Brown9c3cda02010-06-15 01:31:58 -0700408 if (down && isAppSwitchKey(keyCode)) {
409 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyAppSwitchComing);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700410 checkAndClearExceptionFromCallback(env, "notifyAppSwitchComing");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700411
412 actions |= InputReaderPolicyInterface::ACTION_APP_SWITCH_COMING;
413 }
414 }
415 return actions;
416}
417
418int32_t NativeInputManager::interceptTouch(nsecs_t when) {
419#if DEBUG_INPUT_READER_POLICY
420 LOGD("interceptTouch - when=%lld", when);
421#endif
422
Jeff Brown5c225b12010-06-16 01:53:36 -0700423 int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
424 if (isScreenOn()) {
425 // Only dispatch touch events when the device is awake.
426 actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700427 }
428
Jeff Brown5c225b12010-06-16 01:53:36 -0700429 if (! isScreenBright()) {
430 // Brighten the screen if dimmed.
431 actions |= InputReaderPolicyInterface::ACTION_BRIGHT_HERE;
432 }
433
434 return actions;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700435}
436
437int32_t NativeInputManager::interceptTrackball(nsecs_t when,
438 bool buttonChanged, bool buttonDown, bool rolled) {
439#if DEBUG_INPUT_READER_POLICY
440 LOGD("interceptTrackball - when=%lld, buttonChanged=%d, buttonDown=%d, rolled=%d",
441 when, buttonChanged, buttonDown, rolled);
442#endif
443
Jeff Brown5c225b12010-06-16 01:53:36 -0700444 int32_t actions = InputReaderPolicyInterface::ACTION_NONE;
445 if (isScreenOn()) {
446 // Only dispatch trackball events when the device is awake.
447 actions |= InputReaderPolicyInterface::ACTION_DISPATCH;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700448 }
449
Jeff Brown5c225b12010-06-16 01:53:36 -0700450 if (! isScreenBright()) {
451 // Brighten the screen if dimmed.
452 actions |= InputReaderPolicyInterface::ACTION_BRIGHT_HERE;
453 }
454
455 return actions;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700456}
457
458int32_t NativeInputManager::interceptSwitch(nsecs_t when, int32_t switchCode,
459 int32_t switchValue) {
460#if DEBUG_INPUT_READER_POLICY
461 LOGD("interceptSwitch - when=%lld, switchCode=%d, switchValue=%d",
462 when, switchCode, switchValue);
463#endif
464
465 JNIEnv* env = jniEnv();
466
467 switch (switchCode) {
468 case SW_LID:
469 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
470 when, switchValue == 0);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700471 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700472 break;
473 }
474
475 return InputReaderPolicyInterface::ACTION_NONE;
476}
477
478bool NativeInputManager::filterTouchEvents() {
479 if (mFilterTouchEvents < 0) {
480 JNIEnv* env = jniEnv();
481
482 jboolean result = env->CallBooleanMethod(mCallbacksObj,
483 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700484 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700485 result = false;
486 }
487
488 mFilterTouchEvents = result ? 1 : 0;
489 }
490 return mFilterTouchEvents;
491}
492
493bool NativeInputManager::filterJumpyTouchEvents() {
494 if (mFilterJumpyTouchEvents < 0) {
495 JNIEnv* env = jniEnv();
496
497 jboolean result = env->CallBooleanMethod(mCallbacksObj,
498 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700499 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700500 result = false;
501 }
502
503 mFilterJumpyTouchEvents = result ? 1 : 0;
504 }
505 return mFilterJumpyTouchEvents;
506}
507
508void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
509 Vector<InputReaderPolicyInterface::VirtualKeyDefinition>& outVirtualKeyDefinitions) {
510 JNIEnv* env = jniEnv();
511
512 jstring deviceNameStr = env->NewStringUTF(deviceName.string());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700513 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700514 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
515 gCallbacksClassInfo.getVirtualKeyDefinitions, deviceNameStr));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700516 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700517 jsize length = env->GetArrayLength(result);
518 for (jsize i = 0; i < length; i++) {
519 jobject item = env->GetObjectArrayElement(result, i);
520
521 outVirtualKeyDefinitions.add();
522 outVirtualKeyDefinitions.editTop().scanCode =
523 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.scanCode));
524 outVirtualKeyDefinitions.editTop().centerX =
525 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerX));
526 outVirtualKeyDefinitions.editTop().centerY =
527 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerY));
528 outVirtualKeyDefinitions.editTop().width =
529 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.width));
530 outVirtualKeyDefinitions.editTop().height =
531 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.height));
532
533 env->DeleteLocalRef(item);
534 }
535 env->DeleteLocalRef(result);
536 }
537 env->DeleteLocalRef(deviceNameStr);
538 }
539}
540
541void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
542 JNIEnv* env = jniEnv();
543
544 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
545 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700546 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700547 jsize length = env->GetArrayLength(result);
548 for (jsize i = 0; i < length; i++) {
549 jstring item = jstring(env->GetObjectArrayElement(result, i));
550
551 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
552 outExcludedDeviceNames.add(String8(deviceNameChars));
553 env->ReleaseStringUTFChars(item, deviceNameChars);
554
555 env->DeleteLocalRef(item);
556 }
557 env->DeleteLocalRef(result);
558 }
559}
560
561void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
562#if DEBUG_INPUT_DISPATCHER_POLICY
563 LOGD("notifyConfigurationChanged - when=%lld", when);
564#endif
565
566 JNIEnv* env = jniEnv();
567
568 InputConfiguration config;
569 mInputManager->getInputConfiguration(& config);
570
571 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged,
572 when, config.touchScreen, config.keyboard, config.navigation);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700573 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700574}
575
576void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
577#if DEBUG_INPUT_DISPATCHER_POLICY
578 LOGD("notifyInputChannelBroken - inputChannel='%s'", inputChannel->getName().string());
579#endif
580
Jeff Brown7fbdc842010-06-17 20:52:56 -0700581 JNIEnv* env = jniEnv();
582
583 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
584 if (inputChannelObjLocal) {
585 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
586 inputChannelObjLocal);
587 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
588
589 env->DeleteLocalRef(inputChannelObjLocal);
590 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700591}
592
Jeff Brown7fbdc842010-06-17 20:52:56 -0700593bool NativeInputManager::notifyInputChannelANR(const sp<InputChannel>& inputChannel,
594 nsecs_t& outNewTimeout) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700595#if DEBUG_INPUT_DISPATCHER_POLICY
596 LOGD("notifyInputChannelANR - inputChannel='%s'",
597 inputChannel->getName().string());
598#endif
599
Jeff Brown7fbdc842010-06-17 20:52:56 -0700600 JNIEnv* env = jniEnv();
601
602 jlong newTimeout;
603 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
604 if (inputChannelObjLocal) {
605 newTimeout = env->CallLongMethod(mCallbacksObj,
606 gCallbacksClassInfo.notifyInputChannelANR, inputChannelObjLocal);
607 if (checkAndClearExceptionFromCallback(env, "notifyInputChannelANR")) {
608 newTimeout = -2;
609 }
610
611 env->DeleteLocalRef(inputChannelObjLocal);
612 } else {
613 newTimeout = -2;
614 }
615
616 if (newTimeout == -2) {
617 return false; // abort
618 }
619
620 outNewTimeout = newTimeout;
621 return true; // resume
Jeff Brown9c3cda02010-06-15 01:31:58 -0700622}
623
624void NativeInputManager::notifyInputChannelRecoveredFromANR(const sp<InputChannel>& inputChannel) {
625#if DEBUG_INPUT_DISPATCHER_POLICY
626 LOGD("notifyInputChannelRecoveredFromANR - inputChannel='%s'",
627 inputChannel->getName().string());
628#endif
629
Jeff Brown7fbdc842010-06-17 20:52:56 -0700630 JNIEnv* env = jniEnv();
631
632 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
633 if (inputChannelObjLocal) {
634 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelRecoveredFromANR,
635 inputChannelObjLocal);
636 checkAndClearExceptionFromCallback(env, "notifyInputChannelRecoveredFromANR");
637
638 env->DeleteLocalRef(inputChannelObjLocal);
639 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700640}
641
642nsecs_t NativeInputManager::getKeyRepeatTimeout() {
643 if (! isScreenOn()) {
644 // Disable key repeat when the screen is off.
645 return -1;
646 } else {
647 // TODO use ViewConfiguration.getLongPressTimeout()
648 return milliseconds_to_nanoseconds(500);
649 }
650}
651
Jeff Brown7fbdc842010-06-17 20:52:56 -0700652int32_t NativeInputManager::getKeyEventTargets(KeyEvent* keyEvent, uint32_t policyFlags,
653 int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700654#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown7fbdc842010-06-17 20:52:56 -0700655 LOGD("getKeyEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
656 policyFlags, injectorPid, injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700657#endif
658
659 JNIEnv* env = jniEnv();
660
Jeff Brown7fbdc842010-06-17 20:52:56 -0700661 jint injectionResult;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700662 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
663 if (! keyEventObj) {
664 LOGE("Could not obtain DVM KeyEvent object to get key event targets.");
Jeff Brown7fbdc842010-06-17 20:52:56 -0700665 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700666 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700667 jint injectionResult = env->CallIntMethod(mCallbacksObj,
668 gCallbacksClassInfo.getKeyEventTargets, mReusableInputTargetListObj,
669 keyEventObj, jint(keyEvent->getNature()), jint(policyFlags),
670 jint(injectorPid), jint(injectorUid));
671 if (checkAndClearExceptionFromCallback(env, "getKeyEventTargets")) {
672 injectionResult = INPUT_EVENT_INJECTION_FAILED;
673 } else {
674 populateInputTargets(env, mReusableInputTargetListObj, outTargets);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700675 }
676 env->DeleteLocalRef(keyEventObj);
677 }
Jeff Brown7fbdc842010-06-17 20:52:56 -0700678 return injectionResult;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700679}
680
Jeff Brown7fbdc842010-06-17 20:52:56 -0700681int32_t NativeInputManager::getMotionEventTargets(MotionEvent* motionEvent, uint32_t policyFlags,
682 int32_t injectorPid, int32_t injectorUid, Vector<InputTarget>& outTargets) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700683#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown7fbdc842010-06-17 20:52:56 -0700684 LOGD("getMotionEventTargets - policyFlags=%d, injectorPid=%d, injectorUid=%d",
685 policyFlags, injectorPid, injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700686#endif
687
688 JNIEnv* env = jniEnv();
689
Jeff Brown7fbdc842010-06-17 20:52:56 -0700690 jint injectionResult;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700691 jobject motionEventObj = android_view_MotionEvent_fromNative(env, motionEvent);
692 if (! motionEventObj) {
693 LOGE("Could not obtain DVM MotionEvent object to get key event targets.");
Jeff Brown7fbdc842010-06-17 20:52:56 -0700694 injectionResult = INPUT_EVENT_INJECTION_FAILED;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700695 } else {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700696 jint injectionResult = env->CallIntMethod(mCallbacksObj,
697 gCallbacksClassInfo.getMotionEventTargets, mReusableInputTargetListObj,
698 motionEventObj, jint(motionEvent->getNature()), jint(policyFlags),
699 jint(injectorPid), jint(injectorUid));
700 if (checkAndClearExceptionFromCallback(env, "getMotionEventTargets")) {
701 injectionResult = INPUT_EVENT_INJECTION_FAILED;
702 } else {
703 populateInputTargets(env, mReusableInputTargetListObj, outTargets);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700704 }
705 android_view_MotionEvent_recycle(env, motionEventObj);
706 env->DeleteLocalRef(motionEventObj);
707 }
Jeff Brown7fbdc842010-06-17 20:52:56 -0700708 return injectionResult;
709}
710
711void NativeInputManager::populateInputTargets(JNIEnv* env, jobject inputTargetListObj,
712 Vector<InputTarget>& outTargets) {
713 jobjectArray inputTargetArray = jobjectArray(env->GetObjectField(
714 inputTargetListObj, gInputTargetListClassInfo.mArray));
715
716 jsize length = env->GetArrayLength(inputTargetArray);
717 for (jsize i = 0; i < length; i++) {
718 jobject item = env->GetObjectArrayElement(inputTargetArray, i);
719 if (! item) {
720 break; // found null element indicating end of used portion of the array
721 }
722
723 outTargets.add();
724 android_view_InputTarget_toNative(env, item, & outTargets.editTop());
725
726 env->DeleteLocalRef(item);
727 }
728 env->DeleteLocalRef(inputTargetArray);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700729}
730
731
732// ----------------------------------------------------------------------------
733
734static sp<NativeInputManager> gNativeInputManager;
735
Jeff Brown46b9ac02010-04-22 18:58:52 -0700736static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700737 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700738 LOGE("Input manager not initialized.");
739 jniThrowRuntimeException(env, "Input manager not initialized.");
740 return true;
741 }
742 return false;
743}
744
745static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
746 jobject callbacks) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700747 if (gNativeInputManager == NULL) {
748 gNativeInputManager = new NativeInputManager(callbacks);
749 } else {
750 LOGE("Input manager already initialized.");
751 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700752 }
753}
754
755static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
756 if (checkInputManagerUnitialized(env)) {
757 return;
758 }
759
Jeff Brown9c3cda02010-06-15 01:31:58 -0700760 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700761 if (result) {
762 jniThrowRuntimeException(env, "Input manager could not be started.");
763 }
764}
765
766static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
767 jint displayId, jint width, jint height) {
768 if (checkInputManagerUnitialized(env)) {
769 return;
770 }
771
772 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
773 // to be passed in like this, not sure which is better but leaving it like this
774 // keeps the window manager in direct control of when display transitions propagate down
775 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700776 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700777}
778
779static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
780 jint displayId, jint orientation) {
781 if (checkInputManagerUnitialized(env)) {
782 return;
783 }
784
Jeff Brown9c3cda02010-06-15 01:31:58 -0700785 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700786}
787
788static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
789 jint deviceId, jint deviceClasses, jint scanCode) {
790 if (checkInputManagerUnitialized(env)) {
791 return KEY_STATE_UNKNOWN;
792 }
793
Jeff Brown9c3cda02010-06-15 01:31:58 -0700794 return gNativeInputManager->getInputManager()->getScanCodeState(
795 deviceId, deviceClasses, scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700796}
797
798static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
799 jint deviceId, jint deviceClasses, jint keyCode) {
800 if (checkInputManagerUnitialized(env)) {
801 return KEY_STATE_UNKNOWN;
802 }
803
Jeff Brown9c3cda02010-06-15 01:31:58 -0700804 return gNativeInputManager->getInputManager()->getKeyCodeState(
805 deviceId, deviceClasses, keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700806}
807
808static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
809 jint deviceId, jint deviceClasses, jint sw) {
810 if (checkInputManagerUnitialized(env)) {
811 return KEY_STATE_UNKNOWN;
812 }
813
Jeff Brown9c3cda02010-06-15 01:31:58 -0700814 return gNativeInputManager->getInputManager()->getSwitchState(deviceId, deviceClasses, sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700815}
816
817static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
818 jintArray keyCodes, jbooleanArray outFlags) {
819 if (checkInputManagerUnitialized(env)) {
820 return JNI_FALSE;
821 }
822
823 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
824 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
825 jsize numCodes = env->GetArrayLength(keyCodes);
826 jboolean result;
827 if (numCodes == env->GetArrayLength(outFlags)) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700828 result = gNativeInputManager->getInputManager()->hasKeys(numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700829 } else {
830 result = JNI_FALSE;
831 }
832
833 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
834 env->ReleaseIntArrayElements(keyCodes, codes, 0);
835 return result;
836}
837
838static void throwInputChannelNotInitialized(JNIEnv* env) {
839 jniThrowException(env, "java/lang/IllegalStateException",
840 "inputChannel is not initialized");
841}
842
843static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
844 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
845 LOGW("Input channel object '%s' was disposed without first being unregistered with "
846 "the input manager!", inputChannel->getName().string());
847
Jeff Brown9c3cda02010-06-15 01:31:58 -0700848 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700849 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700850 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700851}
852
853static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
854 jobject inputChannelObj) {
855 if (checkInputManagerUnitialized(env)) {
856 return;
857 }
858
859 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
860 inputChannelObj);
861 if (inputChannel == NULL) {
862 throwInputChannelNotInitialized(env);
863 return;
864 }
865
Jeff Brown7fbdc842010-06-17 20:52:56 -0700866
867 status_t status = gNativeInputManager->registerInputChannel(
868 env, inputChannel, inputChannelObj);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700869 if (status) {
870 jniThrowRuntimeException(env, "Failed to register input channel. "
871 "Check logs for details.");
872 return;
873 }
874
875 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
876 android_server_InputManager_handleInputChannelDisposed, NULL);
877}
878
879static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
880 jobject inputChannelObj) {
881 if (checkInputManagerUnitialized(env)) {
882 return;
883 }
884
885 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
886 inputChannelObj);
887 if (inputChannel == NULL) {
888 throwInputChannelNotInitialized(env);
889 return;
890 }
891
892 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
893
Jeff Brown7fbdc842010-06-17 20:52:56 -0700894 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700895 if (status) {
896 jniThrowRuntimeException(env, "Failed to unregister input channel. "
897 "Check logs for details.");
898 }
899}
900
Jeff Brown7fbdc842010-06-17 20:52:56 -0700901static jint android_server_InputManager_nativeInjectKeyEvent(JNIEnv* env, jclass clazz,
902 jobject keyEventObj, jint nature, jint injectorPid, jint injectorUid,
903 jboolean sync, jint timeoutMillis) {
904 if (checkInputManagerUnitialized(env)) {
905 return INPUT_EVENT_INJECTION_FAILED;
906 }
907
908 KeyEvent keyEvent;
909 android_view_KeyEvent_toNative(env, keyEventObj, nature, & keyEvent);
910
911 return gNativeInputManager->getInputManager()->injectInputEvent(& keyEvent,
912 injectorPid, injectorUid, sync, timeoutMillis);
913}
914
915static jint android_server_InputManager_nativeInjectMotionEvent(JNIEnv* env, jclass clazz,
916 jobject motionEventObj, jint nature, jint injectorPid, jint injectorUid,
917 jboolean sync, jint timeoutMillis) {
918 if (checkInputManagerUnitialized(env)) {
919 return INPUT_EVENT_INJECTION_FAILED;
920 }
921
922 MotionEvent motionEvent;
923 android_view_MotionEvent_toNative(env, motionEventObj, nature, & motionEvent);
924
925 return gNativeInputManager->getInputManager()->injectInputEvent(& motionEvent,
926 injectorPid, injectorUid, sync, timeoutMillis);
927}
928
Jeff Brown9c3cda02010-06-15 01:31:58 -0700929// ----------------------------------------------------------------------------
930
Jeff Brown46b9ac02010-04-22 18:58:52 -0700931static JNINativeMethod gInputManagerMethods[] = {
932 /* name, signature, funcPtr */
933 { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
934 (void*) android_server_InputManager_nativeInit },
935 { "nativeStart", "()V",
936 (void*) android_server_InputManager_nativeStart },
937 { "nativeSetDisplaySize", "(III)V",
938 (void*) android_server_InputManager_nativeSetDisplaySize },
939 { "nativeSetDisplayOrientation", "(II)V",
940 (void*) android_server_InputManager_nativeSetDisplayOrientation },
941 { "nativeGetScanCodeState", "(III)I",
942 (void*) android_server_InputManager_nativeGetScanCodeState },
943 { "nativeGetKeyCodeState", "(III)I",
944 (void*) android_server_InputManager_nativeGetKeyCodeState },
945 { "nativeGetSwitchState", "(III)I",
946 (void*) android_server_InputManager_nativeGetSwitchState },
947 { "nativeHasKeys", "([I[Z)Z",
948 (void*) android_server_InputManager_nativeHasKeys },
949 { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;)V",
950 (void*) android_server_InputManager_nativeRegisterInputChannel },
951 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -0700952 (void*) android_server_InputManager_nativeUnregisterInputChannel },
953 { "nativeInjectKeyEvent", "(Landroid/view/KeyEvent;IIIZI)I",
954 (void*) android_server_InputManager_nativeInjectKeyEvent },
955 { "nativeInjectMotionEvent", "(Landroid/view/MotionEvent;IIIZI)I",
956 (void*) android_server_InputManager_nativeInjectMotionEvent }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700957};
958
959#define FIND_CLASS(var, className) \
960 var = env->FindClass(className); \
961 LOG_FATAL_IF(! var, "Unable to find class " className); \
962 var = jclass(env->NewGlobalRef(var));
963
964#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
965 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
966 LOG_FATAL_IF(! var, "Unable to find method " methodName);
967
968#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
969 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
970 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
971
972int register_android_server_InputManager(JNIEnv* env) {
973 int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
974 gInputManagerMethods, NELEM(gInputManagerMethods));
975 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
976
Jeff Brown9c3cda02010-06-15 01:31:58 -0700977 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -0700978
979 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
980
981 GET_METHOD_ID(gCallbacksClassInfo.isScreenOn, gCallbacksClassInfo.clazz,
982 "isScreenOn", "()Z");
983
984 GET_METHOD_ID(gCallbacksClassInfo.isScreenBright, gCallbacksClassInfo.clazz,
985 "isScreenBright", "()Z");
986
987 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
988 "notifyConfigurationChanged", "(JIII)V");
989
990 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
991 "notifyLidSwitchChanged", "(JZ)V");
992
Jeff Brown7fbdc842010-06-17 20:52:56 -0700993 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
994 "notifyInputChannelBroken", "(Landroid/view/InputChannel;)V");
995
996 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelANR, gCallbacksClassInfo.clazz,
997 "notifyInputChannelANR", "(Landroid/view/InputChannel;)J");
998
999 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelRecoveredFromANR, gCallbacksClassInfo.clazz,
1000 "notifyInputChannelRecoveredFromANR", "(Landroid/view/InputChannel;)V");
1001
Jeff Brown46b9ac02010-04-22 18:58:52 -07001002 GET_METHOD_ID(gCallbacksClassInfo.virtualKeyFeedback, gCallbacksClassInfo.clazz,
1003 "virtualKeyFeedback", "(JIIIIIIJ)V");
1004
1005 GET_METHOD_ID(gCallbacksClassInfo.hackInterceptKey, gCallbacksClassInfo.clazz,
1006 "hackInterceptKey", "(IIIIIIJZ)I");
1007
1008 GET_METHOD_ID(gCallbacksClassInfo.goToSleep, gCallbacksClassInfo.clazz,
1009 "goToSleep", "(J)V");
1010
1011 GET_METHOD_ID(gCallbacksClassInfo.pokeUserActivityForKey, gCallbacksClassInfo.clazz,
1012 "pokeUserActivityForKey", "(J)V");
1013
1014 GET_METHOD_ID(gCallbacksClassInfo.notifyAppSwitchComing, gCallbacksClassInfo.clazz,
1015 "notifyAppSwitchComing", "()V");
1016
1017 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1018 "filterTouchEvents", "()Z");
1019
1020 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1021 "filterJumpyTouchEvents", "()Z");
1022
1023 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyDefinitions, gCallbacksClassInfo.clazz,
1024 "getVirtualKeyDefinitions",
1025 "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
1026
1027 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1028 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1029
1030 GET_METHOD_ID(gCallbacksClassInfo.getKeyEventTargets, gCallbacksClassInfo.clazz,
Jeff Brown7fbdc842010-06-17 20:52:56 -07001031 "getKeyEventTargets",
1032 "(Lcom/android/server/InputTargetList;Landroid/view/KeyEvent;IIII)I");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001033
1034 GET_METHOD_ID(gCallbacksClassInfo.getMotionEventTargets, gCallbacksClassInfo.clazz,
Jeff Brown7fbdc842010-06-17 20:52:56 -07001035 "getMotionEventTargets",
1036 "(Lcom/android/server/InputTargetList;Landroid/view/MotionEvent;IIII)I");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001037
1038 // VirtualKeyDefinition
1039
1040 FIND_CLASS(gVirtualKeyDefinitionClassInfo.clazz,
1041 "com/android/server/InputManager$VirtualKeyDefinition");
1042
1043 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.scanCode, gVirtualKeyDefinitionClassInfo.clazz,
1044 "scanCode", "I");
1045
1046 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerX, gVirtualKeyDefinitionClassInfo.clazz,
1047 "centerX", "I");
1048
1049 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerY, gVirtualKeyDefinitionClassInfo.clazz,
1050 "centerY", "I");
1051
1052 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.width, gVirtualKeyDefinitionClassInfo.clazz,
1053 "width", "I");
1054
1055 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
1056 "height", "I");
1057
Jeff Brown7fbdc842010-06-17 20:52:56 -07001058 // InputTargetList
1059
1060 FIND_CLASS(gInputTargetListClassInfo.clazz, "com/android/server/InputTargetList");
1061
1062 GET_METHOD_ID(gInputTargetListClassInfo.ctor, gInputTargetListClassInfo.clazz,
1063 "<init>", "()V");
1064
1065 GET_FIELD_ID(gInputTargetListClassInfo.mArray, gInputTargetListClassInfo.clazz,
1066 "mArray", "[Landroid/view/InputTarget;");
1067
Jeff Brown46b9ac02010-04-22 18:58:52 -07001068 return 0;
1069}
1070
Jeff Brown46b9ac02010-04-22 18:58:52 -07001071} /* namespace android */