blob: 3fd6965564261ee8bd72eda86f7b4c478987af01 [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;
59 jmethodID getVirtualKeyDefinitions;
Jeff Brown8d608662010-08-30 03:02:23 -070060 jmethodID getInputDeviceCalibration;
Jeff Brown46b9ac02010-04-22 18:58:52 -070061 jmethodID getExcludedDeviceNames;
Jeff Brownae9fc032010-08-18 15:51:08 -070062 jmethodID getMaxEventsPerSecond;
Jeff Brown46b9ac02010-04-22 18:58:52 -070063} gCallbacksClassInfo;
64
65static struct {
66 jclass clazz;
67
68 jfieldID scanCode;
69 jfieldID centerX;
70 jfieldID centerY;
71 jfieldID width;
72 jfieldID height;
73} gVirtualKeyDefinitionClassInfo;
74
Jeff Brown7fbdc842010-06-17 20:52:56 -070075static struct {
76 jclass clazz;
77
Jeff Brown8d608662010-08-30 03:02:23 -070078 jfieldID keys;
79 jfieldID values;
80} gInputDeviceCalibrationClassInfo;
81
82static struct {
83 jclass clazz;
84
Jeff Brown349703e2010-06-22 01:27:15 -070085 jfieldID inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -070086 jfieldID name;
Jeff Brown349703e2010-06-22 01:27:15 -070087 jfieldID layoutParamsFlags;
88 jfieldID layoutParamsType;
89 jfieldID dispatchingTimeoutNanos;
90 jfieldID frameLeft;
91 jfieldID frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -070092 jfieldID frameRight;
93 jfieldID frameBottom;
94 jfieldID visibleFrameLeft;
95 jfieldID visibleFrameTop;
96 jfieldID visibleFrameRight;
97 jfieldID visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -070098 jfieldID touchableAreaLeft;
99 jfieldID touchableAreaTop;
100 jfieldID touchableAreaRight;
101 jfieldID touchableAreaBottom;
102 jfieldID visible;
Jeff Brown519e0242010-09-15 15:18:56 -0700103 jfieldID canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -0700104 jfieldID hasFocus;
105 jfieldID hasWallpaper;
106 jfieldID paused;
Jeff Brown519e0242010-09-15 15:18:56 -0700107 jfieldID layer;
Jeff Brown349703e2010-06-22 01:27:15 -0700108 jfieldID ownerPid;
109 jfieldID ownerUid;
110} gInputWindowClassInfo;
111
112static struct {
113 jclass clazz;
114
115 jfieldID name;
116 jfieldID dispatchingTimeoutNanos;
117 jfieldID token;
118} gInputApplicationClassInfo;
119
Jeff Brown6ec402b2010-07-28 15:48:59 -0700120static struct {
121 jclass clazz;
122} gKeyEventClassInfo;
123
124static struct {
125 jclass clazz;
126} gMotionEventClassInfo;
127
Jeff Brown8d608662010-08-30 03:02:23 -0700128static struct {
129 jclass clazz;
130
131 jmethodID ctor;
132 jmethodID addMotionRange;
133
134 jfieldID mId;
135 jfieldID mName;
136 jfieldID mSources;
137 jfieldID mKeyboardType;
138 jfieldID mMotionRanges;
139} gInputDeviceClassInfo;
140
Jeff Brown57c59372010-09-21 18:22:55 -0700141static struct {
142 jclass clazz;
143
144 jfieldID touchscreen;
145 jfieldID keyboard;
146 jfieldID navigation;
147} gConfigurationClassInfo;
148
Jeff Brown349703e2010-06-22 01:27:15 -0700149// ----------------------------------------------------------------------------
150
151static inline nsecs_t now() {
152 return systemTime(SYSTEM_TIME_MONOTONIC);
153}
Jeff Brown7fbdc842010-06-17 20:52:56 -0700154
Jeff Brown9c3cda02010-06-15 01:31:58 -0700155// ----------------------------------------------------------------------------
156
157class NativeInputManager : public virtual RefBase,
158 public virtual InputReaderPolicyInterface,
159 public virtual InputDispatcherPolicyInterface {
160protected:
161 virtual ~NativeInputManager();
162
163public:
164 NativeInputManager(jobject callbacksObj);
165
166 inline sp<InputManager> getInputManager() const { return mInputManager; }
167
Jeff Brownb88102f2010-09-08 11:49:43 -0700168 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700169
Jeff Brown9c3cda02010-06-15 01:31:58 -0700170 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
171 void setDisplayOrientation(int32_t displayId, int32_t orientation);
172
Jeff Brown7fbdc842010-06-17 20:52:56 -0700173 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Browna41ca772010-08-11 14:46:32 -0700174 jweak inputChannelObjWeak, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700175 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
176
Jeff Brown349703e2010-06-22 01:27:15 -0700177 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
178 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
179 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700180
Jeff Brown9c3cda02010-06-15 01:31:58 -0700181 /* --- InputReaderPolicyInterface implementation --- */
182
183 virtual bool getDisplayInfo(int32_t displayId,
184 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700185 virtual bool filterTouchEvents();
186 virtual bool filterJumpyTouchEvents();
187 virtual void getVirtualKeyDefinitions(const String8& deviceName,
Jeff Brown8d608662010-08-30 03:02:23 -0700188 Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions);
189 virtual void getInputDeviceCalibration(const String8& deviceName,
190 InputDeviceCalibration& outCalibration);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700191 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
192
193 /* --- InputDispatcherPolicyInterface implementation --- */
194
Jeff Browne20c9e02010-10-11 14:20:19 -0700195 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
196 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700198 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
199 const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700200 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700201 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700202 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700203 virtual int32_t getMaxEventsPerSecond();
Jeff Brownb6997262010-10-08 22:31:17 -0700204 virtual void interceptKeyBeforeQueueing(nsecs_t when, int32_t deviceId,
205 int32_t action, int32_t& flags, int32_t keyCode, int32_t scanCode,
206 uint32_t& policyFlags);
207 virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -0700208 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
209 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -0700210 virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
211 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700212 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700213 virtual bool checkInjectEventsPermissionNonReentrant(
214 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700215
216private:
Jeff Brownb88102f2010-09-08 11:49:43 -0700217 class ApplicationToken : public InputApplicationHandle {
218 jweak mTokenObjWeak;
Jeff Brown349703e2010-06-22 01:27:15 -0700219
220 public:
Jeff Brownb88102f2010-09-08 11:49:43 -0700221 ApplicationToken(jweak tokenObjWeak) :
222 mTokenObjWeak(tokenObjWeak) { }
Jeff Brown349703e2010-06-22 01:27:15 -0700223
Jeff Brownb88102f2010-09-08 11:49:43 -0700224 virtual ~ApplicationToken() {
225 JNIEnv* env = NativeInputManager::jniEnv();
226 env->DeleteWeakGlobalRef(mTokenObjWeak);
227 }
Jeff Brown349703e2010-06-22 01:27:15 -0700228
Jeff Brownb88102f2010-09-08 11:49:43 -0700229 inline jweak getTokenObj() { return mTokenObjWeak; }
Jeff Brown349703e2010-06-22 01:27:15 -0700230 };
231
Jeff Brown9c3cda02010-06-15 01:31:58 -0700232 sp<InputManager> mInputManager;
233
234 jobject mCallbacksObj;
235
236 // Cached filtering policies.
237 int32_t mFilterTouchEvents;
238 int32_t mFilterJumpyTouchEvents;
239
Jeff Brownae9fc032010-08-18 15:51:08 -0700240 // Cached throttling policy.
241 int32_t mMaxEventsPerSecond;
242
Jeff Brown9c3cda02010-06-15 01:31:58 -0700243 // Cached display state. (lock mDisplayLock)
244 Mutex mDisplayLock;
245 int32_t mDisplayWidth, mDisplayHeight;
246 int32_t mDisplayOrientation;
247
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700248 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700249 bool isScreenOn();
250 bool isScreenBright();
251
Jeff Brown2cbecea2010-08-17 15:59:26 -0700252 // Weak references to all currently registered input channels by connection pointer.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700253 Mutex mInputChannelRegistryLock;
Jeff Brown2cbecea2010-08-17 15:59:26 -0700254 KeyedVector<InputChannel*, jweak> mInputChannelObjWeakTable;
Jeff Brown7fbdc842010-06-17 20:52:56 -0700255
256 jobject getInputChannelObjLocal(JNIEnv* env, const sp<InputChannel>& inputChannel);
257
Jeff Brown349703e2010-06-22 01:27:15 -0700258 static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
Jeff Brown349703e2010-06-22 01:27:15 -0700259
Jeff Brownb88102f2010-09-08 11:49:43 -0700260 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700261
Jeff Brown9c3cda02010-06-15 01:31:58 -0700262 static inline JNIEnv* jniEnv() {
263 return AndroidRuntime::getJNIEnv();
264 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700265};
266
267// ----------------------------------------------------------------------------
268
269NativeInputManager::NativeInputManager(jobject callbacksObj) :
270 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
Jeff Brownae9fc032010-08-18 15:51:08 -0700271 mMaxEventsPerSecond(-1),
Jeff Brownb88102f2010-09-08 11:49:43 -0700272 mDisplayWidth(-1), mDisplayHeight(-1), mDisplayOrientation(ROTATION_0) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700273 JNIEnv* env = jniEnv();
274
275 mCallbacksObj = env->NewGlobalRef(callbacksObj);
276
277 sp<EventHub> eventHub = new EventHub();
278 mInputManager = new InputManager(eventHub, this, this);
279}
280
281NativeInputManager::~NativeInputManager() {
282 JNIEnv* env = jniEnv();
283
284 env->DeleteGlobalRef(mCallbacksObj);
285}
286
Jeff Brownb88102f2010-09-08 11:49:43 -0700287void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700288 mInputManager->getReader()->dump(dump);
289 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700290
Jeff Brownb88102f2010-09-08 11:49:43 -0700291 mInputManager->getDispatcher()->dump(dump);
292 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700293}
294
Jeff Brown7fbdc842010-06-17 20:52:56 -0700295bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700296 if (env->ExceptionCheck()) {
297 LOGE("An exception was thrown by callback '%s'.", methodName);
298 LOGE_EX(env);
299 env->ExceptionClear();
300 return true;
301 }
302 return false;
303}
304
305void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
306 if (displayId == 0) {
307 AutoMutex _l(mDisplayLock);
308
309 mDisplayWidth = width;
310 mDisplayHeight = height;
311 }
312}
313
314void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
315 if (displayId == 0) {
316 AutoMutex _l(mDisplayLock);
317
318 mDisplayOrientation = orientation;
319 }
320}
321
Jeff Brown7fbdc842010-06-17 20:52:56 -0700322status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Browna41ca772010-08-11 14:46:32 -0700323 const sp<InputChannel>& inputChannel, jobject inputChannelObj, bool monitor) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700324 jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
325 if (! inputChannelObjWeak) {
326 LOGE("Could not create weak reference for input channel.");
327 LOGE_EX(env);
328 return NO_MEMORY;
329 }
330
331 status_t status;
332 {
333 AutoMutex _l(mInputChannelRegistryLock);
334
Jeff Brown2cbecea2010-08-17 15:59:26 -0700335 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700336 if (index >= 0) {
337 LOGE("Input channel object '%s' has already been registered",
338 inputChannel->getName().string());
339 status = INVALID_OPERATION;
340 goto DeleteWeakRef;
341 }
342
Jeff Brown2cbecea2010-08-17 15:59:26 -0700343 mInputChannelObjWeakTable.add(inputChannel.get(), inputChannelObjWeak);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700344 }
345
Jeff Brownb88102f2010-09-08 11:49:43 -0700346 status = mInputManager->getDispatcher()->registerInputChannel(inputChannel, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700347 if (! status) {
Jeff Browna41ca772010-08-11 14:46:32 -0700348 // Success.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700349 return OK;
350 }
351
Jeff Browna41ca772010-08-11 14:46:32 -0700352 // Failed!
Jeff Brown7fbdc842010-06-17 20:52:56 -0700353 {
354 AutoMutex _l(mInputChannelRegistryLock);
Jeff Brown2cbecea2010-08-17 15:59:26 -0700355 mInputChannelObjWeakTable.removeItem(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700356 }
357
358DeleteWeakRef:
359 env->DeleteWeakGlobalRef(inputChannelObjWeak);
360 return status;
361}
362
363status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
364 const sp<InputChannel>& inputChannel) {
365 jweak inputChannelObjWeak;
366 {
367 AutoMutex _l(mInputChannelRegistryLock);
368
Jeff Brown2cbecea2010-08-17 15:59:26 -0700369 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700370 if (index < 0) {
371 LOGE("Input channel object '%s' is not currently registered",
372 inputChannel->getName().string());
373 return INVALID_OPERATION;
374 }
375
Jeff Brown2cbecea2010-08-17 15:59:26 -0700376 inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
377 mInputChannelObjWeakTable.removeItemsAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700378 }
379
380 env->DeleteWeakGlobalRef(inputChannelObjWeak);
381
Jeff Brownb88102f2010-09-08 11:49:43 -0700382 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700383}
384
385jobject NativeInputManager::getInputChannelObjLocal(JNIEnv* env,
386 const sp<InputChannel>& inputChannel) {
Jeff Brown54a18252010-09-16 14:07:33 -0700387 InputChannel* inputChannelPtr = inputChannel.get();
388 if (! inputChannelPtr) {
389 return NULL;
390 }
391
Jeff Brown7fbdc842010-06-17 20:52:56 -0700392 {
393 AutoMutex _l(mInputChannelRegistryLock);
394
Jeff Brown54a18252010-09-16 14:07:33 -0700395 ssize_t index = mInputChannelObjWeakTable.indexOfKey(inputChannelPtr);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700396 if (index < 0) {
397 return NULL;
398 }
399
Jeff Brown2cbecea2010-08-17 15:59:26 -0700400 jweak inputChannelObjWeak = mInputChannelObjWeakTable.valueAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700401 return env->NewLocalRef(inputChannelObjWeak);
402 }
403}
404
Jeff Brown9c3cda02010-06-15 01:31:58 -0700405bool NativeInputManager::getDisplayInfo(int32_t displayId,
406 int32_t* width, int32_t* height, int32_t* orientation) {
407 bool result = false;
408 if (displayId == 0) {
409 AutoMutex _l(mDisplayLock);
410
411 if (mDisplayWidth > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700412 if (width) {
413 *width = mDisplayWidth;
414 }
415 if (height) {
416 *height = mDisplayHeight;
417 }
418 if (orientation) {
419 *orientation = mDisplayOrientation;
420 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700421 result = true;
422 }
423 }
424 return result;
425}
426
Jeff Brown9c3cda02010-06-15 01:31:58 -0700427bool NativeInputManager::filterTouchEvents() {
428 if (mFilterTouchEvents < 0) {
429 JNIEnv* env = jniEnv();
430
431 jboolean result = env->CallBooleanMethod(mCallbacksObj,
432 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700433 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700434 result = false;
435 }
436
437 mFilterTouchEvents = result ? 1 : 0;
438 }
439 return mFilterTouchEvents;
440}
441
442bool NativeInputManager::filterJumpyTouchEvents() {
443 if (mFilterJumpyTouchEvents < 0) {
444 JNIEnv* env = jniEnv();
445
446 jboolean result = env->CallBooleanMethod(mCallbacksObj,
447 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700448 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700449 result = false;
450 }
451
452 mFilterJumpyTouchEvents = result ? 1 : 0;
453 }
454 return mFilterJumpyTouchEvents;
455}
456
457void NativeInputManager::getVirtualKeyDefinitions(const String8& deviceName,
Jeff Brown8d608662010-08-30 03:02:23 -0700458 Vector<VirtualKeyDefinition>& outVirtualKeyDefinitions) {
459 outVirtualKeyDefinitions.clear();
460
Jeff Brown9c3cda02010-06-15 01:31:58 -0700461 JNIEnv* env = jniEnv();
462
463 jstring deviceNameStr = env->NewStringUTF(deviceName.string());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700464 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700465 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
466 gCallbacksClassInfo.getVirtualKeyDefinitions, deviceNameStr));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700467 if (! checkAndClearExceptionFromCallback(env, "getVirtualKeyDefinitions") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700468 jsize length = env->GetArrayLength(result);
469 for (jsize i = 0; i < length; i++) {
470 jobject item = env->GetObjectArrayElement(result, i);
471
472 outVirtualKeyDefinitions.add();
473 outVirtualKeyDefinitions.editTop().scanCode =
474 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.scanCode));
475 outVirtualKeyDefinitions.editTop().centerX =
476 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerX));
477 outVirtualKeyDefinitions.editTop().centerY =
478 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.centerY));
479 outVirtualKeyDefinitions.editTop().width =
480 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.width));
481 outVirtualKeyDefinitions.editTop().height =
482 int32_t(env->GetIntField(item, gVirtualKeyDefinitionClassInfo.height));
483
484 env->DeleteLocalRef(item);
485 }
486 env->DeleteLocalRef(result);
487 }
488 env->DeleteLocalRef(deviceNameStr);
489 }
490}
491
Jeff Brown8d608662010-08-30 03:02:23 -0700492void NativeInputManager::getInputDeviceCalibration(const String8& deviceName,
493 InputDeviceCalibration& outCalibration) {
494 outCalibration.clear();
495
496 JNIEnv* env = jniEnv();
497
498 jstring deviceNameStr = env->NewStringUTF(deviceName.string());
499 if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration")) {
500 jobject result = env->CallObjectMethod(mCallbacksObj,
501 gCallbacksClassInfo.getInputDeviceCalibration, deviceNameStr);
502 if (! checkAndClearExceptionFromCallback(env, "getInputDeviceCalibration") && result) {
503 jobjectArray keys = jobjectArray(env->GetObjectField(result,
504 gInputDeviceCalibrationClassInfo.keys));
505 jobjectArray values = jobjectArray(env->GetObjectField(result,
506 gInputDeviceCalibrationClassInfo.values));
507
508 jsize length = env->GetArrayLength(keys);
509 for (jsize i = 0; i < length; i++) {
510 jstring keyStr = jstring(env->GetObjectArrayElement(keys, i));
511 jstring valueStr = jstring(env->GetObjectArrayElement(values, i));
512
513 const char* keyChars = env->GetStringUTFChars(keyStr, NULL);
514 String8 key(keyChars);
515 env->ReleaseStringUTFChars(keyStr, keyChars);
516
517 const char* valueChars = env->GetStringUTFChars(valueStr, NULL);
518 String8 value(valueChars);
519 env->ReleaseStringUTFChars(valueStr, valueChars);
520
521 outCalibration.addProperty(key, value);
522
523 env->DeleteLocalRef(keyStr);
524 env->DeleteLocalRef(valueStr);
525 }
526 env->DeleteLocalRef(keys);
527 env->DeleteLocalRef(values);
528 env->DeleteLocalRef(result);
529 }
530 env->DeleteLocalRef(deviceNameStr);
531 }
532}
533
Jeff Brown9c3cda02010-06-15 01:31:58 -0700534void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700535 outExcludedDeviceNames.clear();
536
Jeff Brown9c3cda02010-06-15 01:31:58 -0700537 JNIEnv* env = jniEnv();
538
539 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
540 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700541 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700542 jsize length = env->GetArrayLength(result);
543 for (jsize i = 0; i < length; i++) {
544 jstring item = jstring(env->GetObjectArrayElement(result, i));
545
546 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
547 outExcludedDeviceNames.add(String8(deviceNameChars));
548 env->ReleaseStringUTFChars(item, deviceNameChars);
549
550 env->DeleteLocalRef(item);
551 }
552 env->DeleteLocalRef(result);
553 }
554}
555
Jeff Browne20c9e02010-10-11 14:20:19 -0700556void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
557 int32_t switchValue, uint32_t policyFlags) {
558#if DEBUG_INPUT_DISPATCHER_POLICY
559 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
560 when, switchCode, switchValue, policyFlags);
561#endif
562
563 JNIEnv* env = jniEnv();
564
565 switch (switchCode) {
566 case SW_LID:
567 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
568 when, switchValue == 0);
569 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
570 break;
571 }
572}
573
Jeff Brown9c3cda02010-06-15 01:31:58 -0700574void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
575#if DEBUG_INPUT_DISPATCHER_POLICY
576 LOGD("notifyConfigurationChanged - when=%lld", when);
577#endif
578
579 JNIEnv* env = jniEnv();
580
Jeff Brown57c59372010-09-21 18:22:55 -0700581 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700582 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700583}
584
Jeff Brown519e0242010-09-15 15:18:56 -0700585nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
586 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700587#if DEBUG_INPUT_DISPATCHER_POLICY
588 LOGD("notifyANR");
589#endif
590
591 JNIEnv* env = jniEnv();
592
Jeff Brown519e0242010-09-15 15:18:56 -0700593 jobject tokenObjLocal;
594 if (inputApplicationHandle.get()) {
595 ApplicationToken* token = static_cast<ApplicationToken*>(inputApplicationHandle.get());
596 jweak tokenObjWeak = token->getTokenObj();
597 tokenObjLocal = env->NewLocalRef(tokenObjWeak);
Jeff Brownb88102f2010-09-08 11:49:43 -0700598 } else {
Jeff Brown519e0242010-09-15 15:18:56 -0700599 tokenObjLocal = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -0700600 }
601
Jeff Brown54a18252010-09-16 14:07:33 -0700602 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
Jeff Brown519e0242010-09-15 15:18:56 -0700603 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
604 gCallbacksClassInfo.notifyANR, tokenObjLocal, inputChannelObjLocal);
605 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
606 newTimeout = 0; // abort dispatch
607 } else {
608 assert(newTimeout >= 0);
609 }
610
611 env->DeleteLocalRef(tokenObjLocal);
612 env->DeleteLocalRef(inputChannelObjLocal);
Jeff Brownb88102f2010-09-08 11:49:43 -0700613 return newTimeout;
614}
615
Jeff Brown9c3cda02010-06-15 01:31:58 -0700616void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
617#if DEBUG_INPUT_DISPATCHER_POLICY
618 LOGD("notifyInputChannelBroken - inputChannel='%s'", inputChannel->getName().string());
619#endif
620
Jeff Brown7fbdc842010-06-17 20:52:56 -0700621 JNIEnv* env = jniEnv();
622
623 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
624 if (inputChannelObjLocal) {
625 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
626 inputChannelObjLocal);
627 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
628
629 env->DeleteLocalRef(inputChannelObjLocal);
630 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700631}
632
Jeff Brown9c3cda02010-06-15 01:31:58 -0700633nsecs_t NativeInputManager::getKeyRepeatTimeout() {
634 if (! isScreenOn()) {
635 // Disable key repeat when the screen is off.
636 return -1;
637 } else {
638 // TODO use ViewConfiguration.getLongPressTimeout()
639 return milliseconds_to_nanoseconds(500);
640 }
641}
642
Jeff Brownb21fb102010-09-07 10:44:57 -0700643nsecs_t NativeInputManager::getKeyRepeatDelay() {
644 return milliseconds_to_nanoseconds(50);
645}
646
Jeff Brownae9fc032010-08-18 15:51:08 -0700647int32_t NativeInputManager::getMaxEventsPerSecond() {
648 if (mMaxEventsPerSecond < 0) {
649 JNIEnv* env = jniEnv();
650
651 jint result = env->CallIntMethod(mCallbacksObj,
652 gCallbacksClassInfo.getMaxEventsPerSecond);
653 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700654 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700655 }
656
657 mMaxEventsPerSecond = result;
658 }
659 return mMaxEventsPerSecond;
660}
661
Jeff Brown349703e2010-06-22 01:27:15 -0700662void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700663 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700664
Jeff Brownb88102f2010-09-08 11:49:43 -0700665 jsize length = env->GetArrayLength(windowObjArray);
666 for (jsize i = 0; i < length; i++) {
667 jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
668 if (! inputTargetObj) {
669 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700670 }
671
Jeff Brownb88102f2010-09-08 11:49:43 -0700672 windows.push();
673 InputWindow& window = windows.editTop();
674 bool valid = populateWindow(env, inputTargetObj, window);
675 if (! valid) {
676 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700677 }
678
Jeff Brownb88102f2010-09-08 11:49:43 -0700679 env->DeleteLocalRef(inputTargetObj);
680 }
Jeff Brown349703e2010-06-22 01:27:15 -0700681
Jeff Brownb88102f2010-09-08 11:49:43 -0700682 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700683}
684
685bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj,
686 InputWindow& outWindow) {
687 bool valid = false;
688
689 jobject inputChannelObj = env->GetObjectField(windowObj,
690 gInputWindowClassInfo.inputChannel);
691 if (inputChannelObj) {
692 sp<InputChannel> inputChannel =
693 android_view_InputChannel_getInputChannel(env, inputChannelObj);
694 if (inputChannel != NULL) {
Jeff Brown519e0242010-09-15 15:18:56 -0700695 jstring name = jstring(env->GetObjectField(windowObj,
696 gInputWindowClassInfo.name));
Jeff Brown349703e2010-06-22 01:27:15 -0700697 jint layoutParamsFlags = env->GetIntField(windowObj,
698 gInputWindowClassInfo.layoutParamsFlags);
699 jint layoutParamsType = env->GetIntField(windowObj,
700 gInputWindowClassInfo.layoutParamsType);
701 jlong dispatchingTimeoutNanos = env->GetLongField(windowObj,
702 gInputWindowClassInfo.dispatchingTimeoutNanos);
703 jint frameLeft = env->GetIntField(windowObj,
704 gInputWindowClassInfo.frameLeft);
705 jint frameTop = env->GetIntField(windowObj,
706 gInputWindowClassInfo.frameTop);
Jeff Brown85a31762010-09-01 17:01:00 -0700707 jint frameRight = env->GetIntField(windowObj,
708 gInputWindowClassInfo.frameRight);
709 jint frameBottom = env->GetIntField(windowObj,
710 gInputWindowClassInfo.frameBottom);
711 jint visibleFrameLeft = env->GetIntField(windowObj,
712 gInputWindowClassInfo.visibleFrameLeft);
713 jint visibleFrameTop = env->GetIntField(windowObj,
714 gInputWindowClassInfo.visibleFrameTop);
715 jint visibleFrameRight = env->GetIntField(windowObj,
716 gInputWindowClassInfo.visibleFrameRight);
717 jint visibleFrameBottom = env->GetIntField(windowObj,
718 gInputWindowClassInfo.visibleFrameBottom);
Jeff Brown349703e2010-06-22 01:27:15 -0700719 jint touchableAreaLeft = env->GetIntField(windowObj,
720 gInputWindowClassInfo.touchableAreaLeft);
721 jint touchableAreaTop = env->GetIntField(windowObj,
722 gInputWindowClassInfo.touchableAreaTop);
723 jint touchableAreaRight = env->GetIntField(windowObj,
724 gInputWindowClassInfo.touchableAreaRight);
725 jint touchableAreaBottom = env->GetIntField(windowObj,
726 gInputWindowClassInfo.touchableAreaBottom);
727 jboolean visible = env->GetBooleanField(windowObj,
728 gInputWindowClassInfo.visible);
Jeff Brown519e0242010-09-15 15:18:56 -0700729 jboolean canReceiveKeys = env->GetBooleanField(windowObj,
730 gInputWindowClassInfo.canReceiveKeys);
Jeff Brown349703e2010-06-22 01:27:15 -0700731 jboolean hasFocus = env->GetBooleanField(windowObj,
732 gInputWindowClassInfo.hasFocus);
733 jboolean hasWallpaper = env->GetBooleanField(windowObj,
734 gInputWindowClassInfo.hasWallpaper);
735 jboolean paused = env->GetBooleanField(windowObj,
736 gInputWindowClassInfo.paused);
Jeff Brown519e0242010-09-15 15:18:56 -0700737 jint layer = env->GetIntField(windowObj,
738 gInputWindowClassInfo.layer);
Jeff Brown349703e2010-06-22 01:27:15 -0700739 jint ownerPid = env->GetIntField(windowObj,
740 gInputWindowClassInfo.ownerPid);
741 jint ownerUid = env->GetIntField(windowObj,
742 gInputWindowClassInfo.ownerUid);
743
Jeff Brown519e0242010-09-15 15:18:56 -0700744 const char* nameStr = env->GetStringUTFChars(name, NULL);
745
Jeff Brown349703e2010-06-22 01:27:15 -0700746 outWindow.inputChannel = inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -0700747 outWindow.name.setTo(nameStr);
Jeff Brown349703e2010-06-22 01:27:15 -0700748 outWindow.layoutParamsFlags = layoutParamsFlags;
749 outWindow.layoutParamsType = layoutParamsType;
750 outWindow.dispatchingTimeout = dispatchingTimeoutNanos;
751 outWindow.frameLeft = frameLeft;
752 outWindow.frameTop = frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -0700753 outWindow.frameRight = frameRight;
754 outWindow.frameBottom = frameBottom;
755 outWindow.visibleFrameLeft = visibleFrameLeft;
756 outWindow.visibleFrameTop = visibleFrameTop;
757 outWindow.visibleFrameRight = visibleFrameRight;
758 outWindow.visibleFrameBottom = visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -0700759 outWindow.touchableAreaLeft = touchableAreaLeft;
760 outWindow.touchableAreaTop = touchableAreaTop;
761 outWindow.touchableAreaRight = touchableAreaRight;
762 outWindow.touchableAreaBottom = touchableAreaBottom;
763 outWindow.visible = visible;
Jeff Brown519e0242010-09-15 15:18:56 -0700764 outWindow.canReceiveKeys = canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -0700765 outWindow.hasFocus = hasFocus;
766 outWindow.hasWallpaper = hasWallpaper;
767 outWindow.paused = paused;
Jeff Brown519e0242010-09-15 15:18:56 -0700768 outWindow.layer = layer;
Jeff Brown349703e2010-06-22 01:27:15 -0700769 outWindow.ownerPid = ownerPid;
770 outWindow.ownerUid = ownerUid;
Jeff Brown519e0242010-09-15 15:18:56 -0700771
772 env->ReleaseStringUTFChars(name, nameStr);
Jeff Brown349703e2010-06-22 01:27:15 -0700773 valid = true;
774 } else {
775 LOGW("Dropping input target because its input channel is not initialized.");
776 }
777
778 env->DeleteLocalRef(inputChannelObj);
779 } else {
780 LOGW("Dropping input target because the input channel object was null.");
781 }
782 return valid;
783}
784
785void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700786 if (applicationObj) {
787 jstring nameObj = jstring(env->GetObjectField(applicationObj,
788 gInputApplicationClassInfo.name));
789 jlong dispatchingTimeoutNanos = env->GetLongField(applicationObj,
790 gInputApplicationClassInfo.dispatchingTimeoutNanos);
791 jobject tokenObj = env->GetObjectField(applicationObj,
792 gInputApplicationClassInfo.token);
793 jweak tokenObjWeak = env->NewWeakGlobalRef(tokenObj);
794 if (! tokenObjWeak) {
795 LOGE("Could not create weak reference for application token.");
796 LOGE_EX(env);
797 env->ExceptionClear();
798 }
799 env->DeleteLocalRef(tokenObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700800
Jeff Brownb88102f2010-09-08 11:49:43 -0700801 String8 name;
802 if (nameObj) {
803 const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
804 name.setTo(nameStr);
805 env->ReleaseStringUTFChars(nameObj, nameStr);
806 env->DeleteLocalRef(nameObj);
807 } else {
808 LOGE("InputApplication.name should not be null.");
809 name.setTo("unknown");
Jeff Brown349703e2010-06-22 01:27:15 -0700810 }
811
Jeff Brownb88102f2010-09-08 11:49:43 -0700812 InputApplication application;
813 application.name = name;
814 application.dispatchingTimeout = dispatchingTimeoutNanos;
815 application.handle = new ApplicationToken(tokenObjWeak);
816 mInputManager->getDispatcher()->setFocusedApplication(& application);
817 } else {
818 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700819 }
820}
821
822void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700823 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700824}
825
Jeff Browne20c9e02010-10-11 14:20:19 -0700826bool NativeInputManager::isScreenOn() {
827 return android_server_PowerManagerService_isScreenOn();
828}
829
830bool NativeInputManager::isScreenBright() {
831 return android_server_PowerManagerService_isScreenBright();
832}
833
834void NativeInputManager::interceptKeyBeforeQueueing(nsecs_t when,
835 int32_t deviceId, int32_t action, int32_t &flags,
836 int32_t keyCode, int32_t scanCode, uint32_t& policyFlags) {
837#if DEBUG_INPUT_DISPATCHER_POLICY
838 LOGD("interceptKeyBeforeQueueing - when=%lld, deviceId=%d, action=%d, flags=%d, "
839 "keyCode=%d, scanCode=%d, policyFlags=0x%x",
840 when, deviceId, action, flags, keyCode, scanCode, policyFlags);
841#endif
842
843 if ((policyFlags & POLICY_FLAG_VIRTUAL) || (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY)) {
844 policyFlags |= POLICY_FLAG_VIRTUAL;
845 flags |= AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
Jeff Brownb88102f2010-09-08 11:49:43 -0700846 }
847
Jeff Brown3122e442010-10-11 23:32:49 -0700848 // Policy:
849 // - Ignore untrusted events and pass them along.
850 // - Ask the window manager what to do with normal events and trusted injected events.
851 // - For normal events wake and brighten the screen if currently off or dim.
852 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
853 const int32_t WM_ACTION_PASS_TO_USER = 1;
854 const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
855 const int32_t WM_ACTION_GO_TO_SLEEP = 4;
Jeff Browne20c9e02010-10-11 14:20:19 -0700856
Jeff Brown3122e442010-10-11 23:32:49 -0700857 bool isScreenOn = this->isScreenOn();
858 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700859
Jeff Brown3122e442010-10-11 23:32:49 -0700860 JNIEnv* env = jniEnv();
861 jint wmActions = env->CallIntMethod(mCallbacksObj,
862 gCallbacksClassInfo.interceptKeyBeforeQueueing,
Jeff Brown4d396052010-10-29 21:50:21 -0700863 when, action, flags, keyCode, scanCode, policyFlags, isScreenOn);
Jeff Brown3122e442010-10-11 23:32:49 -0700864 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
865 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700866 }
867
Jeff Brown3122e442010-10-11 23:32:49 -0700868 if (!(flags & POLICY_FLAG_INJECTED)) {
869 if (!isScreenOn) {
870 policyFlags |= POLICY_FLAG_WOKE_HERE;
871 flags |= AKEY_EVENT_FLAG_WOKE_HERE;
872 }
873
874 if (!isScreenBright) {
875 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
876 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700877 }
878
879 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
880 android_server_PowerManagerService_goToSleep(when);
881 }
882
883 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
884 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
885 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700886
Jeff Brown3122e442010-10-11 23:32:49 -0700887 if (wmActions & WM_ACTION_PASS_TO_USER) {
888 policyFlags |= POLICY_FLAG_PASS_TO_USER;
889 }
890 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700891 policyFlags |= POLICY_FLAG_PASS_TO_USER;
892 }
893}
894
895void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
896#if DEBUG_INPUT_DISPATCHER_POLICY
897 LOGD("interceptGenericBeforeQueueing - when=%lld, policyFlags=0x%x", when, policyFlags);
898#endif
899
Jeff Brown3122e442010-10-11 23:32:49 -0700900 // Policy:
901 // - Ignore untrusted events and pass them along.
902 // - No special filtering for injected events required at this time.
903 // - Filter normal events based on screen state.
904 // - For normal events brighten (but do not wake) the screen if currently dim.
905 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
906 if (isScreenOn()) {
907 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700908
Jeff Brown3122e442010-10-11 23:32:49 -0700909 if (!isScreenBright()) {
910 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
911 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700912 }
Jeff Brown3122e442010-10-11 23:32:49 -0700913 } else {
914 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700915 }
916}
917
918bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
919 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700920 // Policy:
921 // - Ignore untrusted events and pass them along.
922 // - Filter normal events and trusted injected events through the window manager policy to
923 // handle the HOME key and the like.
924 if (policyFlags & POLICY_FLAG_TRUSTED) {
925 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700926
Jeff Brown3122e442010-10-11 23:32:49 -0700927 // Note: inputChannel may be null.
928 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
929 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
930 gCallbacksClassInfo.interceptKeyBeforeDispatching,
931 inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
Jeff Brown4d396052010-10-29 21:50:21 -0700932 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
Jeff Brown3122e442010-10-11 23:32:49 -0700933 keyEvent->getRepeatCount(), policyFlags);
934 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
Jeff Brownd0097872010-06-30 14:41:59 -0700935
Jeff Brown3122e442010-10-11 23:32:49 -0700936 env->DeleteLocalRef(inputChannelObj);
937 return consumed && ! error;
938 } else {
939 return false;
940 }
Jeff Brownd0097872010-06-30 14:41:59 -0700941}
942
Jeff Brown3915bb82010-11-05 15:02:16 -0700943bool NativeInputManager::dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
944 const KeyEvent* keyEvent, uint32_t policyFlags) {
945 // Policy:
946 // - Ignore untrusted events and do not perform default handling.
947 if (policyFlags & POLICY_FLAG_TRUSTED) {
948 JNIEnv* env = jniEnv();
949
950 // Note: inputChannel may be null.
951 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
952 jboolean handled = env->CallBooleanMethod(mCallbacksObj,
953 gCallbacksClassInfo.dispatchUnhandledKey,
954 inputChannelObj, keyEvent->getAction(), keyEvent->getFlags(),
955 keyEvent->getKeyCode(), keyEvent->getScanCode(), keyEvent->getMetaState(),
956 keyEvent->getRepeatCount(), policyFlags);
957 bool error = checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey");
958
959 env->DeleteLocalRef(inputChannelObj);
960 return handled && ! error;
961 } else {
962 return false;
963 }
964}
965
Jeff Brown01ce2e92010-09-26 22:20:12 -0700966void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
967 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700968}
969
Jeff Brown349703e2010-06-22 01:27:15 -0700970
Jeff Brownb88102f2010-09-08 11:49:43 -0700971bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
972 int32_t injectorPid, int32_t injectorUid) {
973 JNIEnv* env = jniEnv();
974 jboolean result = env->CallBooleanMethod(mCallbacksObj,
975 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
976 checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");
Jeff Brown349703e2010-06-22 01:27:15 -0700977 return result;
978}
979
Jeff Brown9c3cda02010-06-15 01:31:58 -0700980// ----------------------------------------------------------------------------
981
982static sp<NativeInputManager> gNativeInputManager;
983
Jeff Brown46b9ac02010-04-22 18:58:52 -0700984static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700985 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700986 LOGE("Input manager not initialized.");
987 jniThrowRuntimeException(env, "Input manager not initialized.");
988 return true;
989 }
990 return false;
991}
992
993static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
994 jobject callbacks) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700995 if (gNativeInputManager == NULL) {
996 gNativeInputManager = new NativeInputManager(callbacks);
997 } else {
998 LOGE("Input manager already initialized.");
999 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001000 }
1001}
1002
1003static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
1004 if (checkInputManagerUnitialized(env)) {
1005 return;
1006 }
1007
Jeff Brown9c3cda02010-06-15 01:31:58 -07001008 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -07001009 if (result) {
1010 jniThrowRuntimeException(env, "Input manager could not be started.");
1011 }
1012}
1013
1014static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
1015 jint displayId, jint width, jint height) {
1016 if (checkInputManagerUnitialized(env)) {
1017 return;
1018 }
1019
1020 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
1021 // to be passed in like this, not sure which is better but leaving it like this
1022 // keeps the window manager in direct control of when display transitions propagate down
1023 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -07001024 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001025}
1026
1027static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
1028 jint displayId, jint orientation) {
1029 if (checkInputManagerUnitialized(env)) {
1030 return;
1031 }
1032
Jeff Brown9c3cda02010-06-15 01:31:58 -07001033 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001034}
1035
1036static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001037 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001038 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001039 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001040 }
1041
Jeff Brownb88102f2010-09-08 11:49:43 -07001042 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001043 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001044}
1045
1046static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001047 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001048 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001049 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001050 }
1051
Jeff Brownb88102f2010-09-08 11:49:43 -07001052 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001053 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001054}
1055
1056static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001057 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001058 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001059 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001060 }
1061
Jeff Brownb88102f2010-09-08 11:49:43 -07001062 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001063 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001064}
1065
1066static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001067 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001068 if (checkInputManagerUnitialized(env)) {
1069 return JNI_FALSE;
1070 }
1071
1072 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1073 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1074 jsize numCodes = env->GetArrayLength(keyCodes);
1075 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001076 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001077 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001078 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001079 } else {
1080 result = JNI_FALSE;
1081 }
1082
1083 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1084 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1085 return result;
1086}
1087
1088static void throwInputChannelNotInitialized(JNIEnv* env) {
1089 jniThrowException(env, "java/lang/IllegalStateException",
1090 "inputChannel is not initialized");
1091}
1092
1093static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1094 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1095 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1096 "the input manager!", inputChannel->getName().string());
1097
Jeff Brown9c3cda02010-06-15 01:31:58 -07001098 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001099 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001100 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001101}
1102
1103static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Browna41ca772010-08-11 14:46:32 -07001104 jobject inputChannelObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001105 if (checkInputManagerUnitialized(env)) {
1106 return;
1107 }
1108
1109 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1110 inputChannelObj);
1111 if (inputChannel == NULL) {
1112 throwInputChannelNotInitialized(env);
1113 return;
1114 }
1115
Jeff Brown7fbdc842010-06-17 20:52:56 -07001116
1117 status_t status = gNativeInputManager->registerInputChannel(
Jeff Browna41ca772010-08-11 14:46:32 -07001118 env, inputChannel, inputChannelObj, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001119 if (status) {
1120 jniThrowRuntimeException(env, "Failed to register input channel. "
1121 "Check logs for details.");
1122 return;
1123 }
1124
Jeff Browna41ca772010-08-11 14:46:32 -07001125 if (! monitor) {
1126 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1127 android_server_InputManager_handleInputChannelDisposed, NULL);
1128 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001129}
1130
1131static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1132 jobject inputChannelObj) {
1133 if (checkInputManagerUnitialized(env)) {
1134 return;
1135 }
1136
1137 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1138 inputChannelObj);
1139 if (inputChannel == NULL) {
1140 throwInputChannelNotInitialized(env);
1141 return;
1142 }
1143
1144 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1145
Jeff Brown7fbdc842010-06-17 20:52:56 -07001146 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001147 if (status) {
1148 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1149 "Check logs for details.");
1150 }
1151}
1152
Jeff Brown6ec402b2010-07-28 15:48:59 -07001153static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1154 jobject inputEventObj, jint injectorPid, jint injectorUid,
1155 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001156 if (checkInputManagerUnitialized(env)) {
1157 return INPUT_EVENT_INJECTION_FAILED;
1158 }
1159
Jeff Brown6ec402b2010-07-28 15:48:59 -07001160 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1161 KeyEvent keyEvent;
1162 android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001163
Jeff Brownb88102f2010-09-08 11:49:43 -07001164 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1165 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001166 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1167 MotionEvent motionEvent;
1168 android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001169
Jeff Brownb88102f2010-09-08 11:49:43 -07001170 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1171 & motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001172 } else {
1173 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001174 return INPUT_EVENT_INJECTION_FAILED;
1175 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001176}
1177
Jeff Brown349703e2010-06-22 01:27:15 -07001178static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1179 jobjectArray windowObjArray) {
1180 if (checkInputManagerUnitialized(env)) {
1181 return;
1182 }
1183
1184 gNativeInputManager->setInputWindows(env, windowObjArray);
1185}
1186
1187static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1188 jobject applicationObj) {
1189 if (checkInputManagerUnitialized(env)) {
1190 return;
1191 }
1192
1193 gNativeInputManager->setFocusedApplication(env, applicationObj);
1194}
1195
1196static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1197 jclass clazz, jboolean enabled, jboolean frozen) {
1198 if (checkInputManagerUnitialized(env)) {
1199 return;
1200 }
1201
1202 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1203}
1204
Jeff Brown8d608662010-08-30 03:02:23 -07001205static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1206 jclass clazz, jint deviceId) {
1207 if (checkInputManagerUnitialized(env)) {
1208 return NULL;
1209 }
1210
1211 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001212 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001213 deviceId, & deviceInfo);
1214 if (status) {
1215 return NULL;
1216 }
1217
1218 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1219 if (! deviceObj) {
1220 return NULL;
1221 }
1222
1223 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1224 if (! deviceNameObj) {
1225 return NULL;
1226 }
1227
1228 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1229 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1230 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1231 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1232
1233 const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1234 for (size_t i = 0; i < ranges.size(); i++) {
1235 int rangeType = ranges.keyAt(i);
1236 const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
1237 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
1238 rangeType, range.min, range.max, range.flat, range.fuzz);
1239 if (env->ExceptionCheck()) {
1240 return NULL;
1241 }
1242 }
1243
1244 return deviceObj;
1245}
1246
1247static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1248 jclass clazz) {
1249 if (checkInputManagerUnitialized(env)) {
1250 return NULL;
1251 }
1252
1253 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001254 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001255
1256 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1257 if (! deviceIdsObj) {
1258 return NULL;
1259 }
1260
1261 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1262 return deviceIdsObj;
1263}
1264
Jeff Brown57c59372010-09-21 18:22:55 -07001265static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1266 jclass clazz, jobject configObj) {
1267 if (checkInputManagerUnitialized(env)) {
1268 return;
1269 }
1270
1271 InputConfiguration config;
1272 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1273
1274 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1275 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1276 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1277}
1278
Jeff Browne6504122010-09-27 14:52:15 -07001279static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1280 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1281 if (checkInputManagerUnitialized(env)) {
1282 return false;
1283 }
1284
1285 sp<InputChannel> fromChannel =
1286 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1287 sp<InputChannel> toChannel =
1288 android_view_InputChannel_getInputChannel(env, toChannelObj);
1289
1290 if (fromChannel == NULL || toChannel == NULL) {
1291 return false;
1292 }
1293
1294 return gNativeInputManager->getInputManager()->getDispatcher()->
1295 transferTouchFocus(fromChannel, toChannel);
1296}
1297
Jeff Browne33348b2010-07-15 23:54:05 -07001298static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1299 if (checkInputManagerUnitialized(env)) {
1300 return NULL;
1301 }
1302
Jeff Brownb88102f2010-09-08 11:49:43 -07001303 String8 dump;
1304 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001305 return env->NewStringUTF(dump.string());
1306}
1307
Jeff Brown9c3cda02010-06-15 01:31:58 -07001308// ----------------------------------------------------------------------------
1309
Jeff Brown46b9ac02010-04-22 18:58:52 -07001310static JNINativeMethod gInputManagerMethods[] = {
1311 /* name, signature, funcPtr */
1312 { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
1313 (void*) android_server_InputManager_nativeInit },
1314 { "nativeStart", "()V",
1315 (void*) android_server_InputManager_nativeStart },
1316 { "nativeSetDisplaySize", "(III)V",
1317 (void*) android_server_InputManager_nativeSetDisplaySize },
1318 { "nativeSetDisplayOrientation", "(II)V",
1319 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1320 { "nativeGetScanCodeState", "(III)I",
1321 (void*) android_server_InputManager_nativeGetScanCodeState },
1322 { "nativeGetKeyCodeState", "(III)I",
1323 (void*) android_server_InputManager_nativeGetKeyCodeState },
1324 { "nativeGetSwitchState", "(III)I",
1325 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001326 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001327 (void*) android_server_InputManager_nativeHasKeys },
Jeff Browna41ca772010-08-11 14:46:32 -07001328 { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001329 (void*) android_server_InputManager_nativeRegisterInputChannel },
1330 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001331 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001332 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1333 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown349703e2010-06-22 01:27:15 -07001334 { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
1335 (void*) android_server_InputManager_nativeSetInputWindows },
1336 { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
1337 (void*) android_server_InputManager_nativeSetFocusedApplication },
1338 { "nativeSetInputDispatchMode", "(ZZ)V",
1339 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown8d608662010-08-30 03:02:23 -07001340 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1341 (void*) android_server_InputManager_nativeGetInputDevice },
1342 { "nativeGetInputDeviceIds", "()[I",
1343 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001344 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1345 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001346 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1347 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001348 { "nativeDump", "()Ljava/lang/String;",
1349 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001350};
1351
1352#define FIND_CLASS(var, className) \
1353 var = env->FindClass(className); \
1354 LOG_FATAL_IF(! var, "Unable to find class " className); \
1355 var = jclass(env->NewGlobalRef(var));
1356
1357#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1358 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1359 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1360
1361#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1362 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1363 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1364
1365int register_android_server_InputManager(JNIEnv* env) {
1366 int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
1367 gInputManagerMethods, NELEM(gInputManagerMethods));
1368 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1369
Jeff Brown9c3cda02010-06-15 01:31:58 -07001370 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001371
1372 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
1373
Jeff Brown46b9ac02010-04-22 18:58:52 -07001374 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001375 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001376
1377 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1378 "notifyLidSwitchChanged", "(JZ)V");
1379
Jeff Brown7fbdc842010-06-17 20:52:56 -07001380 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
1381 "notifyInputChannelBroken", "(Landroid/view/InputChannel;)V");
1382
Jeff Brown349703e2010-06-22 01:27:15 -07001383 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown519e0242010-09-15 15:18:56 -07001384 "notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001385
Jeff Brown349703e2010-06-22 01:27:15 -07001386 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown4d396052010-10-29 21:50:21 -07001387 "interceptKeyBeforeQueueing", "(JIIIIIZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001388
1389 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown4d396052010-10-29 21:50:21 -07001390 "interceptKeyBeforeDispatching", "(Landroid/view/InputChannel;IIIIIII)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001391
Jeff Brown3915bb82010-11-05 15:02:16 -07001392 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
1393 "dispatchUnhandledKey", "(Landroid/view/InputChannel;IIIIIII)Z");
1394
Jeff Brown349703e2010-06-22 01:27:15 -07001395 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1396 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001397
Jeff Brown46b9ac02010-04-22 18:58:52 -07001398 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1399 "filterTouchEvents", "()Z");
1400
1401 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1402 "filterJumpyTouchEvents", "()Z");
1403
1404 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyDefinitions, gCallbacksClassInfo.clazz,
1405 "getVirtualKeyDefinitions",
1406 "(Ljava/lang/String;)[Lcom/android/server/InputManager$VirtualKeyDefinition;");
1407
Jeff Brown8d608662010-08-30 03:02:23 -07001408 GET_METHOD_ID(gCallbacksClassInfo.getInputDeviceCalibration, gCallbacksClassInfo.clazz,
1409 "getInputDeviceCalibration",
1410 "(Ljava/lang/String;)Lcom/android/server/InputManager$InputDeviceCalibration;");
1411
Jeff Brown46b9ac02010-04-22 18:58:52 -07001412 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1413 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1414
Jeff Brownae9fc032010-08-18 15:51:08 -07001415 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1416 "getMaxEventsPerSecond", "()I");
1417
Jeff Brown46b9ac02010-04-22 18:58:52 -07001418 // VirtualKeyDefinition
1419
1420 FIND_CLASS(gVirtualKeyDefinitionClassInfo.clazz,
1421 "com/android/server/InputManager$VirtualKeyDefinition");
1422
1423 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.scanCode, gVirtualKeyDefinitionClassInfo.clazz,
1424 "scanCode", "I");
1425
1426 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerX, gVirtualKeyDefinitionClassInfo.clazz,
1427 "centerX", "I");
1428
1429 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.centerY, gVirtualKeyDefinitionClassInfo.clazz,
1430 "centerY", "I");
1431
1432 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.width, gVirtualKeyDefinitionClassInfo.clazz,
1433 "width", "I");
1434
1435 GET_FIELD_ID(gVirtualKeyDefinitionClassInfo.height, gVirtualKeyDefinitionClassInfo.clazz,
1436 "height", "I");
1437
Jeff Brown8d608662010-08-30 03:02:23 -07001438 // InputDeviceCalibration
1439
1440 FIND_CLASS(gInputDeviceCalibrationClassInfo.clazz,
1441 "com/android/server/InputManager$InputDeviceCalibration");
1442
1443 GET_FIELD_ID(gInputDeviceCalibrationClassInfo.keys, gInputDeviceCalibrationClassInfo.clazz,
1444 "keys", "[Ljava/lang/String;");
1445
1446 GET_FIELD_ID(gInputDeviceCalibrationClassInfo.values, gInputDeviceCalibrationClassInfo.clazz,
1447 "values", "[Ljava/lang/String;");
1448
Jeff Brown349703e2010-06-22 01:27:15 -07001449 // InputWindow
Jeff Brown7fbdc842010-06-17 20:52:56 -07001450
Jeff Brown349703e2010-06-22 01:27:15 -07001451 FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001452
Jeff Brown349703e2010-06-22 01:27:15 -07001453 GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
1454 "inputChannel", "Landroid/view/InputChannel;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001455
Jeff Brown519e0242010-09-15 15:18:56 -07001456 GET_FIELD_ID(gInputWindowClassInfo.name, gInputWindowClassInfo.clazz,
1457 "name", "Ljava/lang/String;");
1458
Jeff Brown349703e2010-06-22 01:27:15 -07001459 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, gInputWindowClassInfo.clazz,
1460 "layoutParamsFlags", "I");
1461
1462 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, gInputWindowClassInfo.clazz,
1463 "layoutParamsType", "I");
1464
1465 GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, gInputWindowClassInfo.clazz,
1466 "dispatchingTimeoutNanos", "J");
1467
1468 GET_FIELD_ID(gInputWindowClassInfo.frameLeft, gInputWindowClassInfo.clazz,
1469 "frameLeft", "I");
1470
1471 GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz,
1472 "frameTop", "I");
1473
Jeff Brown85a31762010-09-01 17:01:00 -07001474 GET_FIELD_ID(gInputWindowClassInfo.frameRight, gInputWindowClassInfo.clazz,
1475 "frameRight", "I");
1476
1477 GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz,
1478 "frameBottom", "I");
1479
1480 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameLeft, gInputWindowClassInfo.clazz,
1481 "visibleFrameLeft", "I");
1482
1483 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameTop, gInputWindowClassInfo.clazz,
1484 "visibleFrameTop", "I");
1485
1486 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameRight, gInputWindowClassInfo.clazz,
1487 "visibleFrameRight", "I");
1488
1489 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameBottom, gInputWindowClassInfo.clazz,
1490 "visibleFrameBottom", "I");
1491
Jeff Brown349703e2010-06-22 01:27:15 -07001492 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz,
1493 "touchableAreaLeft", "I");
1494
1495 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaTop, gInputWindowClassInfo.clazz,
1496 "touchableAreaTop", "I");
1497
1498 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaRight, gInputWindowClassInfo.clazz,
1499 "touchableAreaRight", "I");
1500
1501 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaBottom, gInputWindowClassInfo.clazz,
1502 "touchableAreaBottom", "I");
1503
1504 GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz,
1505 "visible", "Z");
1506
Jeff Brown519e0242010-09-15 15:18:56 -07001507 GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, gInputWindowClassInfo.clazz,
1508 "canReceiveKeys", "Z");
1509
Jeff Brown349703e2010-06-22 01:27:15 -07001510 GET_FIELD_ID(gInputWindowClassInfo.hasFocus, gInputWindowClassInfo.clazz,
1511 "hasFocus", "Z");
1512
1513 GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, gInputWindowClassInfo.clazz,
1514 "hasWallpaper", "Z");
1515
1516 GET_FIELD_ID(gInputWindowClassInfo.paused, gInputWindowClassInfo.clazz,
1517 "paused", "Z");
1518
Jeff Brown519e0242010-09-15 15:18:56 -07001519 GET_FIELD_ID(gInputWindowClassInfo.layer, gInputWindowClassInfo.clazz,
1520 "layer", "I");
1521
Jeff Brown349703e2010-06-22 01:27:15 -07001522 GET_FIELD_ID(gInputWindowClassInfo.ownerPid, gInputWindowClassInfo.clazz,
1523 "ownerPid", "I");
1524
1525 GET_FIELD_ID(gInputWindowClassInfo.ownerUid, gInputWindowClassInfo.clazz,
1526 "ownerUid", "I");
1527
1528 // InputApplication
1529
1530 FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");
1531
1532 GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
1533 "name", "Ljava/lang/String;");
1534
1535 GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
1536 gInputApplicationClassInfo.clazz,
1537 "dispatchingTimeoutNanos", "J");
1538
1539 GET_FIELD_ID(gInputApplicationClassInfo.token, gInputApplicationClassInfo.clazz,
1540 "token", "Ljava/lang/Object;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001541
Jeff Brown6ec402b2010-07-28 15:48:59 -07001542 // KeyEvent
1543
1544 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1545
Jeff Brown8d608662010-08-30 03:02:23 -07001546 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001547
1548 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1549
Jeff Brown8d608662010-08-30 03:02:23 -07001550 // InputDevice
1551
1552 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1553
1554 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1555 "<init>", "()V");
1556
1557 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
1558 "addMotionRange", "(IFFFF)V");
1559
1560 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1561 "mId", "I");
1562
1563 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1564 "mName", "Ljava/lang/String;");
1565
1566 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1567 "mSources", "I");
1568
1569 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1570 "mKeyboardType", "I");
1571
1572 GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
1573 "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
1574
Jeff Brown57c59372010-09-21 18:22:55 -07001575 // Configuration
1576
1577 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1578
1579 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1580 "touchscreen", "I");
1581
1582 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1583 "keyboard", "I");
1584
1585 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1586 "navigation", "I");
1587
Jeff Brown46b9ac02010-04-22 18:58:52 -07001588 return 0;
1589}
1590
Jeff Brown46b9ac02010-04-22 18:58:52 -07001591} /* namespace android */