blob: 9156249229e776701e73975734617d07fbc2efd8 [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
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INPUT_READER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070023
24// Log debug messages about InputDispatcherPolicy
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_INPUT_DISPATCHER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070026
Jeff Brown46b9ac02010-04-22 18:58:52 -070027#include "JNIHelp.h"
28#include "jni.h"
Jeff Brown349703e2010-06-22 01:27:15 -070029#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070030#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"
Jeff Brown00fa7bd2010-07-02 15:37:36 -070040#include "com_android_server_PowerManagerService.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070041
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
Jeff Brown46b9ac02010-04-22 18:58:52 -070049 jmethodID notifyConfigurationChanged;
50 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070051 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070052 jmethodID notifyANR;
Jeff Brown349703e2010-06-22 01:27:15 -070053 jmethodID interceptKeyBeforeQueueing;
54 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070055 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070056 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070057 jmethodID filterTouchEvents;
58 jmethodID filterJumpyTouchEvents;
Jeff Brown46b9ac02010-04-22 18:58:52 -070059 jmethodID getExcludedDeviceNames;
Jeff Brownae9fc032010-08-18 15:51:08 -070060 jmethodID getMaxEventsPerSecond;
Jeff Brown46b9ac02010-04-22 18:58:52 -070061} gCallbacksClassInfo;
62
63static struct {
64 jclass clazz;
65
Jeff Brown349703e2010-06-22 01:27:15 -070066 jfieldID inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -070067 jfieldID name;
Jeff Brown349703e2010-06-22 01:27:15 -070068 jfieldID layoutParamsFlags;
69 jfieldID layoutParamsType;
70 jfieldID dispatchingTimeoutNanos;
71 jfieldID frameLeft;
72 jfieldID frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -070073 jfieldID frameRight;
74 jfieldID frameBottom;
75 jfieldID visibleFrameLeft;
76 jfieldID visibleFrameTop;
77 jfieldID visibleFrameRight;
78 jfieldID visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -070079 jfieldID touchableAreaLeft;
80 jfieldID touchableAreaTop;
81 jfieldID touchableAreaRight;
82 jfieldID touchableAreaBottom;
83 jfieldID visible;
Jeff Brown519e0242010-09-15 15:18:56 -070084 jfieldID canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -070085 jfieldID hasFocus;
86 jfieldID hasWallpaper;
87 jfieldID paused;
Jeff Brown519e0242010-09-15 15:18:56 -070088 jfieldID layer;
Jeff Brown349703e2010-06-22 01:27:15 -070089 jfieldID ownerPid;
90 jfieldID ownerUid;
91} gInputWindowClassInfo;
92
93static struct {
94 jclass clazz;
95
96 jfieldID name;
97 jfieldID dispatchingTimeoutNanos;
98 jfieldID token;
99} gInputApplicationClassInfo;
100
Jeff Brown6ec402b2010-07-28 15:48:59 -0700101static struct {
102 jclass clazz;
103} gKeyEventClassInfo;
104
105static struct {
106 jclass clazz;
107} gMotionEventClassInfo;
108
Jeff Brown8d608662010-08-30 03:02:23 -0700109static struct {
110 jclass clazz;
111
112 jmethodID ctor;
113 jmethodID addMotionRange;
114
115 jfieldID mId;
116 jfieldID mName;
117 jfieldID mSources;
118 jfieldID mKeyboardType;
119 jfieldID mMotionRanges;
120} gInputDeviceClassInfo;
121
Jeff Brown57c59372010-09-21 18:22:55 -0700122static struct {
123 jclass clazz;
124
125 jfieldID touchscreen;
126 jfieldID keyboard;
127 jfieldID navigation;
128} gConfigurationClassInfo;
129
Jeff Brown349703e2010-06-22 01:27:15 -0700130// ----------------------------------------------------------------------------
131
132static inline nsecs_t now() {
133 return systemTime(SYSTEM_TIME_MONOTONIC);
134}
Jeff Brown7fbdc842010-06-17 20:52:56 -0700135
Jeff Brown9c3cda02010-06-15 01:31:58 -0700136// ----------------------------------------------------------------------------
137
138class NativeInputManager : public virtual RefBase,
139 public virtual InputReaderPolicyInterface,
140 public virtual InputDispatcherPolicyInterface {
141protected:
142 virtual ~NativeInputManager();
143
144public:
145 NativeInputManager(jobject callbacksObj);
146
147 inline sp<InputManager> getInputManager() const { return mInputManager; }
148
Jeff Brownb88102f2010-09-08 11:49:43 -0700149 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700150
Jeff Brown9c3cda02010-06-15 01:31:58 -0700151 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
152 void setDisplayOrientation(int32_t displayId, int32_t orientation);
153
Jeff Brown7fbdc842010-06-17 20:52:56 -0700154 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Browna41ca772010-08-11 14:46:32 -0700155 jweak inputChannelObjWeak, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700156 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
157
Jeff Brown349703e2010-06-22 01:27:15 -0700158 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
159 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
160 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700161
Jeff Brown9c3cda02010-06-15 01:31:58 -0700162 /* --- InputReaderPolicyInterface implementation --- */
163
164 virtual bool getDisplayInfo(int32_t displayId,
165 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700166 virtual bool filterTouchEvents();
167 virtual bool filterJumpyTouchEvents();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700168 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
169
170 /* --- InputDispatcherPolicyInterface implementation --- */
171
Jeff Browne20c9e02010-10-11 14:20:19 -0700172 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
173 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700174 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700175 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
176 const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700177 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700178 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700179 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700180 virtual int32_t getMaxEventsPerSecond();
Jeff Brown1f245102010-11-18 20:53:46 -0800181 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -0700182 virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -0700183 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
184 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -0700185 virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800186 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700187 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700188 virtual bool checkInjectEventsPermissionNonReentrant(
189 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700190
191private:
Jeff Brownb88102f2010-09-08 11:49:43 -0700192 class ApplicationToken : public InputApplicationHandle {
193 jweak mTokenObjWeak;
Jeff Brown349703e2010-06-22 01:27:15 -0700194
195 public:
Jeff Brownb88102f2010-09-08 11:49:43 -0700196 ApplicationToken(jweak tokenObjWeak) :
197 mTokenObjWeak(tokenObjWeak) { }
Jeff Brown349703e2010-06-22 01:27:15 -0700198
Jeff Brownb88102f2010-09-08 11:49:43 -0700199 virtual ~ApplicationToken() {
200 JNIEnv* env = NativeInputManager::jniEnv();
201 env->DeleteWeakGlobalRef(mTokenObjWeak);
202 }
Jeff Brown349703e2010-06-22 01:27:15 -0700203
Jeff Brownb88102f2010-09-08 11:49:43 -0700204 inline jweak getTokenObj() { return mTokenObjWeak; }
Jeff Brown349703e2010-06-22 01:27:15 -0700205 };
206
Jeff Brown9c3cda02010-06-15 01:31:58 -0700207 sp<InputManager> mInputManager;
208
209 jobject mCallbacksObj;
210
211 // Cached filtering policies.
212 int32_t mFilterTouchEvents;
213 int32_t mFilterJumpyTouchEvents;
214
Jeff Brownae9fc032010-08-18 15:51:08 -0700215 // Cached throttling policy.
216 int32_t mMaxEventsPerSecond;
217
Jeff Brown9c3cda02010-06-15 01:31:58 -0700218 // Cached display state. (lock mDisplayLock)
219 Mutex mDisplayLock;
220 int32_t mDisplayWidth, mDisplayHeight;
221 int32_t mDisplayOrientation;
222
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700223 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700224 bool isScreenOn();
225 bool isScreenBright();
226
Jeff Brown2cbecea2010-08-17 15:59:26 -0700227 // Weak references to all currently registered input channels by connection pointer.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700228 Mutex mInputChannelRegistryLock;
Jeff Brown2cbecea2010-08-17 15:59:26 -0700229 KeyedVector<InputChannel*, jweak> mInputChannelObjWeakTable;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700230
231 jobject getInputChannelObjLocal(JNIEnv* env, const sp<InputChannel>& inputChannel);
232
Jeff Brown349703e2010-06-22 01:27:15 -0700233 static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
Jeff Brown349703e2010-06-22 01:27:15 -0700234
Jeff Brownb88102f2010-09-08 11:49:43 -0700235 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700236
Jeff Brown9c3cda02010-06-15 01:31:58 -0700237 static inline JNIEnv* jniEnv() {
238 return AndroidRuntime::getJNIEnv();
239 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700240};
241
242// ----------------------------------------------------------------------------
243
244NativeInputManager::NativeInputManager(jobject callbacksObj) :
245 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
Jeff Brownae9fc032010-08-18 15:51:08 -0700246 mMaxEventsPerSecond(-1),
Jeff Brownb88102f2010-09-08 11:49:43 -0700247 mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(ROTATION_0) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700248 JNIEnv* env = jniEnv();
249
250 mCallbacksObj = env->NewGlobalRef(callbacksObj);
251
252 sp<EventHub> eventHub = new EventHub();
253 mInputManager = new InputManager(eventHub, this, this);
254}
255
256NativeInputManager::~NativeInputManager() {
257 JNIEnv* env = jniEnv();
258
259 env->DeleteGlobalRef(mCallbacksObj);
260}
261
Jeff Brownb88102f2010-09-08 11:49:43 -0700262void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700263 mInputManager->getReader()->dump(dump);
264 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700265
Jeff Brownb88102f2010-09-08 11:49:43 -0700266 mInputManager->getDispatcher()->dump(dump);
267 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700268}
269
Jeff Brown7fbdc842010-06-17 20:52:56 -0700270bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700271 if (env->ExceptionCheck()) {
272 LOGE("An exception was thrown by callback '%s'.", methodName);
273 LOGE_EX(env);
274 env->ExceptionClear();
275 return true;
276 }
277 return false;
278}
279
280void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
281 if (displayId == 0) {
282 AutoMutex _l(mDisplayLock);
283
284 mDisplayWidth = width;
285 mDisplayHeight = height;
286 }
287}
288
289void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
290 if (displayId == 0) {
291 AutoMutex _l(mDisplayLock);
292
293 mDisplayOrientation = orientation;
294 }
295}
296
Jeff Brown7fbdc842010-06-17 20:52:56 -0700297status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Browna41ca772010-08-11 14:46:32 -0700298 const sp<InputChannel>& inputChannel, jobject inputChannelObj, bool monitor) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700299 jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
300 if (! inputChannelObjWeak) {
301 LOGE("Could not create weak reference for input channel.");
302 LOGE_EX(env);
303 return NO_MEMORY;
304 }
305
306 status_t status;
307 {
308 AutoMutex _l(mInputChannelRegistryLock);
309
Jeff Brown2cbecea2010-08-17 15:59:26 -0700310 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700311 if (index >= 0) {
312 LOGE("Input channel object '%s' has already been registered",
313 inputChannel->getName().string());
314 status = INVALID_OPERATION;
315 goto DeleteWeakRef;
316 }
317
Jeff Brown2cbecea2010-08-17 15:59:26 -0700318 mInputChannelObjWeakTable.add(inputChannel.get(), inputChannelObjWeak);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700319 }
320
Jeff Brownb88102f2010-09-08 11:49:43 -0700321 status = mInputManager->getDispatcher()->registerInputChannel(inputChannel, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700322 if (! status) {
Jeff Browna41ca772010-08-11 14:46:32 -0700323 // Success.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700324 return OK;
325 }
326
Jeff Browna41ca772010-08-11 14:46:32 -0700327 // Failed!
Jeff Brown7fbdc842010-06-17 20:52:56 -0700328 {
329 AutoMutex _l(mInputChannelRegistryLock);
Jeff Brown2cbecea2010-08-17 15:59:26 -0700330 mInputChannelObjWeakTable.removeItem(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700331 }
332
333DeleteWeakRef:
334 env->DeleteWeakGlobalRef(inputChannelObjWeak);
335 return status;
336}
337
338status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
339 const sp<InputChannel>& inputChannel) {
340 jweak inputChannelObjWeak;
341 {
342 AutoMutex _l(mInputChannelRegistryLock);
343
Jeff Brown2cbecea2010-08-17 15:59:26 -0700344 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700345 if (index < 0) {
346 LOGE("Input channel object '%s' is not currently registered",
347 inputChannel->getName().string());
348 return INVALID_OPERATION;
349 }
350
Jeff Brown2cbecea2010-08-17 15:59:26 -0700351 inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
352 mInputChannelObjWeakTable.removeItemsAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700353 }
354
355 env->DeleteWeakGlobalRef(inputChannelObjWeak);
356
Jeff Brownb88102f2010-09-08 11:49:43 -0700357 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700358}
359
360jobject NativeInputManager::getInputChannelObjLocal(JNIEnv* env,
361 const sp<InputChannel>& inputChannel) {
Jeff Brown54a18252010-09-16 14:07:33 -0700362 InputChannel* inputChannelPtr = inputChannel.get();
363 if (! inputChannelPtr) {
364 return NULL;
365 }
366
Jeff Brown7fbdc842010-06-17 20:52:56 -0700367 {
368 AutoMutex _l(mInputChannelRegistryLock);
369
Jeff Brown54a18252010-09-16 14:07:33 -0700370 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannelPtr);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700371 if (index < 0) {
372 return NULL;
373 }
374
Jeff Brown2cbecea2010-08-17 15:59:26 -0700375 jweak inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700376 return env->NewLocalRef(inputChannelObjWeak);
377 }
378}
379
Jeff Brown9c3cda02010-06-15 01:31:58 -0700380bool NativeInputManager::getDisplayInfo(int32_t displayId,
381 int32_t* width, int32_t* height, int32_t* orientation) {
382 bool result = false;
383 if (displayId == 0) {
384 AutoMutex _l(mDisplayLock);
385
386 if (mDisplayWidth > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700387 if (width) {
388 *width = mDisplayWidth;
389 }
390 if (height) {
391 *height = mDisplayHeight;
392 }
393 if (orientation) {
394 *orientation = mDisplayOrientation;
395 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700396 result = true;
397 }
398 }
399 return result;
400}
401
Jeff Brown9c3cda02010-06-15 01:31:58 -0700402bool NativeInputManager::filterTouchEvents() {
403 if (mFilterTouchEvents < 0) {
404 JNIEnv* env = jniEnv();
405
406 jboolean result = env->CallBooleanMethod(mCallbacksObj,
407 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700408 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700409 result = false;
410 }
411
412 mFilterTouchEvents = result ? 1 : 0;
413 }
414 return mFilterTouchEvents;
415}
416
417bool NativeInputManager::filterJumpyTouchEvents() {
418 if (mFilterJumpyTouchEvents < 0) {
419 JNIEnv* env = jniEnv();
420
421 jboolean result = env->CallBooleanMethod(mCallbacksObj,
422 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700423 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700424 result = false;
425 }
426
427 mFilterJumpyTouchEvents = result ? 1 : 0;
428 }
429 return mFilterJumpyTouchEvents;
430}
431
Jeff Brown9c3cda02010-06-15 01:31:58 -0700432void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700433 outExcludedDeviceNames.clear();
434
Jeff Brown9c3cda02010-06-15 01:31:58 -0700435 JNIEnv* env = jniEnv();
436
437 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
438 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700439 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700440 jsize length = env->GetArrayLength(result);
441 for (jsize i = 0; i < length; i++) {
442 jstring item = jstring(env->GetObjectArrayElement(result, i));
443
444 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
445 outExcludedDeviceNames.add(String8(deviceNameChars));
446 env->ReleaseStringUTFChars(item, deviceNameChars);
447
448 env->DeleteLocalRef(item);
449 }
450 env->DeleteLocalRef(result);
451 }
452}
453
Jeff Browne20c9e02010-10-11 14:20:19 -0700454void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
455 int32_t switchValue, uint32_t policyFlags) {
456#if DEBUG_INPUT_DISPATCHER_POLICY
457 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
458 when, switchCode, switchValue, policyFlags);
459#endif
460
461 JNIEnv* env = jniEnv();
462
463 switch (switchCode) {
464 case SW_LID:
465 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
466 when, switchValue == 0);
467 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
468 break;
469 }
470}
471
Jeff Brown9c3cda02010-06-15 01:31:58 -0700472void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
473#if DEBUG_INPUT_DISPATCHER_POLICY
474 LOGD("notifyConfigurationChanged - when=%lld", when);
475#endif
476
477 JNIEnv* env = jniEnv();
478
Jeff Brown57c59372010-09-21 18:22:55 -0700479 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700480 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700481}
482
Jeff Brown519e0242010-09-15 15:18:56 -0700483nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
484 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700485#if DEBUG_INPUT_DISPATCHER_POLICY
486 LOGD("notifyANR");
487#endif
488
489 JNIEnv* env = jniEnv();
490
Jeff Brown519e0242010-09-15 15:18:56 -0700491 jobject tokenObjLocal;
492 if (inputApplicationHandle.get()) {
493 ApplicationToken* token = static_cast<ApplicationToken*>(inputApplicationHandle.get());
494 jweak tokenObjWeak = token->getTokenObj();
495 tokenObjLocal = env->NewLocalRef(tokenObjWeak);
Jeff Brownb88102f2010-09-08 11:49:43 -0700496 } else {
Jeff Brown519e0242010-09-15 15:18:56 -0700497 tokenObjLocal = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -0700498 }
499
Jeff Brown54a18252010-09-16 14:07:33 -0700500 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
Jeff Brown519e0242010-09-15 15:18:56 -0700501 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
502 gCallbacksClassInfo.notifyANR, tokenObjLocal, inputChannelObjLocal);
503 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
504 newTimeout = 0; // abort dispatch
505 } else {
506 assert(newTimeout >= 0);
507 }
508
509 env->DeleteLocalRef(tokenObjLocal);
510 env->DeleteLocalRef(inputChannelObjLocal);
Jeff Brownb88102f2010-09-08 11:49:43 -0700511 return newTimeout;
512}
513
Jeff Brown9c3cda02010-06-15 01:31:58 -0700514void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
515#if DEBUG_INPUT_DISPATCHER_POLICY
516 LOGD("notifyInputChannelBroken - inputChannel='%s'", inputChannel->getName().string());
517#endif
518
Jeff Brown7fbdc842010-06-17 20:52:56 -0700519 JNIEnv* env = jniEnv();
520
521 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
522 if (inputChannelObjLocal) {
523 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
524 inputChannelObjLocal);
525 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
526
527 env->DeleteLocalRef(inputChannelObjLocal);
528 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700529}
530
Jeff Brown9c3cda02010-06-15 01:31:58 -0700531nsecs_t NativeInputManager::getKeyRepeatTimeout() {
532 if (! isScreenOn()) {
533 // Disable key repeat when the screen is off.
534 return -1;
535 } else {
536 // TODO use ViewConfiguration.getLongPressTimeout()
537 return milliseconds_to_nanoseconds(500);
538 }
539}
540
Jeff Brownb21fb102010-09-07 10:44:57 -0700541nsecs_t NativeInputManager::getKeyRepeatDelay() {
542 return milliseconds_to_nanoseconds(50);
543}
544
Jeff Brownae9fc032010-08-18 15:51:08 -0700545int32_t NativeInputManager::getMaxEventsPerSecond() {
546 if (mMaxEventsPerSecond < 0) {
547 JNIEnv* env = jniEnv();
548
549 jint result = env->CallIntMethod(mCallbacksObj,
550 gCallbacksClassInfo.getMaxEventsPerSecond);
551 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700552 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700553 }
554
555 mMaxEventsPerSecond = result;
556 }
557 return mMaxEventsPerSecond;
558}
559
Jeff Brown349703e2010-06-22 01:27:15 -0700560void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700561 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700562
Jeff Brownb88102f2010-09-08 11:49:43 -0700563 jsize length = env->GetArrayLength(windowObjArray);
564 for (jsize i = 0; i < length; i++) {
565 jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
566 if (! inputTargetObj) {
567 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700568 }
569
Jeff Brownb88102f2010-09-08 11:49:43 -0700570 windows.push();
571 InputWindow& window = windows.editTop();
572 bool valid = populateWindow(env, inputTargetObj, window);
573 if (! valid) {
574 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700575 }
576
Jeff Brownb88102f2010-09-08 11:49:43 -0700577 env->DeleteLocalRef(inputTargetObj);
578 }
Jeff Brown349703e2010-06-22 01:27:15 -0700579
Jeff Brownb88102f2010-09-08 11:49:43 -0700580 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700581}
582
583bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj,
584 InputWindow& outWindow) {
585 bool valid = false;
586
587 jobject inputChannelObj = env->GetObjectField(windowObj,
588 gInputWindowClassInfo.inputChannel);
589 if (inputChannelObj) {
590 sp<InputChannel> inputChannel =
591 android_view_InputChannel_getInputChannel(env, inputChannelObj);
592 if (inputChannel != NULL) {
Jeff Brown519e0242010-09-15 15:18:56 -0700593 jstring name = jstring(env->GetObjectField(windowObj,
594 gInputWindowClassInfo.name));
Jeff Brown349703e2010-06-22 01:27:15 -0700595 jint layoutParamsFlags = env->GetIntField(windowObj,
596 gInputWindowClassInfo.layoutParamsFlags);
597 jint layoutParamsType = env->GetIntField(windowObj,
598 gInputWindowClassInfo.layoutParamsType);
599 jlong dispatchingTimeoutNanos = env->GetLongField(windowObj,
600 gInputWindowClassInfo.dispatchingTimeoutNanos);
601 jint frameLeft = env->GetIntField(windowObj,
602 gInputWindowClassInfo.frameLeft);
603 jint frameTop = env->GetIntField(windowObj,
604 gInputWindowClassInfo.frameTop);
Jeff Brown85a31762010-09-01 17:01:00 -0700605 jint frameRight = env->GetIntField(windowObj,
606 gInputWindowClassInfo.frameRight);
607 jint frameBottom = env->GetIntField(windowObj,
608 gInputWindowClassInfo.frameBottom);
609 jint visibleFrameLeft = env->GetIntField(windowObj,
610 gInputWindowClassInfo.visibleFrameLeft);
611 jint visibleFrameTop = env->GetIntField(windowObj,
612 gInputWindowClassInfo.visibleFrameTop);
613 jint visibleFrameRight = env->GetIntField(windowObj,
614 gInputWindowClassInfo.visibleFrameRight);
615 jint visibleFrameBottom = env->GetIntField(windowObj,
616 gInputWindowClassInfo.visibleFrameBottom);
Jeff Brown349703e2010-06-22 01:27:15 -0700617 jint touchableAreaLeft = env->GetIntField(windowObj,
618 gInputWindowClassInfo.touchableAreaLeft);
619 jint touchableAreaTop = env->GetIntField(windowObj,
620 gInputWindowClassInfo.touchableAreaTop);
621 jint touchableAreaRight = env->GetIntField(windowObj,
622 gInputWindowClassInfo.touchableAreaRight);
623 jint touchableAreaBottom = env->GetIntField(windowObj,
624 gInputWindowClassInfo.touchableAreaBottom);
625 jboolean visible = env->GetBooleanField(windowObj,
626 gInputWindowClassInfo.visible);
Jeff Brown519e0242010-09-15 15:18:56 -0700627 jboolean canReceiveKeys = env->GetBooleanField(windowObj,
628 gInputWindowClassInfo.canReceiveKeys);
Jeff Brown349703e2010-06-22 01:27:15 -0700629 jboolean hasFocus = env->GetBooleanField(windowObj,
630 gInputWindowClassInfo.hasFocus);
631 jboolean hasWallpaper = env->GetBooleanField(windowObj,
632 gInputWindowClassInfo.hasWallpaper);
633 jboolean paused = env->GetBooleanField(windowObj,
634 gInputWindowClassInfo.paused);
Jeff Brown519e0242010-09-15 15:18:56 -0700635 jint layer = env->GetIntField(windowObj,
636 gInputWindowClassInfo.layer);
Jeff Brown349703e2010-06-22 01:27:15 -0700637 jint ownerPid = env->GetIntField(windowObj,
638 gInputWindowClassInfo.ownerPid);
639 jint ownerUid = env->GetIntField(windowObj,
640 gInputWindowClassInfo.ownerUid);
641
Jeff Brown519e0242010-09-15 15:18:56 -0700642 const char* nameStr = env->GetStringUTFChars(name, NULL);
643
Jeff Brown349703e2010-06-22 01:27:15 -0700644 outWindow.inputChannel = inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -0700645 outWindow.name.setTo(nameStr);
Jeff Brown349703e2010-06-22 01:27:15 -0700646 outWindow.layoutParamsFlags = layoutParamsFlags;
647 outWindow.layoutParamsType = layoutParamsType;
648 outWindow.dispatchingTimeout = dispatchingTimeoutNanos;
649 outWindow.frameLeft = frameLeft;
650 outWindow.frameTop = frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -0700651 outWindow.frameRight = frameRight;
652 outWindow.frameBottom = frameBottom;
653 outWindow.visibleFrameLeft = visibleFrameLeft;
654 outWindow.visibleFrameTop = visibleFrameTop;
655 outWindow.visibleFrameRight = visibleFrameRight;
656 outWindow.visibleFrameBottom = visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -0700657 outWindow.touchableAreaLeft = touchableAreaLeft;
658 outWindow.touchableAreaTop = touchableAreaTop;
659 outWindow.touchableAreaRight = touchableAreaRight;
660 outWindow.touchableAreaBottom = touchableAreaBottom;
661 outWindow.visible = visible;
Jeff Brown519e0242010-09-15 15:18:56 -0700662 outWindow.canReceiveKeys = canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -0700663 outWindow.hasFocus = hasFocus;
664 outWindow.hasWallpaper = hasWallpaper;
665 outWindow.paused = paused;
Jeff Brown519e0242010-09-15 15:18:56 -0700666 outWindow.layer = layer;
Jeff Brown349703e2010-06-22 01:27:15 -0700667 outWindow.ownerPid = ownerPid;
668 outWindow.ownerUid = ownerUid;
Jeff Brown519e0242010-09-15 15:18:56 -0700669
670 env->ReleaseStringUTFChars(name, nameStr);
Jeff Brown1f245102010-11-18 20:53:46 -0800671 env->DeleteLocalRef(name);
Jeff Brown349703e2010-06-22 01:27:15 -0700672 valid = true;
673 } else {
674 LOGW("Dropping input target because its input channel is not initialized.");
675 }
676
677 env->DeleteLocalRef(inputChannelObj);
678 } else {
679 LOGW("Dropping input target because the input channel object was null.");
680 }
681 return valid;
682}
683
684void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700685 if (applicationObj) {
686 jstring nameObj = jstring(env->GetObjectField(applicationObj,
687 gInputApplicationClassInfo.name));
688 jlong dispatchingTimeoutNanos = env->GetLongField(applicationObj,
689 gInputApplicationClassInfo.dispatchingTimeoutNanos);
690 jobject tokenObj = env->GetObjectField(applicationObj,
691 gInputApplicationClassInfo.token);
692 jweak tokenObjWeak = env->NewWeakGlobalRef(tokenObj);
693 if (! tokenObjWeak) {
694 LOGE("Could not create weak reference for application token.");
695 LOGE_EX(env);
696 env->ExceptionClear();
697 }
698 env->DeleteLocalRef(tokenObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700699
Jeff Brownb88102f2010-09-08 11:49:43 -0700700 String8 name;
701 if (nameObj) {
702 const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
703 name.setTo(nameStr);
704 env->ReleaseStringUTFChars(nameObj, nameStr);
705 env->DeleteLocalRef(nameObj);
706 } else {
707 LOGE("InputApplication.name should not be null.");
708 name.setTo("unknown");
Jeff Brown349703e2010-06-22 01:27:15 -0700709 }
710
Jeff Brownb88102f2010-09-08 11:49:43 -0700711 InputApplication application;
712 application.name = name;
713 application.dispatchingTimeout = dispatchingTimeoutNanos;
714 application.handle = new ApplicationToken(tokenObjWeak);
715 mInputManager->getDispatcher()->setFocusedApplication(& application);
716 } else {
717 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700718 }
719}
720
721void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700722 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700723}
724
Jeff Browne20c9e02010-10-11 14:20:19 -0700725bool NativeInputManager::isScreenOn() {
726 return android_server_PowerManagerService_isScreenOn();
727}
728
729bool NativeInputManager::isScreenBright() {
730 return android_server_PowerManagerService_isScreenBright();
731}
732
Jeff Brown1f245102010-11-18 20:53:46 -0800733void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
734 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700735 // Policy:
736 // - Ignore untrusted events and pass them along.
737 // - Ask the window manager what to do with normal events and trusted injected events.
738 // - For normal events wake and brighten the screen if currently off or dim.
739 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
740 const int32_t WM_ACTION_PASS_TO_USER = 1;
741 const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
742 const int32_t WM_ACTION_GO_TO_SLEEP = 4;
Jeff Browne20c9e02010-10-11 14:20:19 -0700743
Jeff Brown1f245102010-11-18 20:53:46 -0800744 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700745 bool isScreenOn = this->isScreenOn();
746 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700747
Jeff Brown3122e442010-10-11 23:32:49 -0700748 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800749 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
750 jint wmActions;
751 if (keyEventObj) {
752 wmActions = env->CallIntMethod(mCallbacksObj,
753 gCallbacksClassInfo.interceptKeyBeforeQueueing,
754 keyEventObj, policyFlags, isScreenOn);
755 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
756 wmActions = 0;
757 }
758 android_view_KeyEvent_recycle(env, keyEventObj);
759 env->DeleteLocalRef(keyEventObj);
760 } else {
761 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700762 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700763 }
764
Jeff Brown1f245102010-11-18 20:53:46 -0800765 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700766 if (!isScreenOn) {
767 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700768 }
769
770 if (!isScreenBright) {
771 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
772 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700773 }
774
775 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
776 android_server_PowerManagerService_goToSleep(when);
777 }
778
779 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
780 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
781 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700782
Jeff Brown3122e442010-10-11 23:32:49 -0700783 if (wmActions & WM_ACTION_PASS_TO_USER) {
784 policyFlags |= POLICY_FLAG_PASS_TO_USER;
785 }
786 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700787 policyFlags |= POLICY_FLAG_PASS_TO_USER;
788 }
789}
790
791void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700792 // Policy:
793 // - Ignore untrusted events and pass them along.
794 // - No special filtering for injected events required at this time.
795 // - Filter normal events based on screen state.
796 // - For normal events brighten (but do not wake) the screen if currently dim.
797 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
798 if (isScreenOn()) {
799 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700800
Jeff Brown3122e442010-10-11 23:32:49 -0700801 if (!isScreenBright()) {
802 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
803 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700804 }
Jeff Brown3122e442010-10-11 23:32:49 -0700805 } else {
806 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700807 }
808}
809
810bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
811 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700812 // Policy:
813 // - Ignore untrusted events and pass them along.
814 // - Filter normal events and trusted injected events through the window manager policy to
815 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800816 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700817 if (policyFlags & POLICY_FLAG_TRUSTED) {
818 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700819
Jeff Brown3122e442010-10-11 23:32:49 -0700820 // Note: inputChannel may be null.
821 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
Jeff Brown1f245102010-11-18 20:53:46 -0800822 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
823 if (keyEventObj) {
824 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
825 gCallbacksClassInfo.interceptKeyBeforeDispatching,
826 inputChannelObj, keyEventObj, policyFlags);
827 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
828 android_view_KeyEvent_recycle(env, keyEventObj);
829 env->DeleteLocalRef(keyEventObj);
830 result = consumed && !error;
831 } else {
832 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800833 }
Jeff Brown3122e442010-10-11 23:32:49 -0700834 env->DeleteLocalRef(inputChannelObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700835 }
Jeff Brown1f245102010-11-18 20:53:46 -0800836 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700837}
838
Jeff Brown3915bb82010-11-05 15:02:16 -0700839bool NativeInputManager::dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800840 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700841 // Policy:
842 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800843 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700844 if (policyFlags & POLICY_FLAG_TRUSTED) {
845 JNIEnv* env = jniEnv();
846
847 // Note: inputChannel may be null.
848 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
Jeff Brown1f245102010-11-18 20:53:46 -0800849 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
850 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800851 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800852 gCallbacksClassInfo.dispatchUnhandledKey,
853 inputChannelObj, keyEventObj, policyFlags);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800854 checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey");
Jeff Brown1f245102010-11-18 20:53:46 -0800855 android_view_KeyEvent_recycle(env, keyEventObj);
856 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800857
858 if (fallbackKeyEventObj) {
859 // Note: outFallbackKeyEvent may be the same object as keyEvent.
860 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
861 outFallbackKeyEvent)) {
862 result = true;
863 }
864 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
865 env->DeleteLocalRef(fallbackKeyEventObj);
866 }
Jeff Brown1f245102010-11-18 20:53:46 -0800867 } else {
868 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800869 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700870 env->DeleteLocalRef(inputChannelObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700871 }
Jeff Brown1f245102010-11-18 20:53:46 -0800872 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700873}
874
Jeff Brown01ce2e92010-09-26 22:20:12 -0700875void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
876 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700877}
878
Jeff Brown349703e2010-06-22 01:27:15 -0700879
Jeff Brownb88102f2010-09-08 11:49:43 -0700880bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
881 int32_t injectorPid, int32_t injectorUid) {
882 JNIEnv* env = jniEnv();
883 jboolean result = env->CallBooleanMethod(mCallbacksObj,
884 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
885 checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");
Jeff Brown349703e2010-06-22 01:27:15 -0700886 return result;
887}
888
Jeff Brown9c3cda02010-06-15 01:31:58 -0700889// ----------------------------------------------------------------------------
890
891static sp<NativeInputManager> gNativeInputManager;
892
Jeff Brown46b9ac02010-04-22 18:58:52 -0700893static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700894 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700895 LOGE("Input manager not initialized.");
896 jniThrowRuntimeException(env, "Input manager not initialized.");
897 return true;
898 }
899 return false;
900}
901
902static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
903 jobject callbacks) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700904 if (gNativeInputManager == NULL) {
905 gNativeInputManager = new NativeInputManager(callbacks);
906 } else {
907 LOGE("Input manager already initialized.");
908 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700909 }
910}
911
912static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
913 if (checkInputManagerUnitialized(env)) {
914 return;
915 }
916
Jeff Brown9c3cda02010-06-15 01:31:58 -0700917 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700918 if (result) {
919 jniThrowRuntimeException(env, "Input manager could not be started.");
920 }
921}
922
923static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
924 jint displayId, jint width, jint height) {
925 if (checkInputManagerUnitialized(env)) {
926 return;
927 }
928
929 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
930 // to be passed in like this, not sure which is better but leaving it like this
931 // keeps the window manager in direct control of when display transitions propagate down
932 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700933 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700934}
935
936static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
937 jint displayId, jint orientation) {
938 if (checkInputManagerUnitialized(env)) {
939 return;
940 }
941
Jeff Brown9c3cda02010-06-15 01:31:58 -0700942 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700943}
944
945static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700946 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700947 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700948 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700949 }
950
Jeff Brownb88102f2010-09-08 11:49:43 -0700951 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700952 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700953}
954
955static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700956 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700957 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700958 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700959 }
960
Jeff Brownb88102f2010-09-08 11:49:43 -0700961 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700962 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700963}
964
965static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700966 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700967 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700968 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700969 }
970
Jeff Brownb88102f2010-09-08 11:49:43 -0700971 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700972 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700973}
974
975static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700976 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700977 if (checkInputManagerUnitialized(env)) {
978 return JNI_FALSE;
979 }
980
981 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
982 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
983 jsize numCodes = env->GetArrayLength(keyCodes);
984 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700985 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700986 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700987 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700988 } else {
989 result = JNI_FALSE;
990 }
991
992 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
993 env->ReleaseIntArrayElements(keyCodes, codes, 0);
994 return result;
995}
996
997static void throwInputChannelNotInitialized(JNIEnv* env) {
998 jniThrowException(env, "java/lang/IllegalStateException",
999 "inputChannel is not initialized");
1000}
1001
1002static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1003 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1004 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1005 "the input manager!", inputChannel->getName().string());
1006
Jeff Brown9c3cda02010-06-15 01:31:58 -07001007 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001008 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001009 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001010}
1011
1012static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Browna41ca772010-08-11 14:46:32 -07001013 jobject inputChannelObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001014 if (checkInputManagerUnitialized(env)) {
1015 return;
1016 }
1017
1018 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1019 inputChannelObj);
1020 if (inputChannel == NULL) {
1021 throwInputChannelNotInitialized(env);
1022 return;
1023 }
1024
Jeff Brown7fbdc842010-06-17 20:52:56 -07001025
1026 status_t status = gNativeInputManager->registerInputChannel(
Jeff Browna41ca772010-08-11 14:46:32 -07001027 env, inputChannel, inputChannelObj, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001028 if (status) {
1029 jniThrowRuntimeException(env, "Failed to register input channel. "
1030 "Check logs for details.");
1031 return;
1032 }
1033
Jeff Browna41ca772010-08-11 14:46:32 -07001034 if (! monitor) {
1035 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1036 android_server_InputManager_handleInputChannelDisposed, NULL);
1037 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001038}
1039
1040static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1041 jobject inputChannelObj) {
1042 if (checkInputManagerUnitialized(env)) {
1043 return;
1044 }
1045
1046 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1047 inputChannelObj);
1048 if (inputChannel == NULL) {
1049 throwInputChannelNotInitialized(env);
1050 return;
1051 }
1052
1053 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1054
Jeff Brown7fbdc842010-06-17 20:52:56 -07001055 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001056 if (status) {
1057 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1058 "Check logs for details.");
1059 }
1060}
1061
Jeff Brown6ec402b2010-07-28 15:48:59 -07001062static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1063 jobject inputEventObj, jint injectorPid, jint injectorUid,
1064 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001065 if (checkInputManagerUnitialized(env)) {
1066 return INPUT_EVENT_INJECTION_FAILED;
1067 }
1068
Jeff Brown6ec402b2010-07-28 15:48:59 -07001069 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1070 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001071 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1072 if (status) {
1073 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1074 return INPUT_EVENT_INJECTION_FAILED;
1075 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001076
Jeff Brownb88102f2010-09-08 11:49:43 -07001077 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1078 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001079 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1080 MotionEvent motionEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001081 status_t status = android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
1082 if (status) {
1083 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1084 return INPUT_EVENT_INJECTION_FAILED;
1085 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001086
Jeff Brownb88102f2010-09-08 11:49:43 -07001087 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1088 & motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001089 } else {
1090 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001091 return INPUT_EVENT_INJECTION_FAILED;
1092 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001093}
1094
Jeff Brown349703e2010-06-22 01:27:15 -07001095static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1096 jobjectArray windowObjArray) {
1097 if (checkInputManagerUnitialized(env)) {
1098 return;
1099 }
1100
1101 gNativeInputManager->setInputWindows(env, windowObjArray);
1102}
1103
1104static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1105 jobject applicationObj) {
1106 if (checkInputManagerUnitialized(env)) {
1107 return;
1108 }
1109
1110 gNativeInputManager->setFocusedApplication(env, applicationObj);
1111}
1112
1113static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1114 jclass clazz, jboolean enabled, jboolean frozen) {
1115 if (checkInputManagerUnitialized(env)) {
1116 return;
1117 }
1118
1119 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1120}
1121
Jeff Brown8d608662010-08-30 03:02:23 -07001122static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1123 jclass clazz, jint deviceId) {
1124 if (checkInputManagerUnitialized(env)) {
1125 return NULL;
1126 }
1127
1128 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001129 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001130 deviceId, & deviceInfo);
1131 if (status) {
1132 return NULL;
1133 }
1134
1135 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1136 if (! deviceObj) {
1137 return NULL;
1138 }
1139
1140 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1141 if (! deviceNameObj) {
1142 return NULL;
1143 }
1144
1145 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1146 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1147 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1148 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1149
1150 const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1151 for (size_t i = 0; i < ranges.size(); i++) {
1152 int rangeType = ranges.keyAt(i);
1153 const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
1154 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
1155 rangeType, range.min, range.max, range.flat, range.fuzz);
1156 if (env->ExceptionCheck()) {
1157 return NULL;
1158 }
1159 }
1160
1161 return deviceObj;
1162}
1163
1164static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1165 jclass clazz) {
1166 if (checkInputManagerUnitialized(env)) {
1167 return NULL;
1168 }
1169
1170 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001171 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001172
1173 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1174 if (! deviceIdsObj) {
1175 return NULL;
1176 }
1177
1178 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1179 return deviceIdsObj;
1180}
1181
Jeff Brown57c59372010-09-21 18:22:55 -07001182static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1183 jclass clazz, jobject configObj) {
1184 if (checkInputManagerUnitialized(env)) {
1185 return;
1186 }
1187
1188 InputConfiguration config;
1189 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1190
1191 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1192 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1193 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1194}
1195
Jeff Browne6504122010-09-27 14:52:15 -07001196static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1197 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1198 if (checkInputManagerUnitialized(env)) {
1199 return false;
1200 }
1201
1202 sp<InputChannel> fromChannel =
1203 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1204 sp<InputChannel> toChannel =
1205 android_view_InputChannel_getInputChannel(env, toChannelObj);
1206
1207 if (fromChannel == NULL || toChannel == NULL) {
1208 return false;
1209 }
1210
1211 return gNativeInputManager->getInputManager()->getDispatcher()->
1212 transferTouchFocus(fromChannel, toChannel);
1213}
1214
Jeff Browne33348b2010-07-15 23:54:05 -07001215static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1216 if (checkInputManagerUnitialized(env)) {
1217 return NULL;
1218 }
1219
Jeff Brownb88102f2010-09-08 11:49:43 -07001220 String8 dump;
1221 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001222 return env->NewStringUTF(dump.string());
1223}
1224
Jeff Brown9c3cda02010-06-15 01:31:58 -07001225// ----------------------------------------------------------------------------
1226
Jeff Brown46b9ac02010-04-22 18:58:52 -07001227static JNINativeMethod gInputManagerMethods[] = {
1228 /* name, signature, funcPtr */
1229 { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
1230 (void*) android_server_InputManager_nativeInit },
1231 { "nativeStart", "()V",
1232 (void*) android_server_InputManager_nativeStart },
1233 { "nativeSetDisplaySize", "(III)V",
1234 (void*) android_server_InputManager_nativeSetDisplaySize },
1235 { "nativeSetDisplayOrientation", "(II)V",
1236 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1237 { "nativeGetScanCodeState", "(III)I",
1238 (void*) android_server_InputManager_nativeGetScanCodeState },
1239 { "nativeGetKeyCodeState", "(III)I",
1240 (void*) android_server_InputManager_nativeGetKeyCodeState },
1241 { "nativeGetSwitchState", "(III)I",
1242 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001243 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001244 (void*) android_server_InputManager_nativeHasKeys },
Jeff Browna41ca772010-08-11 14:46:32 -07001245 { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001246 (void*) android_server_InputManager_nativeRegisterInputChannel },
1247 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001248 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001249 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1250 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown349703e2010-06-22 01:27:15 -07001251 { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
1252 (void*) android_server_InputManager_nativeSetInputWindows },
1253 { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
1254 (void*) android_server_InputManager_nativeSetFocusedApplication },
1255 { "nativeSetInputDispatchMode", "(ZZ)V",
1256 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown8d608662010-08-30 03:02:23 -07001257 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1258 (void*) android_server_InputManager_nativeGetInputDevice },
1259 { "nativeGetInputDeviceIds", "()[I",
1260 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001261 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1262 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001263 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1264 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001265 { "nativeDump", "()Ljava/lang/String;",
1266 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001267};
1268
1269#define FIND_CLASS(var, className) \
1270 var = env->FindClass(className); \
1271 LOG_FATAL_IF(! var, "Unable to find class " className); \
1272 var = jclass(env->NewGlobalRef(var));
1273
1274#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1275 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1276 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1277
1278#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1279 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1280 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1281
1282int register_android_server_InputManager(JNIEnv* env) {
1283 int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
1284 gInputManagerMethods, NELEM(gInputManagerMethods));
1285 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1286
Jeff Brown9c3cda02010-06-15 01:31:58 -07001287 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001288
1289 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
1290
Jeff Brown46b9ac02010-04-22 18:58:52 -07001291 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001292 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001293
1294 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1295 "notifyLidSwitchChanged", "(JZ)V");
1296
Jeff Brown7fbdc842010-06-17 20:52:56 -07001297 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
1298 "notifyInputChannelBroken", "(Landroid/view/InputChannel;)V");
1299
Jeff Brown349703e2010-06-22 01:27:15 -07001300 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown519e0242010-09-15 15:18:56 -07001301 "notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001302
Jeff Brown349703e2010-06-22 01:27:15 -07001303 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001304 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001305
1306 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001307 "interceptKeyBeforeDispatching",
1308 "(Landroid/view/InputChannel;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001309
Jeff Brown3915bb82010-11-05 15:02:16 -07001310 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001311 "dispatchUnhandledKey",
1312 "(Landroid/view/InputChannel;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001313
Jeff Brown349703e2010-06-22 01:27:15 -07001314 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1315 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001316
Jeff Brown46b9ac02010-04-22 18:58:52 -07001317 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1318 "filterTouchEvents", "()Z");
1319
1320 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1321 "filterJumpyTouchEvents", "()Z");
1322
Jeff Brown46b9ac02010-04-22 18:58:52 -07001323 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1324 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1325
Jeff Brownae9fc032010-08-18 15:51:08 -07001326 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1327 "getMaxEventsPerSecond", "()I");
1328
Jeff Brown349703e2010-06-22 01:27:15 -07001329 // InputWindow
Jeff Brown7fbdc842010-06-17 20:52:56 -07001330
Jeff Brown349703e2010-06-22 01:27:15 -07001331 FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001332
Jeff Brown349703e2010-06-22 01:27:15 -07001333 GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
1334 "inputChannel", "Landroid/view/InputChannel;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001335
Jeff Brown519e0242010-09-15 15:18:56 -07001336 GET_FIELD_ID(gInputWindowClassInfo.name, gInputWindowClassInfo.clazz,
1337 "name", "Ljava/lang/String;");
1338
Jeff Brown349703e2010-06-22 01:27:15 -07001339 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, gInputWindowClassInfo.clazz,
1340 "layoutParamsFlags", "I");
1341
1342 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, gInputWindowClassInfo.clazz,
1343 "layoutParamsType", "I");
1344
1345 GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, gInputWindowClassInfo.clazz,
1346 "dispatchingTimeoutNanos", "J");
1347
1348 GET_FIELD_ID(gInputWindowClassInfo.frameLeft, gInputWindowClassInfo.clazz,
1349 "frameLeft", "I");
1350
1351 GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz,
1352 "frameTop", "I");
1353
Jeff Brown85a31762010-09-01 17:01:00 -07001354 GET_FIELD_ID(gInputWindowClassInfo.frameRight, gInputWindowClassInfo.clazz,
1355 "frameRight", "I");
1356
1357 GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz,
1358 "frameBottom", "I");
1359
1360 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameLeft, gInputWindowClassInfo.clazz,
1361 "visibleFrameLeft", "I");
1362
1363 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameTop, gInputWindowClassInfo.clazz,
1364 "visibleFrameTop", "I");
1365
1366 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameRight, gInputWindowClassInfo.clazz,
1367 "visibleFrameRight", "I");
1368
1369 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameBottom, gInputWindowClassInfo.clazz,
1370 "visibleFrameBottom", "I");
1371
Jeff Brown349703e2010-06-22 01:27:15 -07001372 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz,
1373 "touchableAreaLeft", "I");
1374
1375 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaTop, gInputWindowClassInfo.clazz,
1376 "touchableAreaTop", "I");
1377
1378 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaRight, gInputWindowClassInfo.clazz,
1379 "touchableAreaRight", "I");
1380
1381 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaBottom, gInputWindowClassInfo.clazz,
1382 "touchableAreaBottom", "I");
1383
1384 GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz,
1385 "visible", "Z");
1386
Jeff Brown519e0242010-09-15 15:18:56 -07001387 GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, gInputWindowClassInfo.clazz,
1388 "canReceiveKeys", "Z");
1389
Jeff Brown349703e2010-06-22 01:27:15 -07001390 GET_FIELD_ID(gInputWindowClassInfo.hasFocus, gInputWindowClassInfo.clazz,
1391 "hasFocus", "Z");
1392
1393 GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, gInputWindowClassInfo.clazz,
1394 "hasWallpaper", "Z");
1395
1396 GET_FIELD_ID(gInputWindowClassInfo.paused, gInputWindowClassInfo.clazz,
1397 "paused", "Z");
1398
Jeff Brown519e0242010-09-15 15:18:56 -07001399 GET_FIELD_ID(gInputWindowClassInfo.layer, gInputWindowClassInfo.clazz,
1400 "layer", "I");
1401
Jeff Brown349703e2010-06-22 01:27:15 -07001402 GET_FIELD_ID(gInputWindowClassInfo.ownerPid, gInputWindowClassInfo.clazz,
1403 "ownerPid", "I");
1404
1405 GET_FIELD_ID(gInputWindowClassInfo.ownerUid, gInputWindowClassInfo.clazz,
1406 "ownerUid", "I");
1407
1408 // InputApplication
1409
1410 FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");
1411
1412 GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
1413 "name", "Ljava/lang/String;");
1414
1415 GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
1416 gInputApplicationClassInfo.clazz,
1417 "dispatchingTimeoutNanos", "J");
1418
1419 GET_FIELD_ID(gInputApplicationClassInfo.token, gInputApplicationClassInfo.clazz,
1420 "token", "Ljava/lang/Object;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001421
Jeff Brown6ec402b2010-07-28 15:48:59 -07001422 // KeyEvent
1423
1424 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1425
Jeff Brown8d608662010-08-30 03:02:23 -07001426 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001427
1428 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1429
Jeff Brown8d608662010-08-30 03:02:23 -07001430 // InputDevice
1431
1432 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1433
1434 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1435 "<init>", "()V");
1436
1437 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
1438 "addMotionRange", "(IFFFF)V");
1439
1440 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1441 "mId", "I");
1442
1443 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1444 "mName", "Ljava/lang/String;");
1445
1446 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1447 "mSources", "I");
1448
1449 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1450 "mKeyboardType", "I");
1451
1452 GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
1453 "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
1454
Jeff Brown57c59372010-09-21 18:22:55 -07001455 // Configuration
1456
1457 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1458
1459 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1460 "touchscreen", "I");
1461
1462 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1463 "keyboard", "I");
1464
1465 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1466 "navigation", "I");
1467
Jeff Brown46b9ac02010-04-22 18:58:52 -07001468 return 0;
1469}
1470
Jeff Brown46b9ac02010-04-22 18:58:52 -07001471} /* namespace android */