blob: 00d0af1c0f374f5ac7da2073af3e9e93ab992d51 [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>
Jeff Brown05dc66a2011-03-02 14:41:58 -080034#include <utils/Looper.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070035#include <utils/threads.h>
Jeff Brown83c09682010-12-23 17:50:18 -080036
Jeff Brownb4ff35d2011-01-02 16:37:43 -080037#include <input/InputManager.h>
38#include <input/PointerController.h>
39
Jeff Brown05dc66a2011-03-02 14:41:58 -080040#include <android_os_MessageQueue.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080041#include <android_view_KeyEvent.h>
42#include <android_view_MotionEvent.h>
43#include <android_view_InputChannel.h>
44#include <android/graphics/GraphicsJNI.h>
45
Jeff Brown00fa7bd2010-07-02 15:37:36 -070046#include "com_android_server_PowerManagerService.h"
Jeff Brown928e0542011-01-10 11:17:36 -080047#include "com_android_server_InputApplication.h"
48#include "com_android_server_InputApplicationHandle.h"
49#include "com_android_server_InputWindow.h"
50#include "com_android_server_InputWindowHandle.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070051
52namespace android {
53
Jeff Brown46b9ac02010-04-22 18:58:52 -070054static struct {
55 jclass clazz;
56
Jeff Brown46b9ac02010-04-22 18:58:52 -070057 jmethodID notifyConfigurationChanged;
58 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070059 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070060 jmethodID notifyANR;
Jeff Brown349703e2010-06-22 01:27:15 -070061 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080062 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070063 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070064 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070065 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070066 jmethodID filterTouchEvents;
67 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080068 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac02010-04-22 18:58:52 -070069 jmethodID getExcludedDeviceNames;
Jeff Brownae9fc032010-08-18 15:51:08 -070070 jmethodID getMaxEventsPerSecond;
Jeff Brown83c09682010-12-23 17:50:18 -080071 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080072 jmethodID getPointerIcon;
Jeff Brown46b9ac02010-04-22 18:58:52 -070073} gCallbacksClassInfo;
74
75static struct {
76 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070077} gKeyEventClassInfo;
78
79static struct {
80 jclass clazz;
81} gMotionEventClassInfo;
82
Jeff Brown8d608662010-08-30 03:02:23 -070083static struct {
84 jclass clazz;
85
86 jmethodID ctor;
87 jmethodID addMotionRange;
88
89 jfieldID mId;
90 jfieldID mName;
91 jfieldID mSources;
92 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -070093} gInputDeviceClassInfo;
94
Jeff Brown57c59372010-09-21 18:22:55 -070095static struct {
96 jclass clazz;
97
98 jfieldID touchscreen;
99 jfieldID keyboard;
100 jfieldID navigation;
101} gConfigurationClassInfo;
102
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800103static struct {
104 jclass clazz;
Jeff Brown349703e2010-06-22 01:27:15 -0700105
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800106 jfieldID bitmap;
107 jfieldID hotSpotX;
108 jfieldID hotSpotY;
109} gPointerIconClassInfo;
Jeff Brown83c09682010-12-23 17:50:18 -0800110
Jeff Brown928e0542011-01-10 11:17:36 -0800111
112// --- Global functions ---
113
114static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
115 const sp<InputApplicationHandle>& inputApplicationHandle) {
116 if (inputApplicationHandle == NULL) {
117 return NULL;
118 }
119 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
120 getInputApplicationHandleObjLocalRef(env);
121}
122
123static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
124 const sp<InputWindowHandle>& inputWindowHandle) {
125 if (inputWindowHandle == NULL) {
126 return NULL;
127 }
128 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
129 getInputWindowHandleObjLocalRef(env);
130}
131
132
133// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800134
Jeff Brown9c3cda02010-06-15 01:31:58 -0700135class NativeInputManager : public virtual RefBase,
136 public virtual InputReaderPolicyInterface,
137 public virtual InputDispatcherPolicyInterface {
138protected:
139 virtual ~NativeInputManager();
140
141public:
Jeff Brown05dc66a2011-03-02 14:41:58 -0800142 NativeInputManager(jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700143
144 inline sp<InputManager> getInputManager() const { return mInputManager; }
145
Jeff Brownb88102f2010-09-08 11:49:43 -0700146 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700147
Jeff Brown9c3cda02010-06-15 01:31:58 -0700148 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
149 void setDisplayOrientation(int32_t displayId, int32_t orientation);
150
Jeff Brown7fbdc842010-06-17 20:52:56 -0700151 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800152 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700153 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
154
Jeff Brown349703e2010-06-22 01:27:15 -0700155 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
156 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
157 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800158 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700159
Jeff Brown9c3cda02010-06-15 01:31:58 -0700160 /* --- InputReaderPolicyInterface implementation --- */
161
162 virtual bool getDisplayInfo(int32_t displayId,
163 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700164 virtual bool filterTouchEvents();
165 virtual bool filterJumpyTouchEvents();
Jeff Brownfe508922011-01-18 15:10:10 -0800166 virtual nsecs_t getVirtualKeyQuietTime();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700167 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800168 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700169
170 /* --- InputDispatcherPolicyInterface implementation --- */
171
Jeff Browne20c9e02010-10-11 14:20:19 -0700172 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
173 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700174 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700175 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800176 const sp<InputWindowHandle>& inputWindowHandle);
177 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700178 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700179 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700180 virtual int32_t getMaxEventsPerSecond();
Jeff Brown1f245102010-11-18 20:53:46 -0800181 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800182 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800183 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700184 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800185 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800186 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700187 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700188 virtual bool checkInjectEventsPermissionNonReentrant(
189 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700190
191private:
192 sp<InputManager> mInputManager;
193
194 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800195 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700196
197 // Cached filtering policies.
198 int32_t mFilterTouchEvents;
199 int32_t mFilterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -0800200 nsecs_t mVirtualKeyQuietTime;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700201
Jeff Brownae9fc032010-08-18 15:51:08 -0700202 // Cached throttling policy.
203 int32_t mMaxEventsPerSecond;
204
Jeff Brown83c09682010-12-23 17:50:18 -0800205 Mutex mLock;
206 struct Locked {
207 // Display size information.
208 int32_t displayWidth, displayHeight; // -1 when initialized
209 int32_t displayOrientation;
210
Jeff Brown05dc66a2011-03-02 14:41:58 -0800211 // System UI visibility.
212 int32_t systemUiVisibility;
213
Jeff Brown83c09682010-12-23 17:50:18 -0800214 // Pointer controller singleton, created and destroyed as needed.
215 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800216 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700217
Jeff Brown05dc66a2011-03-02 14:41:58 -0800218 void updateInactivityFadeDelayLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800219 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800220
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700221 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700222 bool isScreenOn();
223 bool isScreenBright();
224
Jeff Brownb88102f2010-09-08 11:49:43 -0700225 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700226
Jeff Brown9c3cda02010-06-15 01:31:58 -0700227 static inline JNIEnv* jniEnv() {
228 return AndroidRuntime::getJNIEnv();
229 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700230};
231
Jeff Brown928e0542011-01-10 11:17:36 -0800232
Jeff Brown9c3cda02010-06-15 01:31:58 -0700233
Jeff Brown05dc66a2011-03-02 14:41:58 -0800234NativeInputManager::NativeInputManager(jobject callbacksObj, const sp<Looper>& looper) :
235 mLooper(looper),
236 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
237 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700238 JNIEnv* env = jniEnv();
239
240 mCallbacksObj = env->NewGlobalRef(callbacksObj);
241
Jeff Brown83c09682010-12-23 17:50:18 -0800242 {
243 AutoMutex _l(mLock);
244 mLocked.displayWidth = -1;
245 mLocked.displayHeight = -1;
246 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800247
248 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800249 }
250
Jeff Brown9c3cda02010-06-15 01:31:58 -0700251 sp<EventHub> eventHub = new EventHub();
252 mInputManager = new InputManager(eventHub, this, this);
253}
254
255NativeInputManager::~NativeInputManager() {
256 JNIEnv* env = jniEnv();
257
258 env->DeleteGlobalRef(mCallbacksObj);
259}
260
Jeff Brownb88102f2010-09-08 11:49:43 -0700261void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700262 mInputManager->getReader()->dump(dump);
263 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700264
Jeff Brownb88102f2010-09-08 11:49:43 -0700265 mInputManager->getDispatcher()->dump(dump);
266 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700267}
268
Jeff Brown7fbdc842010-06-17 20:52:56 -0700269bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700270 if (env->ExceptionCheck()) {
271 LOGE("An exception was thrown by callback '%s'.", methodName);
272 LOGE_EX(env);
273 env->ExceptionClear();
274 return true;
275 }
276 return false;
277}
278
279void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
280 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800281 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700282
Jeff Brown83c09682010-12-23 17:50:18 -0800283 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
284 mLocked.displayWidth = width;
285 mLocked.displayHeight = height;
286
287 sp<PointerController> controller = mLocked.pointerController.promote();
288 if (controller != NULL) {
289 controller->setDisplaySize(width, height);
290 }
291 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700292 }
293}
294
295void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
296 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800297 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700298
Jeff Brown83c09682010-12-23 17:50:18 -0800299 if (mLocked.displayOrientation != orientation) {
300 mLocked.displayOrientation = orientation;
301
302 sp<PointerController> controller = mLocked.pointerController.promote();
303 if (controller != NULL) {
304 controller->setDisplayOrientation(orientation);
305 }
306 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700307 }
308}
309
Jeff Brown7fbdc842010-06-17 20:52:56 -0700310status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800311 const sp<InputChannel>& inputChannel,
312 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
313 return mInputManager->getDispatcher()->registerInputChannel(
314 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700315}
316
317status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
318 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700319 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700320}
321
Jeff Brown9c3cda02010-06-15 01:31:58 -0700322bool NativeInputManager::getDisplayInfo(int32_t displayId,
323 int32_t* width, int32_t* height, int32_t* orientation) {
324 bool result = false;
325 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800326 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700327
Jeff Brown83c09682010-12-23 17:50:18 -0800328 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700329 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800330 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700331 }
332 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800333 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700334 }
335 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800336 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700337 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700338 result = true;
339 }
340 }
341 return result;
342}
343
Jeff Brown9c3cda02010-06-15 01:31:58 -0700344bool NativeInputManager::filterTouchEvents() {
345 if (mFilterTouchEvents < 0) {
346 JNIEnv* env = jniEnv();
347
348 jboolean result = env->CallBooleanMethod(mCallbacksObj,
349 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700350 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700351 result = false;
352 }
353
354 mFilterTouchEvents = result ? 1 : 0;
355 }
356 return mFilterTouchEvents;
357}
358
359bool NativeInputManager::filterJumpyTouchEvents() {
360 if (mFilterJumpyTouchEvents < 0) {
361 JNIEnv* env = jniEnv();
362
363 jboolean result = env->CallBooleanMethod(mCallbacksObj,
364 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700365 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700366 result = false;
367 }
368
369 mFilterJumpyTouchEvents = result ? 1 : 0;
370 }
371 return mFilterJumpyTouchEvents;
372}
373
Jeff Brownfe508922011-01-18 15:10:10 -0800374nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
375 if (mVirtualKeyQuietTime < 0) {
376 JNIEnv* env = jniEnv();
377
378 jint result = env->CallIntMethod(mCallbacksObj,
379 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
380 if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
381 result = 0;
382 }
383 if (result < 0) {
384 result = 0;
385 }
386
387 mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
388 }
389 return mVirtualKeyQuietTime;
390}
391
Jeff Brown9c3cda02010-06-15 01:31:58 -0700392void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700393 outExcludedDeviceNames.clear();
394
Jeff Brown9c3cda02010-06-15 01:31:58 -0700395 JNIEnv* env = jniEnv();
396
397 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
398 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700399 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700400 jsize length = env->GetArrayLength(result);
401 for (jsize i = 0; i < length; i++) {
402 jstring item = jstring(env->GetObjectArrayElement(result, i));
403
404 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
405 outExcludedDeviceNames.add(String8(deviceNameChars));
406 env->ReleaseStringUTFChars(item, deviceNameChars);
407
408 env->DeleteLocalRef(item);
409 }
410 env->DeleteLocalRef(result);
411 }
412}
413
Jeff Brown83c09682010-12-23 17:50:18 -0800414sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
415 AutoMutex _l(mLock);
416
417 sp<PointerController> controller = mLocked.pointerController.promote();
418 if (controller == NULL) {
419 JNIEnv* env = jniEnv();
420 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800421 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
422 layer = -1;
423 }
Jeff Brown83c09682010-12-23 17:50:18 -0800424
Jeff Brown05dc66a2011-03-02 14:41:58 -0800425 controller = new PointerController(mLooper, layer);
Jeff Brown83c09682010-12-23 17:50:18 -0800426 mLocked.pointerController = controller;
427
428 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
429 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800430
431 jobject iconObj = env->CallObjectMethod(mCallbacksObj, gCallbacksClassInfo.getPointerIcon);
432 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon") && iconObj) {
433 jfloat iconHotSpotX = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotX);
434 jfloat iconHotSpotY = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotY);
435 jobject iconBitmapObj = env->GetObjectField(iconObj, gPointerIconClassInfo.bitmap);
436 if (iconBitmapObj) {
437 SkBitmap* iconBitmap = GraphicsJNI::getNativeBitmap(env, iconBitmapObj);
438 if (iconBitmap) {
439 controller->setPointerIcon(iconBitmap, iconHotSpotX, iconHotSpotY);
440 }
441 env->DeleteLocalRef(iconBitmapObj);
442 }
443 env->DeleteLocalRef(iconObj);
444 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800445
446 updateInactivityFadeDelayLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800447 }
448 return controller;
449}
450
Jeff Browne20c9e02010-10-11 14:20:19 -0700451void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
452 int32_t switchValue, uint32_t policyFlags) {
453#if DEBUG_INPUT_DISPATCHER_POLICY
454 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
455 when, switchCode, switchValue, policyFlags);
456#endif
457
458 JNIEnv* env = jniEnv();
459
460 switch (switchCode) {
461 case SW_LID:
462 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
463 when, switchValue == 0);
464 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
465 break;
466 }
467}
468
Jeff Brown9c3cda02010-06-15 01:31:58 -0700469void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
470#if DEBUG_INPUT_DISPATCHER_POLICY
471 LOGD("notifyConfigurationChanged - when=%lld", when);
472#endif
473
474 JNIEnv* env = jniEnv();
475
Jeff Brown57c59372010-09-21 18:22:55 -0700476 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700477 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700478}
479
Jeff Brown519e0242010-09-15 15:18:56 -0700480nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800481 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700482#if DEBUG_INPUT_DISPATCHER_POLICY
483 LOGD("notifyANR");
484#endif
485
486 JNIEnv* env = jniEnv();
487
Jeff Brown928e0542011-01-10 11:17:36 -0800488 jobject inputApplicationHandleObj =
489 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
490 jobject inputWindowHandleObj =
491 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700492
Jeff Brown519e0242010-09-15 15:18:56 -0700493 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800494 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700495 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
496 newTimeout = 0; // abort dispatch
497 } else {
498 assert(newTimeout >= 0);
499 }
500
Jeff Brown928e0542011-01-10 11:17:36 -0800501 env->DeleteLocalRef(inputWindowHandleObj);
502 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700503 return newTimeout;
504}
505
Jeff Brown928e0542011-01-10 11:17:36 -0800506void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700507#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800508 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700509#endif
510
Jeff Brown7fbdc842010-06-17 20:52:56 -0700511 JNIEnv* env = jniEnv();
512
Jeff Brown928e0542011-01-10 11:17:36 -0800513 jobject inputWindowHandleObj =
514 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
515 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700516 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800517 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700518 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
519
Jeff Brown928e0542011-01-10 11:17:36 -0800520 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700521 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700522}
523
Jeff Brown9c3cda02010-06-15 01:31:58 -0700524nsecs_t NativeInputManager::getKeyRepeatTimeout() {
525 if (! isScreenOn()) {
526 // Disable key repeat when the screen is off.
527 return -1;
528 } else {
529 // TODO use ViewConfiguration.getLongPressTimeout()
530 return milliseconds_to_nanoseconds(500);
531 }
532}
533
Jeff Brownb21fb102010-09-07 10:44:57 -0700534nsecs_t NativeInputManager::getKeyRepeatDelay() {
535 return milliseconds_to_nanoseconds(50);
536}
537
Jeff Brownae9fc032010-08-18 15:51:08 -0700538int32_t NativeInputManager::getMaxEventsPerSecond() {
539 if (mMaxEventsPerSecond < 0) {
540 JNIEnv* env = jniEnv();
541
542 jint result = env->CallIntMethod(mCallbacksObj,
543 gCallbacksClassInfo.getMaxEventsPerSecond);
544 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700545 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700546 }
547
548 mMaxEventsPerSecond = result;
549 }
550 return mMaxEventsPerSecond;
551}
552
Jeff Brown349703e2010-06-22 01:27:15 -0700553void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700554 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700555
Jeff Brownb88102f2010-09-08 11:49:43 -0700556 jsize length = env->GetArrayLength(windowObjArray);
557 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800558 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
559 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700560 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700561 }
562
Jeff Brownb88102f2010-09-08 11:49:43 -0700563 windows.push();
564 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800565 android_server_InputWindow_toNative(env, windowObj, &window);
566 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700567 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700568 }
Jeff Brown928e0542011-01-10 11:17:36 -0800569 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700570 }
Jeff Brown349703e2010-06-22 01:27:15 -0700571
Jeff Brownb88102f2010-09-08 11:49:43 -0700572 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700573}
574
Jeff Brown349703e2010-06-22 01:27:15 -0700575void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700576 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700577 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800578 android_server_InputApplication_toNative(env, applicationObj, &application);
579 if (application.inputApplicationHandle != NULL) {
580 mInputManager->getDispatcher()->setFocusedApplication(&application);
581 }
Jeff Brown349703e2010-06-22 01:27:15 -0700582 }
Jeff Brown928e0542011-01-10 11:17:36 -0800583 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700584}
585
586void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700587 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700588}
589
Jeff Brown05dc66a2011-03-02 14:41:58 -0800590void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
591 AutoMutex _l(mLock);
592
593 if (mLocked.systemUiVisibility != visibility) {
594 mLocked.systemUiVisibility = visibility;
595
596 sp<PointerController> controller = mLocked.pointerController.promote();
597 if (controller != NULL) {
598 updateInactivityFadeDelayLocked(controller);
599 }
600 }
601}
602
603void NativeInputManager::updateInactivityFadeDelayLocked(const sp<PointerController>& controller) {
604 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
605 controller->setInactivityFadeDelay(lightsOut
606 ? PointerController::INACTIVITY_FADE_DELAY_SHORT
607 : PointerController::INACTIVITY_FADE_DELAY_NORMAL);
608}
609
Jeff Browne20c9e02010-10-11 14:20:19 -0700610bool NativeInputManager::isScreenOn() {
611 return android_server_PowerManagerService_isScreenOn();
612}
613
614bool NativeInputManager::isScreenBright() {
615 return android_server_PowerManagerService_isScreenBright();
616}
617
Jeff Brown1f245102010-11-18 20:53:46 -0800618void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
619 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700620 // Policy:
621 // - Ignore untrusted events and pass them along.
622 // - Ask the window manager what to do with normal events and trusted injected events.
623 // - For normal events wake and brighten the screen if currently off or dim.
624 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800625 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700626 bool isScreenOn = this->isScreenOn();
627 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700628
Jeff Brown3122e442010-10-11 23:32:49 -0700629 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800630 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
631 jint wmActions;
632 if (keyEventObj) {
633 wmActions = env->CallIntMethod(mCallbacksObj,
634 gCallbacksClassInfo.interceptKeyBeforeQueueing,
635 keyEventObj, policyFlags, isScreenOn);
636 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
637 wmActions = 0;
638 }
639 android_view_KeyEvent_recycle(env, keyEventObj);
640 env->DeleteLocalRef(keyEventObj);
641 } else {
642 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700643 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700644 }
645
Jeff Brown1f245102010-11-18 20:53:46 -0800646 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700647 if (!isScreenOn) {
648 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700649 }
650
651 if (!isScreenBright) {
652 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
653 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700654 }
655
Jeff Brown56194eb2011-03-02 19:23:13 -0800656 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700657 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700658 policyFlags |= POLICY_FLAG_PASS_TO_USER;
659 }
660}
661
Jeff Brown56194eb2011-03-02 19:23:13 -0800662void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700663 // Policy:
664 // - Ignore untrusted events and pass them along.
665 // - No special filtering for injected events required at this time.
666 // - Filter normal events based on screen state.
667 // - For normal events brighten (but do not wake) the screen if currently dim.
668 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
669 if (isScreenOn()) {
670 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700671
Jeff Brown3122e442010-10-11 23:32:49 -0700672 if (!isScreenBright()) {
673 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
674 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800675 } else {
676 JNIEnv* env = jniEnv();
677 jint wmActions = env->CallIntMethod(mCallbacksObj,
678 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
679 policyFlags);
680 if (checkAndClearExceptionFromCallback(env,
681 "interceptMotionBeforeQueueingWhenScreenOff")) {
682 wmActions = 0;
683 }
684
685 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
686 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700687 }
Jeff Brown3122e442010-10-11 23:32:49 -0700688 } else {
689 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700690 }
691}
692
Jeff Brown56194eb2011-03-02 19:23:13 -0800693void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
694 uint32_t& policyFlags) {
695 enum {
696 WM_ACTION_PASS_TO_USER = 1,
697 WM_ACTION_POKE_USER_ACTIVITY = 2,
698 WM_ACTION_GO_TO_SLEEP = 4,
699 };
700
701 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
702#ifdef DEBUG_INPUT_DISPATCHER_POLICY
703 LOGD("handleInterceptActions: Going to sleep.");
704#endif
705 android_server_PowerManagerService_goToSleep(when);
706 }
707
708 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
709#ifdef DEBUG_INPUT_DISPATCHER_POLICY
710 LOGD("handleInterceptActions: Poking user activity.");
711#endif
712 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
713 }
714
715 if (wmActions & WM_ACTION_PASS_TO_USER) {
716 policyFlags |= POLICY_FLAG_PASS_TO_USER;
717 } else {
718#ifdef DEBUG_INPUT_DISPATCHER_POLICY
719 LOGD("handleInterceptActions: Not passing key to user.");
720#endif
721 }
722}
723
Jeff Brown928e0542011-01-10 11:17:36 -0800724bool NativeInputManager::interceptKeyBeforeDispatching(
725 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700726 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700727 // Policy:
728 // - Ignore untrusted events and pass them along.
729 // - Filter normal events and trusted injected events through the window manager policy to
730 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800731 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700732 if (policyFlags & POLICY_FLAG_TRUSTED) {
733 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700734
Jeff Brown928e0542011-01-10 11:17:36 -0800735 // Note: inputWindowHandle may be null.
736 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800737 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
738 if (keyEventObj) {
739 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
740 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800741 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800742 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
743 android_view_KeyEvent_recycle(env, keyEventObj);
744 env->DeleteLocalRef(keyEventObj);
745 result = consumed && !error;
746 } else {
747 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800748 }
Jeff Brown928e0542011-01-10 11:17:36 -0800749 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700750 }
Jeff Brown1f245102010-11-18 20:53:46 -0800751 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700752}
753
Jeff Brown928e0542011-01-10 11:17:36 -0800754bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800755 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700756 // Policy:
757 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800758 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700759 if (policyFlags & POLICY_FLAG_TRUSTED) {
760 JNIEnv* env = jniEnv();
761
Jeff Brown928e0542011-01-10 11:17:36 -0800762 // Note: inputWindowHandle may be null.
763 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800764 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
765 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800766 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800767 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800768 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800769 checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey");
Jeff Brown1f245102010-11-18 20:53:46 -0800770 android_view_KeyEvent_recycle(env, keyEventObj);
771 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800772
773 if (fallbackKeyEventObj) {
774 // Note: outFallbackKeyEvent may be the same object as keyEvent.
775 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
776 outFallbackKeyEvent)) {
777 result = true;
778 }
779 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
780 env->DeleteLocalRef(fallbackKeyEventObj);
781 }
Jeff Brown1f245102010-11-18 20:53:46 -0800782 } else {
783 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800784 }
Jeff Brown928e0542011-01-10 11:17:36 -0800785 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700786 }
Jeff Brown1f245102010-11-18 20:53:46 -0800787 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700788}
789
Jeff Brown01ce2e92010-09-26 22:20:12 -0700790void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
791 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700792}
793
Jeff Brown349703e2010-06-22 01:27:15 -0700794
Jeff Brownb88102f2010-09-08 11:49:43 -0700795bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
796 int32_t injectorPid, int32_t injectorUid) {
797 JNIEnv* env = jniEnv();
798 jboolean result = env->CallBooleanMethod(mCallbacksObj,
799 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
800 checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");
Jeff Brown349703e2010-06-22 01:27:15 -0700801 return result;
802}
803
Jeff Brown83c09682010-12-23 17:50:18 -0800804
Jeff Brown9c3cda02010-06-15 01:31:58 -0700805// ----------------------------------------------------------------------------
806
807static sp<NativeInputManager> gNativeInputManager;
808
Jeff Brown46b9ac02010-04-22 18:58:52 -0700809static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700810 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700811 LOGE("Input manager not initialized.");
812 jniThrowRuntimeException(env, "Input manager not initialized.");
813 return true;
814 }
815 return false;
816}
817
818static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown05dc66a2011-03-02 14:41:58 -0800819 jobject callbacks, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700820 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800821 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
822 gNativeInputManager = new NativeInputManager(callbacks, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700823 } else {
824 LOGE("Input manager already initialized.");
825 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700826 }
827}
828
829static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
830 if (checkInputManagerUnitialized(env)) {
831 return;
832 }
833
Jeff Brown9c3cda02010-06-15 01:31:58 -0700834 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700835 if (result) {
836 jniThrowRuntimeException(env, "Input manager could not be started.");
837 }
838}
839
840static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
841 jint displayId, jint width, jint height) {
842 if (checkInputManagerUnitialized(env)) {
843 return;
844 }
845
846 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
847 // to be passed in like this, not sure which is better but leaving it like this
848 // keeps the window manager in direct control of when display transitions propagate down
849 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700850 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700851}
852
853static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
854 jint displayId, jint orientation) {
855 if (checkInputManagerUnitialized(env)) {
856 return;
857 }
858
Jeff Brown9c3cda02010-06-15 01:31:58 -0700859 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700860}
861
862static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700863 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700864 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700865 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700866 }
867
Jeff Brownb88102f2010-09-08 11:49:43 -0700868 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700869 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700870}
871
872static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700873 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700874 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700875 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700876 }
877
Jeff Brownb88102f2010-09-08 11:49:43 -0700878 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700879 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700880}
881
882static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700883 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700884 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700885 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700886 }
887
Jeff Brownb88102f2010-09-08 11:49:43 -0700888 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700889 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700890}
891
892static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700893 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700894 if (checkInputManagerUnitialized(env)) {
895 return JNI_FALSE;
896 }
897
898 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
899 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
900 jsize numCodes = env->GetArrayLength(keyCodes);
901 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700902 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700903 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700904 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700905 } else {
906 result = JNI_FALSE;
907 }
908
909 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
910 env->ReleaseIntArrayElements(keyCodes, codes, 0);
911 return result;
912}
913
914static void throwInputChannelNotInitialized(JNIEnv* env) {
915 jniThrowException(env, "java/lang/IllegalStateException",
916 "inputChannel is not initialized");
917}
918
919static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
920 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
921 LOGW("Input channel object '%s' was disposed without first being unregistered with "
922 "the input manager!", inputChannel->getName().string());
923
Jeff Brown9c3cda02010-06-15 01:31:58 -0700924 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700925 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700926 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700927}
928
929static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -0800930 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700931 if (checkInputManagerUnitialized(env)) {
932 return;
933 }
934
935 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
936 inputChannelObj);
937 if (inputChannel == NULL) {
938 throwInputChannelNotInitialized(env);
939 return;
940 }
941
Jeff Brown928e0542011-01-10 11:17:36 -0800942 sp<InputWindowHandle> inputWindowHandle =
943 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700944
945 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -0800946 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700947 if (status) {
948 jniThrowRuntimeException(env, "Failed to register input channel. "
949 "Check logs for details.");
950 return;
951 }
952
Jeff Browna41ca772010-08-11 14:46:32 -0700953 if (! monitor) {
954 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
955 android_server_InputManager_handleInputChannelDisposed, NULL);
956 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700957}
958
959static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
960 jobject inputChannelObj) {
961 if (checkInputManagerUnitialized(env)) {
962 return;
963 }
964
965 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
966 inputChannelObj);
967 if (inputChannel == NULL) {
968 throwInputChannelNotInitialized(env);
969 return;
970 }
971
972 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
973
Jeff Brown7fbdc842010-06-17 20:52:56 -0700974 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700975 if (status) {
976 jniThrowRuntimeException(env, "Failed to unregister input channel. "
977 "Check logs for details.");
978 }
979}
980
Jeff Brown6ec402b2010-07-28 15:48:59 -0700981static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
982 jobject inputEventObj, jint injectorPid, jint injectorUid,
983 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700984 if (checkInputManagerUnitialized(env)) {
985 return INPUT_EVENT_INJECTION_FAILED;
986 }
987
Jeff Brown6ec402b2010-07-28 15:48:59 -0700988 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
989 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -0800990 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
991 if (status) {
992 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
993 return INPUT_EVENT_INJECTION_FAILED;
994 }
Jeff Brown7fbdc842010-06-17 20:52:56 -0700995
Jeff Brownb88102f2010-09-08 11:49:43 -0700996 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
997 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -0700998 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
999 MotionEvent motionEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001000 status_t status = android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
1001 if (status) {
1002 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1003 return INPUT_EVENT_INJECTION_FAILED;
1004 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001005
Jeff Brownb88102f2010-09-08 11:49:43 -07001006 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1007 & motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001008 } else {
1009 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001010 return INPUT_EVENT_INJECTION_FAILED;
1011 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001012}
1013
Jeff Brown349703e2010-06-22 01:27:15 -07001014static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1015 jobjectArray windowObjArray) {
1016 if (checkInputManagerUnitialized(env)) {
1017 return;
1018 }
1019
1020 gNativeInputManager->setInputWindows(env, windowObjArray);
1021}
1022
1023static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1024 jobject applicationObj) {
1025 if (checkInputManagerUnitialized(env)) {
1026 return;
1027 }
1028
1029 gNativeInputManager->setFocusedApplication(env, applicationObj);
1030}
1031
1032static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1033 jclass clazz, jboolean enabled, jboolean frozen) {
1034 if (checkInputManagerUnitialized(env)) {
1035 return;
1036 }
1037
1038 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1039}
1040
Jeff Brown05dc66a2011-03-02 14:41:58 -08001041static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1042 jclass clazz, jint visibility) {
1043 if (checkInputManagerUnitialized(env)) {
1044 return;
1045 }
1046
1047 gNativeInputManager->setSystemUiVisibility(visibility);
1048}
1049
Jeff Brown8d608662010-08-30 03:02:23 -07001050static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1051 jclass clazz, jint deviceId) {
1052 if (checkInputManagerUnitialized(env)) {
1053 return NULL;
1054 }
1055
1056 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001057 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001058 deviceId, & deviceInfo);
1059 if (status) {
1060 return NULL;
1061 }
1062
1063 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1064 if (! deviceObj) {
1065 return NULL;
1066 }
1067
1068 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1069 if (! deviceNameObj) {
1070 return NULL;
1071 }
1072
1073 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1074 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1075 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1076 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1077
1078 const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1079 for (size_t i = 0; i < ranges.size(); i++) {
1080 int rangeType = ranges.keyAt(i);
1081 const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
1082 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
1083 rangeType, range.min, range.max, range.flat, range.fuzz);
1084 if (env->ExceptionCheck()) {
1085 return NULL;
1086 }
1087 }
1088
1089 return deviceObj;
1090}
1091
1092static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1093 jclass clazz) {
1094 if (checkInputManagerUnitialized(env)) {
1095 return NULL;
1096 }
1097
1098 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001099 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001100
1101 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1102 if (! deviceIdsObj) {
1103 return NULL;
1104 }
1105
1106 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1107 return deviceIdsObj;
1108}
1109
Jeff Brown57c59372010-09-21 18:22:55 -07001110static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1111 jclass clazz, jobject configObj) {
1112 if (checkInputManagerUnitialized(env)) {
1113 return;
1114 }
1115
1116 InputConfiguration config;
1117 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1118
1119 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1120 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1121 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1122}
1123
Jeff Browne6504122010-09-27 14:52:15 -07001124static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1125 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1126 if (checkInputManagerUnitialized(env)) {
1127 return false;
1128 }
1129
1130 sp<InputChannel> fromChannel =
1131 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1132 sp<InputChannel> toChannel =
1133 android_view_InputChannel_getInputChannel(env, toChannelObj);
1134
1135 if (fromChannel == NULL || toChannel == NULL) {
1136 return false;
1137 }
1138
1139 return gNativeInputManager->getInputManager()->getDispatcher()->
1140 transferTouchFocus(fromChannel, toChannel);
1141}
1142
Jeff Browne33348b2010-07-15 23:54:05 -07001143static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1144 if (checkInputManagerUnitialized(env)) {
1145 return NULL;
1146 }
1147
Jeff Brownb88102f2010-09-08 11:49:43 -07001148 String8 dump;
1149 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001150 return env->NewStringUTF(dump.string());
1151}
1152
Jeff Brown9c3cda02010-06-15 01:31:58 -07001153// ----------------------------------------------------------------------------
1154
Jeff Brown46b9ac02010-04-22 18:58:52 -07001155static JNINativeMethod gInputManagerMethods[] = {
1156 /* name, signature, funcPtr */
Jeff Brown05dc66a2011-03-02 14:41:58 -08001157 { "nativeInit", "(Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001158 (void*) android_server_InputManager_nativeInit },
1159 { "nativeStart", "()V",
1160 (void*) android_server_InputManager_nativeStart },
1161 { "nativeSetDisplaySize", "(III)V",
1162 (void*) android_server_InputManager_nativeSetDisplaySize },
1163 { "nativeSetDisplayOrientation", "(II)V",
1164 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1165 { "nativeGetScanCodeState", "(III)I",
1166 (void*) android_server_InputManager_nativeGetScanCodeState },
1167 { "nativeGetKeyCodeState", "(III)I",
1168 (void*) android_server_InputManager_nativeGetKeyCodeState },
1169 { "nativeGetSwitchState", "(III)I",
1170 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001171 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001172 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001173 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001174 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001175 (void*) android_server_InputManager_nativeRegisterInputChannel },
1176 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001177 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001178 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1179 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001180 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001181 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001182 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001183 (void*) android_server_InputManager_nativeSetFocusedApplication },
1184 { "nativeSetInputDispatchMode", "(ZZ)V",
1185 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001186 { "nativeSetSystemUiVisibility", "(I)V",
1187 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001188 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1189 (void*) android_server_InputManager_nativeGetInputDevice },
1190 { "nativeGetInputDeviceIds", "()[I",
1191 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001192 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1193 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001194 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1195 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001196 { "nativeDump", "()Ljava/lang/String;",
1197 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001198};
1199
1200#define FIND_CLASS(var, className) \
1201 var = env->FindClass(className); \
1202 LOG_FATAL_IF(! var, "Unable to find class " className); \
1203 var = jclass(env->NewGlobalRef(var));
1204
1205#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1206 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1207 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1208
1209#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1210 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1211 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1212
1213int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001214 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001215 gInputManagerMethods, NELEM(gInputManagerMethods));
1216 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1217
Jeff Brown9c3cda02010-06-15 01:31:58 -07001218 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001219
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001220 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001221
Jeff Brown46b9ac02010-04-22 18:58:52 -07001222 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001223 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001224
1225 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1226 "notifyLidSwitchChanged", "(JZ)V");
1227
Jeff Brown7fbdc842010-06-17 20:52:56 -07001228 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001229 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001230
Jeff Brown349703e2010-06-22 01:27:15 -07001231 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001232 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001233 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001234
Jeff Brown349703e2010-06-22 01:27:15 -07001235 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001236 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001237
Jeff Brown56194eb2011-03-02 19:23:13 -08001238 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
1239 gCallbacksClassInfo.clazz,
1240 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1241
Jeff Brown349703e2010-06-22 01:27:15 -07001242 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001243 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001244 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001245
Jeff Brown3915bb82010-11-05 15:02:16 -07001246 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001247 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001248 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001249
Jeff Brown349703e2010-06-22 01:27:15 -07001250 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1251 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001252
Jeff Brown46b9ac02010-04-22 18:58:52 -07001253 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1254 "filterTouchEvents", "()Z");
1255
1256 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1257 "filterJumpyTouchEvents", "()Z");
1258
Jeff Brownfe508922011-01-18 15:10:10 -08001259 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
1260 "getVirtualKeyQuietTimeMillis", "()I");
1261
Jeff Brown46b9ac02010-04-22 18:58:52 -07001262 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1263 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1264
Jeff Brownae9fc032010-08-18 15:51:08 -07001265 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1266 "getMaxEventsPerSecond", "()I");
1267
Jeff Brown83c09682010-12-23 17:50:18 -08001268 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, gCallbacksClassInfo.clazz,
1269 "getPointerLayer", "()I");
1270
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001271 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, gCallbacksClassInfo.clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001272 "getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001273
Jeff Brown6ec402b2010-07-28 15:48:59 -07001274 // KeyEvent
1275
1276 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1277
Jeff Brown8d608662010-08-30 03:02:23 -07001278 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001279
1280 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1281
Jeff Brown8d608662010-08-30 03:02:23 -07001282 // InputDevice
1283
1284 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1285
1286 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1287 "<init>", "()V");
1288
1289 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
1290 "addMotionRange", "(IFFFF)V");
1291
1292 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1293 "mId", "I");
1294
1295 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1296 "mName", "Ljava/lang/String;");
1297
1298 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1299 "mSources", "I");
1300
1301 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1302 "mKeyboardType", "I");
1303
Jeff Brown57c59372010-09-21 18:22:55 -07001304 // Configuration
1305
1306 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1307
1308 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1309 "touchscreen", "I");
1310
1311 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1312 "keyboard", "I");
1313
1314 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1315 "navigation", "I");
1316
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001317 // PointerIcon
1318
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001319 FIND_CLASS(gPointerIconClassInfo.clazz, "com/android/server/wm/InputManager$PointerIcon");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001320
1321 GET_FIELD_ID(gPointerIconClassInfo.bitmap, gPointerIconClassInfo.clazz,
1322 "bitmap", "Landroid/graphics/Bitmap;");
1323
1324 GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, gPointerIconClassInfo.clazz,
1325 "hotSpotX", "F");
1326
1327 GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, gPointerIconClassInfo.clazz,
1328 "hotSpotY", "F");
1329
Jeff Brown46b9ac02010-04-22 18:58:52 -07001330 return 0;
1331}
1332
Jeff Brown46b9ac02010-04-22 18:58:52 -07001333} /* namespace android */