blob: 5ed63f0b14dceb2ab3ec67a254acf88e3bc607e9 [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 Brown83c09682010-12-23 17:50:18 -080027
Jeff Brown46b9ac02010-04-22 18:58:52 -070028#include "JNIHelp.h"
29#include "jni.h"
Jeff Brown349703e2010-06-22 01:27:15 -070030#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070031#include <android_runtime/AndroidRuntime.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080032
Jeff Brown46b9ac02010-04-22 18:58:52 -070033#include <utils/Log.h>
34#include <utils/threads.h>
Jeff Brown83c09682010-12-23 17:50:18 -080035
Jeff Brownb4ff35d2011-01-02 16:37:43 -080036#include <input/InputManager.h>
37#include <input/PointerController.h>
38
39#include <android_view_KeyEvent.h>
40#include <android_view_MotionEvent.h>
41#include <android_view_InputChannel.h>
42#include <android/graphics/GraphicsJNI.h>
43
Jeff Brown00fa7bd2010-07-02 15:37:36 -070044#include "com_android_server_PowerManagerService.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070045
46namespace android {
47
Jeff Brown9c3cda02010-06-15 01:31:58 -070048// ----------------------------------------------------------------------------
Jeff Brown46b9ac02010-04-22 18:58:52 -070049
50static struct {
51 jclass clazz;
52
Jeff Brown46b9ac02010-04-22 18:58:52 -070053 jmethodID notifyConfigurationChanged;
54 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070055 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070056 jmethodID notifyANR;
Jeff Brown349703e2010-06-22 01:27:15 -070057 jmethodID interceptKeyBeforeQueueing;
58 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070059 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070060 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070061 jmethodID filterTouchEvents;
62 jmethodID filterJumpyTouchEvents;
Jeff Brown46b9ac02010-04-22 18:58:52 -070063 jmethodID getExcludedDeviceNames;
Jeff Brownae9fc032010-08-18 15:51:08 -070064 jmethodID getMaxEventsPerSecond;
Jeff Brown83c09682010-12-23 17:50:18 -080065 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080066 jmethodID getPointerIcon;
Jeff Brown46b9ac02010-04-22 18:58:52 -070067} gCallbacksClassInfo;
68
69static struct {
70 jclass clazz;
71
Jeff Brown349703e2010-06-22 01:27:15 -070072 jfieldID inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -070073 jfieldID name;
Jeff Brown349703e2010-06-22 01:27:15 -070074 jfieldID layoutParamsFlags;
75 jfieldID layoutParamsType;
76 jfieldID dispatchingTimeoutNanos;
77 jfieldID frameLeft;
78 jfieldID frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -070079 jfieldID frameRight;
80 jfieldID frameBottom;
81 jfieldID visibleFrameLeft;
82 jfieldID visibleFrameTop;
83 jfieldID visibleFrameRight;
84 jfieldID visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -070085 jfieldID touchableAreaLeft;
86 jfieldID touchableAreaTop;
87 jfieldID touchableAreaRight;
88 jfieldID touchableAreaBottom;
89 jfieldID visible;
Jeff Brown519e0242010-09-15 15:18:56 -070090 jfieldID canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -070091 jfieldID hasFocus;
92 jfieldID hasWallpaper;
93 jfieldID paused;
Jeff Brown519e0242010-09-15 15:18:56 -070094 jfieldID layer;
Jeff Brown349703e2010-06-22 01:27:15 -070095 jfieldID ownerPid;
96 jfieldID ownerUid;
97} gInputWindowClassInfo;
98
99static struct {
100 jclass clazz;
101
102 jfieldID name;
103 jfieldID dispatchingTimeoutNanos;
104 jfieldID token;
105} gInputApplicationClassInfo;
106
Jeff Brown6ec402b2010-07-28 15:48:59 -0700107static struct {
108 jclass clazz;
109} gKeyEventClassInfo;
110
111static struct {
112 jclass clazz;
113} gMotionEventClassInfo;
114
Jeff Brown8d608662010-08-30 03:02:23 -0700115static struct {
116 jclass clazz;
117
118 jmethodID ctor;
119 jmethodID addMotionRange;
120
121 jfieldID mId;
122 jfieldID mName;
123 jfieldID mSources;
124 jfieldID mKeyboardType;
125 jfieldID mMotionRanges;
126} gInputDeviceClassInfo;
127
Jeff Brown57c59372010-09-21 18:22:55 -0700128static struct {
129 jclass clazz;
130
131 jfieldID touchscreen;
132 jfieldID keyboard;
133 jfieldID navigation;
134} gConfigurationClassInfo;
135
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800136static struct {
137 jclass clazz;
Jeff Brown349703e2010-06-22 01:27:15 -0700138
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800139 jfieldID bitmap;
140 jfieldID hotSpotX;
141 jfieldID hotSpotY;
142} gPointerIconClassInfo;
Jeff Brown83c09682010-12-23 17:50:18 -0800143
144// ----------------------------------------------------------------------------
145
Jeff Brown9c3cda02010-06-15 01:31:58 -0700146class NativeInputManager : public virtual RefBase,
147 public virtual InputReaderPolicyInterface,
148 public virtual InputDispatcherPolicyInterface {
149protected:
150 virtual ~NativeInputManager();
151
152public:
153 NativeInputManager(jobject callbacksObj);
154
155 inline sp<InputManager> getInputManager() const { return mInputManager; }
156
Jeff Brownb88102f2010-09-08 11:49:43 -0700157 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700158
Jeff Brown9c3cda02010-06-15 01:31:58 -0700159 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
160 void setDisplayOrientation(int32_t displayId, int32_t orientation);
161
Jeff Brown7fbdc842010-06-17 20:52:56 -0700162 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Browna41ca772010-08-11 14:46:32 -0700163 jweak inputChannelObjWeak, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700164 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
165
Jeff Brown349703e2010-06-22 01:27:15 -0700166 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
167 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
168 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700169
Jeff Brown9c3cda02010-06-15 01:31:58 -0700170 /* --- InputReaderPolicyInterface implementation --- */
171
172 virtual bool getDisplayInfo(int32_t displayId,
173 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700174 virtual bool filterTouchEvents();
175 virtual bool filterJumpyTouchEvents();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700176 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800177 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700178
179 /* --- InputDispatcherPolicyInterface implementation --- */
180
Jeff Browne20c9e02010-10-11 14:20:19 -0700181 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
182 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700183 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700184 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
185 const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700186 virtual void notifyInputChannelBroken(const sp<InputChannel>& inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700187 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700188 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700189 virtual int32_t getMaxEventsPerSecond();
Jeff Brown1f245102010-11-18 20:53:46 -0800190 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brownb6997262010-10-08 22:31:17 -0700191 virtual void interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brownb88102f2010-09-08 11:49:43 -0700192 virtual bool interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
193 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown3915bb82010-11-05 15:02:16 -0700194 virtual bool dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800195 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700196 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700197 virtual bool checkInjectEventsPermissionNonReentrant(
198 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700199
200private:
Jeff Brownb88102f2010-09-08 11:49:43 -0700201 class ApplicationToken : public InputApplicationHandle {
202 jweak mTokenObjWeak;
Jeff Brown349703e2010-06-22 01:27:15 -0700203
204 public:
Jeff Brownb88102f2010-09-08 11:49:43 -0700205 ApplicationToken(jweak tokenObjWeak) :
206 mTokenObjWeak(tokenObjWeak) { }
Jeff Brown349703e2010-06-22 01:27:15 -0700207
Jeff Brownb88102f2010-09-08 11:49:43 -0700208 virtual ~ApplicationToken() {
209 JNIEnv* env = NativeInputManager::jniEnv();
210 env->DeleteWeakGlobalRef(mTokenObjWeak);
211 }
Jeff Brown349703e2010-06-22 01:27:15 -0700212
Jeff Brownb88102f2010-09-08 11:49:43 -0700213 inline jweak getTokenObj() { return mTokenObjWeak; }
Jeff Brown349703e2010-06-22 01:27:15 -0700214 };
215
Jeff Brown9c3cda02010-06-15 01:31:58 -0700216 sp<InputManager> mInputManager;
217
218 jobject mCallbacksObj;
219
220 // Cached filtering policies.
221 int32_t mFilterTouchEvents;
222 int32_t mFilterJumpyTouchEvents;
223
Jeff Brownae9fc032010-08-18 15:51:08 -0700224 // Cached throttling policy.
225 int32_t mMaxEventsPerSecond;
226
Jeff Brown83c09682010-12-23 17:50:18 -0800227 Mutex mLock;
228 struct Locked {
229 // Display size information.
230 int32_t displayWidth, displayHeight; // -1 when initialized
231 int32_t displayOrientation;
232
233 // Pointer controller singleton, created and destroyed as needed.
234 wp<PointerController> pointerController;
235
236 // Weak references to all currently registered input channels by connection pointer.
237 KeyedVector<InputChannel*, jweak> inputChannelObjWeakTable;
238 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700239
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700240 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700241 bool isScreenOn();
242 bool isScreenBright();
243
Jeff Brown7fbdc842010-06-17 20:52:56 -0700244 jobject getInputChannelObjLocal(JNIEnv* env, const sp<InputChannel>& inputChannel);
245
Jeff Brown349703e2010-06-22 01:27:15 -0700246 static bool populateWindow(JNIEnv* env, jobject windowObj, InputWindow& outWindow);
Jeff Brown349703e2010-06-22 01:27:15 -0700247
Jeff Brownb88102f2010-09-08 11:49:43 -0700248 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700249
Jeff Brown9c3cda02010-06-15 01:31:58 -0700250 static inline JNIEnv* jniEnv() {
251 return AndroidRuntime::getJNIEnv();
252 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700253};
254
255// ----------------------------------------------------------------------------
256
257NativeInputManager::NativeInputManager(jobject callbacksObj) :
258 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
Jeff Brown83c09682010-12-23 17:50:18 -0800259 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700260 JNIEnv* env = jniEnv();
261
262 mCallbacksObj = env->NewGlobalRef(callbacksObj);
263
Jeff Brown83c09682010-12-23 17:50:18 -0800264 {
265 AutoMutex _l(mLock);
266 mLocked.displayWidth = -1;
267 mLocked.displayHeight = -1;
268 mLocked.displayOrientation = ROTATION_0;
269 }
270
Jeff Brown9c3cda02010-06-15 01:31:58 -0700271 sp<EventHub> eventHub = new EventHub();
272 mInputManager = new InputManager(eventHub, this, this);
273}
274
275NativeInputManager::~NativeInputManager() {
276 JNIEnv* env = jniEnv();
277
278 env->DeleteGlobalRef(mCallbacksObj);
279}
280
Jeff Brownb88102f2010-09-08 11:49:43 -0700281void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700282 mInputManager->getReader()->dump(dump);
283 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700284
Jeff Brownb88102f2010-09-08 11:49:43 -0700285 mInputManager->getDispatcher()->dump(dump);
286 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700287}
288
Jeff Brown7fbdc842010-06-17 20:52:56 -0700289bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700290 if (env->ExceptionCheck()) {
291 LOGE("An exception was thrown by callback '%s'.", methodName);
292 LOGE_EX(env);
293 env->ExceptionClear();
294 return true;
295 }
296 return false;
297}
298
299void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
300 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800301 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700302
Jeff Brown83c09682010-12-23 17:50:18 -0800303 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
304 mLocked.displayWidth = width;
305 mLocked.displayHeight = height;
306
307 sp<PointerController> controller = mLocked.pointerController.promote();
308 if (controller != NULL) {
309 controller->setDisplaySize(width, height);
310 }
311 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700312 }
313}
314
315void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
316 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800317 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700318
Jeff Brown83c09682010-12-23 17:50:18 -0800319 if (mLocked.displayOrientation != orientation) {
320 mLocked.displayOrientation = orientation;
321
322 sp<PointerController> controller = mLocked.pointerController.promote();
323 if (controller != NULL) {
324 controller->setDisplayOrientation(orientation);
325 }
326 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700327 }
328}
329
Jeff Brown7fbdc842010-06-17 20:52:56 -0700330status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Browna41ca772010-08-11 14:46:32 -0700331 const sp<InputChannel>& inputChannel, jobject inputChannelObj, bool monitor) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700332 jweak inputChannelObjWeak = env->NewWeakGlobalRef(inputChannelObj);
333 if (! inputChannelObjWeak) {
334 LOGE("Could not create weak reference for input channel.");
335 LOGE_EX(env);
336 return NO_MEMORY;
337 }
338
339 status_t status;
340 {
Jeff Brown83c09682010-12-23 17:50:18 -0800341 AutoMutex _l(mLock);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700342
Jeff Brown83c09682010-12-23 17:50:18 -0800343 ssize_t index = mLocked.inputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700344 if (index >= 0) {
345 LOGE("Input channel object '%s' has already been registered",
346 inputChannel->getName().string());
347 status = INVALID_OPERATION;
348 goto DeleteWeakRef;
349 }
350
Jeff Brown83c09682010-12-23 17:50:18 -0800351 mLocked.inputChannelObjWeakTable.add(inputChannel.get(), inputChannelObjWeak);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700352 }
353
Jeff Brownb88102f2010-09-08 11:49:43 -0700354 status = mInputManager->getDispatcher()->registerInputChannel(inputChannel, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700355 if (! status) {
Jeff Browna41ca772010-08-11 14:46:32 -0700356 // Success.
Jeff Brown7fbdc842010-06-17 20:52:56 -0700357 return OK;
358 }
359
Jeff Browna41ca772010-08-11 14:46:32 -0700360 // Failed!
Jeff Brown7fbdc842010-06-17 20:52:56 -0700361 {
Jeff Brown83c09682010-12-23 17:50:18 -0800362 AutoMutex _l(mLock);
363 mLocked.inputChannelObjWeakTable.removeItem(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700364 }
365
366DeleteWeakRef:
367 env->DeleteWeakGlobalRef(inputChannelObjWeak);
368 return status;
369}
370
371status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
372 const sp<InputChannel>& inputChannel) {
373 jweak inputChannelObjWeak;
374 {
Jeff Brown83c09682010-12-23 17:50:18 -0800375 AutoMutex _l(mLock);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700376
Jeff Brown83c09682010-12-23 17:50:18 -0800377 ssize_t index = mLocked.inputChannelObjWeakTable.indexOfKey(inputChannel.get());
Jeff Brown7fbdc842010-06-17 20:52:56 -0700378 if (index < 0) {
379 LOGE("Input channel object '%s' is not currently registered",
380 inputChannel->getName().string());
381 return INVALID_OPERATION;
382 }
383
Jeff Brown83c09682010-12-23 17:50:18 -0800384 inputChannelObjWeak = mLocked.inputChannelObjWeakTable.valueAt(index);
385 mLocked.inputChannelObjWeakTable.removeItemsAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700386 }
387
388 env->DeleteWeakGlobalRef(inputChannelObjWeak);
389
Jeff Brownb88102f2010-09-08 11:49:43 -0700390 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700391}
392
393jobject NativeInputManager::getInputChannelObjLocal(JNIEnv* env,
394 const sp<InputChannel>& inputChannel) {
Jeff Brown54a18252010-09-16 14:07:33 -0700395 InputChannel* inputChannelPtr = inputChannel.get();
396 if (! inputChannelPtr) {
397 return NULL;
398 }
399
Jeff Brown7fbdc842010-06-17 20:52:56 -0700400 {
Jeff Brown83c09682010-12-23 17:50:18 -0800401 AutoMutex _l(mLock);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700402
Jeff Brown83c09682010-12-23 17:50:18 -0800403 ssize_t index = mLocked.inputChannelObjWeakTable.indexOfKey(inputChannelPtr);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700404 if (index < 0) {
405 return NULL;
406 }
407
Jeff Brown83c09682010-12-23 17:50:18 -0800408 jweak inputChannelObjWeak = mLocked.inputChannelObjWeakTable.valueAt(index);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700409 return env->NewLocalRef(inputChannelObjWeak);
410 }
411}
412
Jeff Brown9c3cda02010-06-15 01:31:58 -0700413bool NativeInputManager::getDisplayInfo(int32_t displayId,
414 int32_t* width, int32_t* height, int32_t* orientation) {
415 bool result = false;
416 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800417 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700418
Jeff Brown83c09682010-12-23 17:50:18 -0800419 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700420 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800421 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700422 }
423 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800424 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700425 }
426 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800427 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700428 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700429 result = true;
430 }
431 }
432 return result;
433}
434
Jeff Brown9c3cda02010-06-15 01:31:58 -0700435bool NativeInputManager::filterTouchEvents() {
436 if (mFilterTouchEvents < 0) {
437 JNIEnv* env = jniEnv();
438
439 jboolean result = env->CallBooleanMethod(mCallbacksObj,
440 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700441 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700442 result = false;
443 }
444
445 mFilterTouchEvents = result ? 1 : 0;
446 }
447 return mFilterTouchEvents;
448}
449
450bool NativeInputManager::filterJumpyTouchEvents() {
451 if (mFilterJumpyTouchEvents < 0) {
452 JNIEnv* env = jniEnv();
453
454 jboolean result = env->CallBooleanMethod(mCallbacksObj,
455 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700456 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700457 result = false;
458 }
459
460 mFilterJumpyTouchEvents = result ? 1 : 0;
461 }
462 return mFilterJumpyTouchEvents;
463}
464
Jeff Brown9c3cda02010-06-15 01:31:58 -0700465void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700466 outExcludedDeviceNames.clear();
467
Jeff Brown9c3cda02010-06-15 01:31:58 -0700468 JNIEnv* env = jniEnv();
469
470 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
471 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700472 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700473 jsize length = env->GetArrayLength(result);
474 for (jsize i = 0; i < length; i++) {
475 jstring item = jstring(env->GetObjectArrayElement(result, i));
476
477 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
478 outExcludedDeviceNames.add(String8(deviceNameChars));
479 env->ReleaseStringUTFChars(item, deviceNameChars);
480
481 env->DeleteLocalRef(item);
482 }
483 env->DeleteLocalRef(result);
484 }
485}
486
Jeff Brown83c09682010-12-23 17:50:18 -0800487sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
488 AutoMutex _l(mLock);
489
490 sp<PointerController> controller = mLocked.pointerController.promote();
491 if (controller == NULL) {
492 JNIEnv* env = jniEnv();
493 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800494 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
495 layer = -1;
496 }
Jeff Brown83c09682010-12-23 17:50:18 -0800497
498 controller = new PointerController(layer);
499 mLocked.pointerController = controller;
500
501 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
502 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800503
504 jobject iconObj = env->CallObjectMethod(mCallbacksObj, gCallbacksClassInfo.getPointerIcon);
505 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon") && iconObj) {
506 jfloat iconHotSpotX = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotX);
507 jfloat iconHotSpotY = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotY);
508 jobject iconBitmapObj = env->GetObjectField(iconObj, gPointerIconClassInfo.bitmap);
509 if (iconBitmapObj) {
510 SkBitmap* iconBitmap = GraphicsJNI::getNativeBitmap(env, iconBitmapObj);
511 if (iconBitmap) {
512 controller->setPointerIcon(iconBitmap, iconHotSpotX, iconHotSpotY);
513 }
514 env->DeleteLocalRef(iconBitmapObj);
515 }
516 env->DeleteLocalRef(iconObj);
517 }
Jeff Brown83c09682010-12-23 17:50:18 -0800518 }
519 return controller;
520}
521
Jeff Browne20c9e02010-10-11 14:20:19 -0700522void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
523 int32_t switchValue, uint32_t policyFlags) {
524#if DEBUG_INPUT_DISPATCHER_POLICY
525 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
526 when, switchCode, switchValue, policyFlags);
527#endif
528
529 JNIEnv* env = jniEnv();
530
531 switch (switchCode) {
532 case SW_LID:
533 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
534 when, switchValue == 0);
535 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
536 break;
537 }
538}
539
Jeff Brown9c3cda02010-06-15 01:31:58 -0700540void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
541#if DEBUG_INPUT_DISPATCHER_POLICY
542 LOGD("notifyConfigurationChanged - when=%lld", when);
543#endif
544
545 JNIEnv* env = jniEnv();
546
Jeff Brown57c59372010-09-21 18:22:55 -0700547 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700548 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700549}
550
Jeff Brown519e0242010-09-15 15:18:56 -0700551nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
552 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700553#if DEBUG_INPUT_DISPATCHER_POLICY
554 LOGD("notifyANR");
555#endif
556
557 JNIEnv* env = jniEnv();
558
Jeff Brown519e0242010-09-15 15:18:56 -0700559 jobject tokenObjLocal;
560 if (inputApplicationHandle.get()) {
561 ApplicationToken* token = static_cast<ApplicationToken*>(inputApplicationHandle.get());
562 jweak tokenObjWeak = token->getTokenObj();
563 tokenObjLocal = env->NewLocalRef(tokenObjWeak);
Jeff Brownb88102f2010-09-08 11:49:43 -0700564 } else {
Jeff Brown519e0242010-09-15 15:18:56 -0700565 tokenObjLocal = NULL;
Jeff Brownb88102f2010-09-08 11:49:43 -0700566 }
567
Jeff Brown54a18252010-09-16 14:07:33 -0700568 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
Jeff Brown519e0242010-09-15 15:18:56 -0700569 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
570 gCallbacksClassInfo.notifyANR, tokenObjLocal, inputChannelObjLocal);
571 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
572 newTimeout = 0; // abort dispatch
573 } else {
574 assert(newTimeout >= 0);
575 }
576
577 env->DeleteLocalRef(tokenObjLocal);
578 env->DeleteLocalRef(inputChannelObjLocal);
Jeff Brownb88102f2010-09-08 11:49:43 -0700579 return newTimeout;
580}
581
Jeff Brown9c3cda02010-06-15 01:31:58 -0700582void NativeInputManager::notifyInputChannelBroken(const sp<InputChannel>& inputChannel) {
583#if DEBUG_INPUT_DISPATCHER_POLICY
584 LOGD("notifyInputChannelBroken - inputChannel='%s'", inputChannel->getName().string());
585#endif
586
Jeff Brown7fbdc842010-06-17 20:52:56 -0700587 JNIEnv* env = jniEnv();
588
589 jobject inputChannelObjLocal = getInputChannelObjLocal(env, inputChannel);
590 if (inputChannelObjLocal) {
591 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
592 inputChannelObjLocal);
593 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
594
595 env->DeleteLocalRef(inputChannelObjLocal);
596 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700597}
598
Jeff Brown9c3cda02010-06-15 01:31:58 -0700599nsecs_t NativeInputManager::getKeyRepeatTimeout() {
600 if (! isScreenOn()) {
601 // Disable key repeat when the screen is off.
602 return -1;
603 } else {
604 // TODO use ViewConfiguration.getLongPressTimeout()
605 return milliseconds_to_nanoseconds(500);
606 }
607}
608
Jeff Brownb21fb102010-09-07 10:44:57 -0700609nsecs_t NativeInputManager::getKeyRepeatDelay() {
610 return milliseconds_to_nanoseconds(50);
611}
612
Jeff Brownae9fc032010-08-18 15:51:08 -0700613int32_t NativeInputManager::getMaxEventsPerSecond() {
614 if (mMaxEventsPerSecond < 0) {
615 JNIEnv* env = jniEnv();
616
617 jint result = env->CallIntMethod(mCallbacksObj,
618 gCallbacksClassInfo.getMaxEventsPerSecond);
619 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700620 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700621 }
622
623 mMaxEventsPerSecond = result;
624 }
625 return mMaxEventsPerSecond;
626}
627
Jeff Brown349703e2010-06-22 01:27:15 -0700628void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700629 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700630
Jeff Brownb88102f2010-09-08 11:49:43 -0700631 jsize length = env->GetArrayLength(windowObjArray);
632 for (jsize i = 0; i < length; i++) {
633 jobject inputTargetObj = env->GetObjectArrayElement(windowObjArray, i);
634 if (! inputTargetObj) {
635 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700636 }
637
Jeff Brownb88102f2010-09-08 11:49:43 -0700638 windows.push();
639 InputWindow& window = windows.editTop();
640 bool valid = populateWindow(env, inputTargetObj, window);
641 if (! valid) {
642 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700643 }
644
Jeff Brownb88102f2010-09-08 11:49:43 -0700645 env->DeleteLocalRef(inputTargetObj);
646 }
Jeff Brown349703e2010-06-22 01:27:15 -0700647
Jeff Brownb88102f2010-09-08 11:49:43 -0700648 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700649}
650
651bool NativeInputManager::populateWindow(JNIEnv* env, jobject windowObj,
652 InputWindow& outWindow) {
653 bool valid = false;
654
655 jobject inputChannelObj = env->GetObjectField(windowObj,
656 gInputWindowClassInfo.inputChannel);
657 if (inputChannelObj) {
658 sp<InputChannel> inputChannel =
659 android_view_InputChannel_getInputChannel(env, inputChannelObj);
660 if (inputChannel != NULL) {
Jeff Brown519e0242010-09-15 15:18:56 -0700661 jstring name = jstring(env->GetObjectField(windowObj,
662 gInputWindowClassInfo.name));
Jeff Brown349703e2010-06-22 01:27:15 -0700663 jint layoutParamsFlags = env->GetIntField(windowObj,
664 gInputWindowClassInfo.layoutParamsFlags);
665 jint layoutParamsType = env->GetIntField(windowObj,
666 gInputWindowClassInfo.layoutParamsType);
667 jlong dispatchingTimeoutNanos = env->GetLongField(windowObj,
668 gInputWindowClassInfo.dispatchingTimeoutNanos);
669 jint frameLeft = env->GetIntField(windowObj,
670 gInputWindowClassInfo.frameLeft);
671 jint frameTop = env->GetIntField(windowObj,
672 gInputWindowClassInfo.frameTop);
Jeff Brown85a31762010-09-01 17:01:00 -0700673 jint frameRight = env->GetIntField(windowObj,
674 gInputWindowClassInfo.frameRight);
675 jint frameBottom = env->GetIntField(windowObj,
676 gInputWindowClassInfo.frameBottom);
677 jint visibleFrameLeft = env->GetIntField(windowObj,
678 gInputWindowClassInfo.visibleFrameLeft);
679 jint visibleFrameTop = env->GetIntField(windowObj,
680 gInputWindowClassInfo.visibleFrameTop);
681 jint visibleFrameRight = env->GetIntField(windowObj,
682 gInputWindowClassInfo.visibleFrameRight);
683 jint visibleFrameBottom = env->GetIntField(windowObj,
684 gInputWindowClassInfo.visibleFrameBottom);
Jeff Brown349703e2010-06-22 01:27:15 -0700685 jint touchableAreaLeft = env->GetIntField(windowObj,
686 gInputWindowClassInfo.touchableAreaLeft);
687 jint touchableAreaTop = env->GetIntField(windowObj,
688 gInputWindowClassInfo.touchableAreaTop);
689 jint touchableAreaRight = env->GetIntField(windowObj,
690 gInputWindowClassInfo.touchableAreaRight);
691 jint touchableAreaBottom = env->GetIntField(windowObj,
692 gInputWindowClassInfo.touchableAreaBottom);
693 jboolean visible = env->GetBooleanField(windowObj,
694 gInputWindowClassInfo.visible);
Jeff Brown519e0242010-09-15 15:18:56 -0700695 jboolean canReceiveKeys = env->GetBooleanField(windowObj,
696 gInputWindowClassInfo.canReceiveKeys);
Jeff Brown349703e2010-06-22 01:27:15 -0700697 jboolean hasFocus = env->GetBooleanField(windowObj,
698 gInputWindowClassInfo.hasFocus);
699 jboolean hasWallpaper = env->GetBooleanField(windowObj,
700 gInputWindowClassInfo.hasWallpaper);
701 jboolean paused = env->GetBooleanField(windowObj,
702 gInputWindowClassInfo.paused);
Jeff Brown519e0242010-09-15 15:18:56 -0700703 jint layer = env->GetIntField(windowObj,
704 gInputWindowClassInfo.layer);
Jeff Brown349703e2010-06-22 01:27:15 -0700705 jint ownerPid = env->GetIntField(windowObj,
706 gInputWindowClassInfo.ownerPid);
707 jint ownerUid = env->GetIntField(windowObj,
708 gInputWindowClassInfo.ownerUid);
709
Jeff Brown519e0242010-09-15 15:18:56 -0700710 const char* nameStr = env->GetStringUTFChars(name, NULL);
711
Jeff Brown349703e2010-06-22 01:27:15 -0700712 outWindow.inputChannel = inputChannel;
Jeff Brown519e0242010-09-15 15:18:56 -0700713 outWindow.name.setTo(nameStr);
Jeff Brown349703e2010-06-22 01:27:15 -0700714 outWindow.layoutParamsFlags = layoutParamsFlags;
715 outWindow.layoutParamsType = layoutParamsType;
716 outWindow.dispatchingTimeout = dispatchingTimeoutNanos;
717 outWindow.frameLeft = frameLeft;
718 outWindow.frameTop = frameTop;
Jeff Brown85a31762010-09-01 17:01:00 -0700719 outWindow.frameRight = frameRight;
720 outWindow.frameBottom = frameBottom;
721 outWindow.visibleFrameLeft = visibleFrameLeft;
722 outWindow.visibleFrameTop = visibleFrameTop;
723 outWindow.visibleFrameRight = visibleFrameRight;
724 outWindow.visibleFrameBottom = visibleFrameBottom;
Jeff Brown349703e2010-06-22 01:27:15 -0700725 outWindow.touchableAreaLeft = touchableAreaLeft;
726 outWindow.touchableAreaTop = touchableAreaTop;
727 outWindow.touchableAreaRight = touchableAreaRight;
728 outWindow.touchableAreaBottom = touchableAreaBottom;
729 outWindow.visible = visible;
Jeff Brown519e0242010-09-15 15:18:56 -0700730 outWindow.canReceiveKeys = canReceiveKeys;
Jeff Brown349703e2010-06-22 01:27:15 -0700731 outWindow.hasFocus = hasFocus;
732 outWindow.hasWallpaper = hasWallpaper;
733 outWindow.paused = paused;
Jeff Brown519e0242010-09-15 15:18:56 -0700734 outWindow.layer = layer;
Jeff Brown349703e2010-06-22 01:27:15 -0700735 outWindow.ownerPid = ownerPid;
736 outWindow.ownerUid = ownerUid;
Jeff Brown519e0242010-09-15 15:18:56 -0700737
738 env->ReleaseStringUTFChars(name, nameStr);
Jeff Brown1f245102010-11-18 20:53:46 -0800739 env->DeleteLocalRef(name);
Jeff Brown349703e2010-06-22 01:27:15 -0700740 valid = true;
741 } else {
742 LOGW("Dropping input target because its input channel is not initialized.");
743 }
744
745 env->DeleteLocalRef(inputChannelObj);
746 } else {
747 LOGW("Dropping input target because the input channel object was null.");
748 }
749 return valid;
750}
751
752void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700753 if (applicationObj) {
754 jstring nameObj = jstring(env->GetObjectField(applicationObj,
755 gInputApplicationClassInfo.name));
756 jlong dispatchingTimeoutNanos = env->GetLongField(applicationObj,
757 gInputApplicationClassInfo.dispatchingTimeoutNanos);
758 jobject tokenObj = env->GetObjectField(applicationObj,
759 gInputApplicationClassInfo.token);
760 jweak tokenObjWeak = env->NewWeakGlobalRef(tokenObj);
761 if (! tokenObjWeak) {
762 LOGE("Could not create weak reference for application token.");
763 LOGE_EX(env);
764 env->ExceptionClear();
765 }
766 env->DeleteLocalRef(tokenObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700767
Jeff Brownb88102f2010-09-08 11:49:43 -0700768 String8 name;
769 if (nameObj) {
770 const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
771 name.setTo(nameStr);
772 env->ReleaseStringUTFChars(nameObj, nameStr);
773 env->DeleteLocalRef(nameObj);
774 } else {
775 LOGE("InputApplication.name should not be null.");
776 name.setTo("unknown");
Jeff Brown349703e2010-06-22 01:27:15 -0700777 }
778
Jeff Brownb88102f2010-09-08 11:49:43 -0700779 InputApplication application;
780 application.name = name;
781 application.dispatchingTimeout = dispatchingTimeoutNanos;
782 application.handle = new ApplicationToken(tokenObjWeak);
783 mInputManager->getDispatcher()->setFocusedApplication(& application);
784 } else {
785 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700786 }
787}
788
789void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700790 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700791}
792
Jeff Browne20c9e02010-10-11 14:20:19 -0700793bool NativeInputManager::isScreenOn() {
794 return android_server_PowerManagerService_isScreenOn();
795}
796
797bool NativeInputManager::isScreenBright() {
798 return android_server_PowerManagerService_isScreenBright();
799}
800
Jeff Brown1f245102010-11-18 20:53:46 -0800801void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
802 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700803 // Policy:
804 // - Ignore untrusted events and pass them along.
805 // - Ask the window manager what to do with normal events and trusted injected events.
806 // - For normal events wake and brighten the screen if currently off or dim.
807 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
808 const int32_t WM_ACTION_PASS_TO_USER = 1;
809 const int32_t WM_ACTION_POKE_USER_ACTIVITY = 2;
810 const int32_t WM_ACTION_GO_TO_SLEEP = 4;
Jeff Browne20c9e02010-10-11 14:20:19 -0700811
Jeff Brown1f245102010-11-18 20:53:46 -0800812 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700813 bool isScreenOn = this->isScreenOn();
814 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700815
Jeff Brown3122e442010-10-11 23:32:49 -0700816 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800817 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
818 jint wmActions;
819 if (keyEventObj) {
820 wmActions = env->CallIntMethod(mCallbacksObj,
821 gCallbacksClassInfo.interceptKeyBeforeQueueing,
822 keyEventObj, policyFlags, isScreenOn);
823 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
824 wmActions = 0;
825 }
826 android_view_KeyEvent_recycle(env, keyEventObj);
827 env->DeleteLocalRef(keyEventObj);
828 } else {
829 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700830 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700831 }
832
Jeff Brown1f245102010-11-18 20:53:46 -0800833 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700834 if (!isScreenOn) {
835 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700836 }
837
838 if (!isScreenBright) {
839 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
840 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700841 }
842
843 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
844 android_server_PowerManagerService_goToSleep(when);
845 }
846
847 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
848 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
849 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700850
Jeff Brown3122e442010-10-11 23:32:49 -0700851 if (wmActions & WM_ACTION_PASS_TO_USER) {
852 policyFlags |= POLICY_FLAG_PASS_TO_USER;
853 }
854 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700855 policyFlags |= POLICY_FLAG_PASS_TO_USER;
856 }
857}
858
859void NativeInputManager::interceptGenericBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700860 // Policy:
861 // - Ignore untrusted events and pass them along.
862 // - No special filtering for injected events required at this time.
863 // - Filter normal events based on screen state.
864 // - For normal events brighten (but do not wake) the screen if currently dim.
865 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
866 if (isScreenOn()) {
867 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700868
Jeff Brown3122e442010-10-11 23:32:49 -0700869 if (!isScreenBright()) {
870 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
871 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700872 }
Jeff Brown3122e442010-10-11 23:32:49 -0700873 } else {
874 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700875 }
876}
877
878bool NativeInputManager::interceptKeyBeforeDispatching(const sp<InputChannel>& inputChannel,
879 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700880 // Policy:
881 // - Ignore untrusted events and pass them along.
882 // - Filter normal events and trusted injected events through the window manager policy to
883 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800884 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700885 if (policyFlags & POLICY_FLAG_TRUSTED) {
886 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700887
Jeff Brown3122e442010-10-11 23:32:49 -0700888 // Note: inputChannel may be null.
889 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
Jeff Brown1f245102010-11-18 20:53:46 -0800890 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
891 if (keyEventObj) {
892 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
893 gCallbacksClassInfo.interceptKeyBeforeDispatching,
894 inputChannelObj, keyEventObj, policyFlags);
895 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
896 android_view_KeyEvent_recycle(env, keyEventObj);
897 env->DeleteLocalRef(keyEventObj);
898 result = consumed && !error;
899 } else {
900 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800901 }
Jeff Brown3122e442010-10-11 23:32:49 -0700902 env->DeleteLocalRef(inputChannelObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700903 }
Jeff Brown1f245102010-11-18 20:53:46 -0800904 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700905}
906
Jeff Brown3915bb82010-11-05 15:02:16 -0700907bool NativeInputManager::dispatchUnhandledKey(const sp<InputChannel>& inputChannel,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800908 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700909 // Policy:
910 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800911 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700912 if (policyFlags & POLICY_FLAG_TRUSTED) {
913 JNIEnv* env = jniEnv();
914
915 // Note: inputChannel may be null.
916 jobject inputChannelObj = getInputChannelObjLocal(env, inputChannel);
Jeff Brown1f245102010-11-18 20:53:46 -0800917 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
918 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800919 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800920 gCallbacksClassInfo.dispatchUnhandledKey,
921 inputChannelObj, keyEventObj, policyFlags);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800922 checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey");
Jeff Brown1f245102010-11-18 20:53:46 -0800923 android_view_KeyEvent_recycle(env, keyEventObj);
924 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800925
926 if (fallbackKeyEventObj) {
927 // Note: outFallbackKeyEvent may be the same object as keyEvent.
928 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
929 outFallbackKeyEvent)) {
930 result = true;
931 }
932 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
933 env->DeleteLocalRef(fallbackKeyEventObj);
934 }
Jeff Brown1f245102010-11-18 20:53:46 -0800935 } else {
936 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800937 }
Jeff Brown3915bb82010-11-05 15:02:16 -0700938 env->DeleteLocalRef(inputChannelObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700939 }
Jeff Brown1f245102010-11-18 20:53:46 -0800940 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700941}
942
Jeff Brown01ce2e92010-09-26 22:20:12 -0700943void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
944 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700945}
946
Jeff Brown349703e2010-06-22 01:27:15 -0700947
Jeff Brownb88102f2010-09-08 11:49:43 -0700948bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
949 int32_t injectorPid, int32_t injectorUid) {
950 JNIEnv* env = jniEnv();
951 jboolean result = env->CallBooleanMethod(mCallbacksObj,
952 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
953 checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");
Jeff Brown349703e2010-06-22 01:27:15 -0700954 return result;
955}
956
Jeff Brown83c09682010-12-23 17:50:18 -0800957
Jeff Brown9c3cda02010-06-15 01:31:58 -0700958// ----------------------------------------------------------------------------
959
960static sp<NativeInputManager> gNativeInputManager;
961
Jeff Brown46b9ac02010-04-22 18:58:52 -0700962static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700963 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700964 LOGE("Input manager not initialized.");
965 jniThrowRuntimeException(env, "Input manager not initialized.");
966 return true;
967 }
968 return false;
969}
970
971static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
972 jobject callbacks) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700973 if (gNativeInputManager == NULL) {
974 gNativeInputManager = new NativeInputManager(callbacks);
975 } else {
976 LOGE("Input manager already initialized.");
977 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700978 }
979}
980
981static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
982 if (checkInputManagerUnitialized(env)) {
983 return;
984 }
985
Jeff Brown9c3cda02010-06-15 01:31:58 -0700986 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700987 if (result) {
988 jniThrowRuntimeException(env, "Input manager could not be started.");
989 }
990}
991
992static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
993 jint displayId, jint width, jint height) {
994 if (checkInputManagerUnitialized(env)) {
995 return;
996 }
997
998 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
999 // to be passed in like this, not sure which is better but leaving it like this
1000 // keeps the window manager in direct control of when display transitions propagate down
1001 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -07001002 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001003}
1004
1005static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
1006 jint displayId, jint orientation) {
1007 if (checkInputManagerUnitialized(env)) {
1008 return;
1009 }
1010
Jeff Brown9c3cda02010-06-15 01:31:58 -07001011 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001012}
1013
1014static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001015 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001016 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001017 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001018 }
1019
Jeff Brownb88102f2010-09-08 11:49:43 -07001020 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001021 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001022}
1023
1024static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001025 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001026 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001027 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001028 }
1029
Jeff Brownb88102f2010-09-08 11:49:43 -07001030 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001031 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001032}
1033
1034static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001035 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001036 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001037 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001038 }
1039
Jeff Brownb88102f2010-09-08 11:49:43 -07001040 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001041 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001042}
1043
1044static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001045 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001046 if (checkInputManagerUnitialized(env)) {
1047 return JNI_FALSE;
1048 }
1049
1050 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1051 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1052 jsize numCodes = env->GetArrayLength(keyCodes);
1053 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001054 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001055 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001056 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001057 } else {
1058 result = JNI_FALSE;
1059 }
1060
1061 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1062 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1063 return result;
1064}
1065
1066static void throwInputChannelNotInitialized(JNIEnv* env) {
1067 jniThrowException(env, "java/lang/IllegalStateException",
1068 "inputChannel is not initialized");
1069}
1070
1071static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1072 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1073 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1074 "the input manager!", inputChannel->getName().string());
1075
Jeff Brown9c3cda02010-06-15 01:31:58 -07001076 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001077 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001078 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001079}
1080
1081static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Browna41ca772010-08-11 14:46:32 -07001082 jobject inputChannelObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001083 if (checkInputManagerUnitialized(env)) {
1084 return;
1085 }
1086
1087 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1088 inputChannelObj);
1089 if (inputChannel == NULL) {
1090 throwInputChannelNotInitialized(env);
1091 return;
1092 }
1093
Jeff Brown7fbdc842010-06-17 20:52:56 -07001094
1095 status_t status = gNativeInputManager->registerInputChannel(
Jeff Browna41ca772010-08-11 14:46:32 -07001096 env, inputChannel, inputChannelObj, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001097 if (status) {
1098 jniThrowRuntimeException(env, "Failed to register input channel. "
1099 "Check logs for details.");
1100 return;
1101 }
1102
Jeff Browna41ca772010-08-11 14:46:32 -07001103 if (! monitor) {
1104 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1105 android_server_InputManager_handleInputChannelDisposed, NULL);
1106 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001107}
1108
1109static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1110 jobject inputChannelObj) {
1111 if (checkInputManagerUnitialized(env)) {
1112 return;
1113 }
1114
1115 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1116 inputChannelObj);
1117 if (inputChannel == NULL) {
1118 throwInputChannelNotInitialized(env);
1119 return;
1120 }
1121
1122 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1123
Jeff Brown7fbdc842010-06-17 20:52:56 -07001124 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001125 if (status) {
1126 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1127 "Check logs for details.");
1128 }
1129}
1130
Jeff Brown6ec402b2010-07-28 15:48:59 -07001131static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1132 jobject inputEventObj, jint injectorPid, jint injectorUid,
1133 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001134 if (checkInputManagerUnitialized(env)) {
1135 return INPUT_EVENT_INJECTION_FAILED;
1136 }
1137
Jeff Brown6ec402b2010-07-28 15:48:59 -07001138 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1139 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001140 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1141 if (status) {
1142 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1143 return INPUT_EVENT_INJECTION_FAILED;
1144 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001145
Jeff Brownb88102f2010-09-08 11:49:43 -07001146 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1147 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001148 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1149 MotionEvent motionEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001150 status_t status = android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
1151 if (status) {
1152 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1153 return INPUT_EVENT_INJECTION_FAILED;
1154 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001155
Jeff Brownb88102f2010-09-08 11:49:43 -07001156 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1157 & motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001158 } else {
1159 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001160 return INPUT_EVENT_INJECTION_FAILED;
1161 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001162}
1163
Jeff Brown349703e2010-06-22 01:27:15 -07001164static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1165 jobjectArray windowObjArray) {
1166 if (checkInputManagerUnitialized(env)) {
1167 return;
1168 }
1169
1170 gNativeInputManager->setInputWindows(env, windowObjArray);
1171}
1172
1173static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1174 jobject applicationObj) {
1175 if (checkInputManagerUnitialized(env)) {
1176 return;
1177 }
1178
1179 gNativeInputManager->setFocusedApplication(env, applicationObj);
1180}
1181
1182static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1183 jclass clazz, jboolean enabled, jboolean frozen) {
1184 if (checkInputManagerUnitialized(env)) {
1185 return;
1186 }
1187
1188 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1189}
1190
Jeff Brown8d608662010-08-30 03:02:23 -07001191static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1192 jclass clazz, jint deviceId) {
1193 if (checkInputManagerUnitialized(env)) {
1194 return NULL;
1195 }
1196
1197 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001198 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001199 deviceId, & deviceInfo);
1200 if (status) {
1201 return NULL;
1202 }
1203
1204 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1205 if (! deviceObj) {
1206 return NULL;
1207 }
1208
1209 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1210 if (! deviceNameObj) {
1211 return NULL;
1212 }
1213
1214 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1215 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1216 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1217 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1218
1219 const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1220 for (size_t i = 0; i < ranges.size(); i++) {
1221 int rangeType = ranges.keyAt(i);
1222 const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
1223 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
1224 rangeType, range.min, range.max, range.flat, range.fuzz);
1225 if (env->ExceptionCheck()) {
1226 return NULL;
1227 }
1228 }
1229
1230 return deviceObj;
1231}
1232
1233static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1234 jclass clazz) {
1235 if (checkInputManagerUnitialized(env)) {
1236 return NULL;
1237 }
1238
1239 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001240 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001241
1242 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1243 if (! deviceIdsObj) {
1244 return NULL;
1245 }
1246
1247 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1248 return deviceIdsObj;
1249}
1250
Jeff Brown57c59372010-09-21 18:22:55 -07001251static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1252 jclass clazz, jobject configObj) {
1253 if (checkInputManagerUnitialized(env)) {
1254 return;
1255 }
1256
1257 InputConfiguration config;
1258 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1259
1260 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1261 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1262 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1263}
1264
Jeff Browne6504122010-09-27 14:52:15 -07001265static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1266 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1267 if (checkInputManagerUnitialized(env)) {
1268 return false;
1269 }
1270
1271 sp<InputChannel> fromChannel =
1272 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1273 sp<InputChannel> toChannel =
1274 android_view_InputChannel_getInputChannel(env, toChannelObj);
1275
1276 if (fromChannel == NULL || toChannel == NULL) {
1277 return false;
1278 }
1279
1280 return gNativeInputManager->getInputManager()->getDispatcher()->
1281 transferTouchFocus(fromChannel, toChannel);
1282}
1283
Jeff Browne33348b2010-07-15 23:54:05 -07001284static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1285 if (checkInputManagerUnitialized(env)) {
1286 return NULL;
1287 }
1288
Jeff Brownb88102f2010-09-08 11:49:43 -07001289 String8 dump;
1290 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001291 return env->NewStringUTF(dump.string());
1292}
1293
Jeff Brown9c3cda02010-06-15 01:31:58 -07001294// ----------------------------------------------------------------------------
1295
Jeff Brown46b9ac02010-04-22 18:58:52 -07001296static JNINativeMethod gInputManagerMethods[] = {
1297 /* name, signature, funcPtr */
1298 { "nativeInit", "(Lcom/android/server/InputManager$Callbacks;)V",
1299 (void*) android_server_InputManager_nativeInit },
1300 { "nativeStart", "()V",
1301 (void*) android_server_InputManager_nativeStart },
1302 { "nativeSetDisplaySize", "(III)V",
1303 (void*) android_server_InputManager_nativeSetDisplaySize },
1304 { "nativeSetDisplayOrientation", "(II)V",
1305 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1306 { "nativeGetScanCodeState", "(III)I",
1307 (void*) android_server_InputManager_nativeGetScanCodeState },
1308 { "nativeGetKeyCodeState", "(III)I",
1309 (void*) android_server_InputManager_nativeGetKeyCodeState },
1310 { "nativeGetSwitchState", "(III)I",
1311 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001312 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001313 (void*) android_server_InputManager_nativeHasKeys },
Jeff Browna41ca772010-08-11 14:46:32 -07001314 { "nativeRegisterInputChannel", "(Landroid/view/InputChannel;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001315 (void*) android_server_InputManager_nativeRegisterInputChannel },
1316 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001317 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001318 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1319 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown349703e2010-06-22 01:27:15 -07001320 { "nativeSetInputWindows", "([Lcom/android/server/InputWindow;)V",
1321 (void*) android_server_InputManager_nativeSetInputWindows },
1322 { "nativeSetFocusedApplication", "(Lcom/android/server/InputApplication;)V",
1323 (void*) android_server_InputManager_nativeSetFocusedApplication },
1324 { "nativeSetInputDispatchMode", "(ZZ)V",
1325 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown8d608662010-08-30 03:02:23 -07001326 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1327 (void*) android_server_InputManager_nativeGetInputDevice },
1328 { "nativeGetInputDeviceIds", "()[I",
1329 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001330 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1331 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001332 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1333 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001334 { "nativeDump", "()Ljava/lang/String;",
1335 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001336};
1337
1338#define FIND_CLASS(var, className) \
1339 var = env->FindClass(className); \
1340 LOG_FATAL_IF(! var, "Unable to find class " className); \
1341 var = jclass(env->NewGlobalRef(var));
1342
1343#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1344 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1345 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1346
1347#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1348 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1349 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1350
1351int register_android_server_InputManager(JNIEnv* env) {
1352 int res = jniRegisterNativeMethods(env, "com/android/server/InputManager",
1353 gInputManagerMethods, NELEM(gInputManagerMethods));
1354 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1355
Jeff Brown9c3cda02010-06-15 01:31:58 -07001356 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001357
1358 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/InputManager$Callbacks");
1359
Jeff Brown46b9ac02010-04-22 18:58:52 -07001360 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001361 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001362
1363 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1364 "notifyLidSwitchChanged", "(JZ)V");
1365
Jeff Brown7fbdc842010-06-17 20:52:56 -07001366 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
1367 "notifyInputChannelBroken", "(Landroid/view/InputChannel;)V");
1368
Jeff Brown349703e2010-06-22 01:27:15 -07001369 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown519e0242010-09-15 15:18:56 -07001370 "notifyANR", "(Ljava/lang/Object;Landroid/view/InputChannel;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001371
Jeff Brown349703e2010-06-22 01:27:15 -07001372 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001373 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001374
1375 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001376 "interceptKeyBeforeDispatching",
1377 "(Landroid/view/InputChannel;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001378
Jeff Brown3915bb82010-11-05 15:02:16 -07001379 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001380 "dispatchUnhandledKey",
1381 "(Landroid/view/InputChannel;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001382
Jeff Brown349703e2010-06-22 01:27:15 -07001383 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1384 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001385
Jeff Brown46b9ac02010-04-22 18:58:52 -07001386 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1387 "filterTouchEvents", "()Z");
1388
1389 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1390 "filterJumpyTouchEvents", "()Z");
1391
Jeff Brown46b9ac02010-04-22 18:58:52 -07001392 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1393 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1394
Jeff Brownae9fc032010-08-18 15:51:08 -07001395 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1396 "getMaxEventsPerSecond", "()I");
1397
Jeff Brown83c09682010-12-23 17:50:18 -08001398 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, gCallbacksClassInfo.clazz,
1399 "getPointerLayer", "()I");
1400
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001401 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, gCallbacksClassInfo.clazz,
1402 "getPointerIcon", "()Lcom/android/server/InputManager$PointerIcon;");
1403
Jeff Brown349703e2010-06-22 01:27:15 -07001404 // InputWindow
Jeff Brown7fbdc842010-06-17 20:52:56 -07001405
Jeff Brown349703e2010-06-22 01:27:15 -07001406 FIND_CLASS(gInputWindowClassInfo.clazz, "com/android/server/InputWindow");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001407
Jeff Brown349703e2010-06-22 01:27:15 -07001408 GET_FIELD_ID(gInputWindowClassInfo.inputChannel, gInputWindowClassInfo.clazz,
1409 "inputChannel", "Landroid/view/InputChannel;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001410
Jeff Brown519e0242010-09-15 15:18:56 -07001411 GET_FIELD_ID(gInputWindowClassInfo.name, gInputWindowClassInfo.clazz,
1412 "name", "Ljava/lang/String;");
1413
Jeff Brown349703e2010-06-22 01:27:15 -07001414 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsFlags, gInputWindowClassInfo.clazz,
1415 "layoutParamsFlags", "I");
1416
1417 GET_FIELD_ID(gInputWindowClassInfo.layoutParamsType, gInputWindowClassInfo.clazz,
1418 "layoutParamsType", "I");
1419
1420 GET_FIELD_ID(gInputWindowClassInfo.dispatchingTimeoutNanos, gInputWindowClassInfo.clazz,
1421 "dispatchingTimeoutNanos", "J");
1422
1423 GET_FIELD_ID(gInputWindowClassInfo.frameLeft, gInputWindowClassInfo.clazz,
1424 "frameLeft", "I");
1425
1426 GET_FIELD_ID(gInputWindowClassInfo.frameTop, gInputWindowClassInfo.clazz,
1427 "frameTop", "I");
1428
Jeff Brown85a31762010-09-01 17:01:00 -07001429 GET_FIELD_ID(gInputWindowClassInfo.frameRight, gInputWindowClassInfo.clazz,
1430 "frameRight", "I");
1431
1432 GET_FIELD_ID(gInputWindowClassInfo.frameBottom, gInputWindowClassInfo.clazz,
1433 "frameBottom", "I");
1434
1435 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameLeft, gInputWindowClassInfo.clazz,
1436 "visibleFrameLeft", "I");
1437
1438 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameTop, gInputWindowClassInfo.clazz,
1439 "visibleFrameTop", "I");
1440
1441 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameRight, gInputWindowClassInfo.clazz,
1442 "visibleFrameRight", "I");
1443
1444 GET_FIELD_ID(gInputWindowClassInfo.visibleFrameBottom, gInputWindowClassInfo.clazz,
1445 "visibleFrameBottom", "I");
1446
Jeff Brown349703e2010-06-22 01:27:15 -07001447 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaLeft, gInputWindowClassInfo.clazz,
1448 "touchableAreaLeft", "I");
1449
1450 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaTop, gInputWindowClassInfo.clazz,
1451 "touchableAreaTop", "I");
1452
1453 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaRight, gInputWindowClassInfo.clazz,
1454 "touchableAreaRight", "I");
1455
1456 GET_FIELD_ID(gInputWindowClassInfo.touchableAreaBottom, gInputWindowClassInfo.clazz,
1457 "touchableAreaBottom", "I");
1458
1459 GET_FIELD_ID(gInputWindowClassInfo.visible, gInputWindowClassInfo.clazz,
1460 "visible", "Z");
1461
Jeff Brown519e0242010-09-15 15:18:56 -07001462 GET_FIELD_ID(gInputWindowClassInfo.canReceiveKeys, gInputWindowClassInfo.clazz,
1463 "canReceiveKeys", "Z");
1464
Jeff Brown349703e2010-06-22 01:27:15 -07001465 GET_FIELD_ID(gInputWindowClassInfo.hasFocus, gInputWindowClassInfo.clazz,
1466 "hasFocus", "Z");
1467
1468 GET_FIELD_ID(gInputWindowClassInfo.hasWallpaper, gInputWindowClassInfo.clazz,
1469 "hasWallpaper", "Z");
1470
1471 GET_FIELD_ID(gInputWindowClassInfo.paused, gInputWindowClassInfo.clazz,
1472 "paused", "Z");
1473
Jeff Brown519e0242010-09-15 15:18:56 -07001474 GET_FIELD_ID(gInputWindowClassInfo.layer, gInputWindowClassInfo.clazz,
1475 "layer", "I");
1476
Jeff Brown349703e2010-06-22 01:27:15 -07001477 GET_FIELD_ID(gInputWindowClassInfo.ownerPid, gInputWindowClassInfo.clazz,
1478 "ownerPid", "I");
1479
1480 GET_FIELD_ID(gInputWindowClassInfo.ownerUid, gInputWindowClassInfo.clazz,
1481 "ownerUid", "I");
1482
1483 // InputApplication
1484
1485 FIND_CLASS(gInputApplicationClassInfo.clazz, "com/android/server/InputApplication");
1486
1487 GET_FIELD_ID(gInputApplicationClassInfo.name, gInputApplicationClassInfo.clazz,
1488 "name", "Ljava/lang/String;");
1489
1490 GET_FIELD_ID(gInputApplicationClassInfo.dispatchingTimeoutNanos,
1491 gInputApplicationClassInfo.clazz,
1492 "dispatchingTimeoutNanos", "J");
1493
1494 GET_FIELD_ID(gInputApplicationClassInfo.token, gInputApplicationClassInfo.clazz,
1495 "token", "Ljava/lang/Object;");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001496
Jeff Brown6ec402b2010-07-28 15:48:59 -07001497 // KeyEvent
1498
1499 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1500
Jeff Brown8d608662010-08-30 03:02:23 -07001501 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001502
1503 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1504
Jeff Brown8d608662010-08-30 03:02:23 -07001505 // InputDevice
1506
1507 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1508
1509 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1510 "<init>", "()V");
1511
1512 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
1513 "addMotionRange", "(IFFFF)V");
1514
1515 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1516 "mId", "I");
1517
1518 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1519 "mName", "Ljava/lang/String;");
1520
1521 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1522 "mSources", "I");
1523
1524 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1525 "mKeyboardType", "I");
1526
1527 GET_FIELD_ID(gInputDeviceClassInfo.mMotionRanges, gInputDeviceClassInfo.clazz,
1528 "mMotionRanges", "[Landroid/view/InputDevice$MotionRange;");
1529
Jeff Brown57c59372010-09-21 18:22:55 -07001530 // Configuration
1531
1532 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1533
1534 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1535 "touchscreen", "I");
1536
1537 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1538 "keyboard", "I");
1539
1540 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1541 "navigation", "I");
1542
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001543 // PointerIcon
1544
1545 FIND_CLASS(gPointerIconClassInfo.clazz, "com/android/server/InputManager$PointerIcon");
1546
1547 GET_FIELD_ID(gPointerIconClassInfo.bitmap, gPointerIconClassInfo.clazz,
1548 "bitmap", "Landroid/graphics/Bitmap;");
1549
1550 GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, gPointerIconClassInfo.clazz,
1551 "hotSpotX", "F");
1552
1553 GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, gPointerIconClassInfo.clazz,
1554 "hotSpotY", "F");
1555
Jeff Brown46b9ac02010-04-22 18:58:52 -07001556 return 0;
1557}
1558
Jeff Brown46b9ac02010-04-22 18:58:52 -07001559} /* namespace android */