blob: 96cf4bd451ae050ad1745b68a1ef2bb078307fbc [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 {
Jeff Brown46b9ac02010-04-22 18:58:52 -070055 jmethodID notifyConfigurationChanged;
56 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070057 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070058 jmethodID notifyANR;
Jeff Brown349703e2010-06-22 01:27:15 -070059 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080060 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070061 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070062 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070063 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070064 jmethodID filterTouchEvents;
65 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080066 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac02010-04-22 18:58:52 -070067 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080068 jmethodID getKeyRepeatTimeout;
69 jmethodID getKeyRepeatDelay;
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 {
Jeff Brown57c59372010-09-21 18:22:55 -070096 jfieldID touchscreen;
97 jfieldID keyboard;
98 jfieldID navigation;
99} gConfigurationClassInfo;
100
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800101static struct {
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800102 jfieldID bitmap;
103 jfieldID hotSpotX;
104 jfieldID hotSpotY;
105} gPointerIconClassInfo;
Jeff Brown83c09682010-12-23 17:50:18 -0800106
Jeff Brown928e0542011-01-10 11:17:36 -0800107
108// --- Global functions ---
109
110static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
111 const sp<InputApplicationHandle>& inputApplicationHandle) {
112 if (inputApplicationHandle == NULL) {
113 return NULL;
114 }
115 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
116 getInputApplicationHandleObjLocalRef(env);
117}
118
119static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
120 const sp<InputWindowHandle>& inputWindowHandle) {
121 if (inputWindowHandle == NULL) {
122 return NULL;
123 }
124 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
125 getInputWindowHandleObjLocalRef(env);
126}
127
128
129// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800130
Jeff Brown9c3cda02010-06-15 01:31:58 -0700131class NativeInputManager : public virtual RefBase,
132 public virtual InputReaderPolicyInterface,
133 public virtual InputDispatcherPolicyInterface {
134protected:
135 virtual ~NativeInputManager();
136
137public:
Jeff Brown05dc66a2011-03-02 14:41:58 -0800138 NativeInputManager(jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700139
140 inline sp<InputManager> getInputManager() const { return mInputManager; }
141
Jeff Brownb88102f2010-09-08 11:49:43 -0700142 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700143
Jeff Brown9c3cda02010-06-15 01:31:58 -0700144 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
145 void setDisplayOrientation(int32_t displayId, int32_t orientation);
146
Jeff Brown7fbdc842010-06-17 20:52:56 -0700147 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800148 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700149 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
150
Jeff Brown349703e2010-06-22 01:27:15 -0700151 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
152 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
153 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800154 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700155
Jeff Brown9c3cda02010-06-15 01:31:58 -0700156 /* --- InputReaderPolicyInterface implementation --- */
157
158 virtual bool getDisplayInfo(int32_t displayId,
159 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700160 virtual bool filterTouchEvents();
161 virtual bool filterJumpyTouchEvents();
Jeff Brownfe508922011-01-18 15:10:10 -0800162 virtual nsecs_t getVirtualKeyQuietTime();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700163 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800164 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700165
166 /* --- InputDispatcherPolicyInterface implementation --- */
167
Jeff Browne20c9e02010-10-11 14:20:19 -0700168 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
169 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700170 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700171 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800172 const sp<InputWindowHandle>& inputWindowHandle);
173 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700174 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700175 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700176 virtual int32_t getMaxEventsPerSecond();
Jeff Brown1f245102010-11-18 20:53:46 -0800177 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800178 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800179 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700180 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800181 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800182 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700183 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700184 virtual bool checkInjectEventsPermissionNonReentrant(
185 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700186
187private:
188 sp<InputManager> mInputManager;
189
190 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800191 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700192
193 // Cached filtering policies.
194 int32_t mFilterTouchEvents;
195 int32_t mFilterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -0800196 nsecs_t mVirtualKeyQuietTime;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197
Jeff Browna4547672011-03-02 21:38:11 -0800198 // Cached key repeat policy.
199 nsecs_t mKeyRepeatTimeout;
200 nsecs_t mKeyRepeatDelay;
201
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),
Jeff Browna4547672011-03-02 21:38:11 -0800237 mKeyRepeatTimeout(-1), mKeyRepeatDelay(-1),
Jeff Brown05dc66a2011-03-02 14:41:58 -0800238 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700239 JNIEnv* env = jniEnv();
240
241 mCallbacksObj = env->NewGlobalRef(callbacksObj);
242
Jeff Brown83c09682010-12-23 17:50:18 -0800243 {
244 AutoMutex _l(mLock);
245 mLocked.displayWidth = -1;
246 mLocked.displayHeight = -1;
247 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800248
249 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800250 }
251
Jeff Brown9c3cda02010-06-15 01:31:58 -0700252 sp<EventHub> eventHub = new EventHub();
253 mInputManager = new InputManager(eventHub, this, this);
254}
255
256NativeInputManager::~NativeInputManager() {
257 JNIEnv* env = jniEnv();
258
259 env->DeleteGlobalRef(mCallbacksObj);
260}
261
Jeff Brownb88102f2010-09-08 11:49:43 -0700262void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700263 mInputManager->getReader()->dump(dump);
264 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700265
Jeff Brownb88102f2010-09-08 11:49:43 -0700266 mInputManager->getDispatcher()->dump(dump);
267 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700268}
269
Jeff Brown7fbdc842010-06-17 20:52:56 -0700270bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700271 if (env->ExceptionCheck()) {
272 LOGE("An exception was thrown by callback '%s'.", methodName);
273 LOGE_EX(env);
274 env->ExceptionClear();
275 return true;
276 }
277 return false;
278}
279
280void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
281 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800282 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700283
Jeff Brown83c09682010-12-23 17:50:18 -0800284 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
285 mLocked.displayWidth = width;
286 mLocked.displayHeight = height;
287
288 sp<PointerController> controller = mLocked.pointerController.promote();
289 if (controller != NULL) {
290 controller->setDisplaySize(width, height);
291 }
292 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700293 }
294}
295
296void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
297 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800298 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700299
Jeff Brown83c09682010-12-23 17:50:18 -0800300 if (mLocked.displayOrientation != orientation) {
301 mLocked.displayOrientation = orientation;
302
303 sp<PointerController> controller = mLocked.pointerController.promote();
304 if (controller != NULL) {
305 controller->setDisplayOrientation(orientation);
306 }
307 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700308 }
309}
310
Jeff Brown7fbdc842010-06-17 20:52:56 -0700311status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800312 const sp<InputChannel>& inputChannel,
313 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
314 return mInputManager->getDispatcher()->registerInputChannel(
315 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700316}
317
318status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
319 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700320 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700321}
322
Jeff Brown9c3cda02010-06-15 01:31:58 -0700323bool NativeInputManager::getDisplayInfo(int32_t displayId,
324 int32_t* width, int32_t* height, int32_t* orientation) {
325 bool result = false;
326 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800327 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700328
Jeff Brown83c09682010-12-23 17:50:18 -0800329 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700330 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800331 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700332 }
333 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800334 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700335 }
336 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800337 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700338 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700339 result = true;
340 }
341 }
342 return result;
343}
344
Jeff Brown9c3cda02010-06-15 01:31:58 -0700345bool NativeInputManager::filterTouchEvents() {
346 if (mFilterTouchEvents < 0) {
347 JNIEnv* env = jniEnv();
348
349 jboolean result = env->CallBooleanMethod(mCallbacksObj,
350 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700351 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700352 result = false;
353 }
354
355 mFilterTouchEvents = result ? 1 : 0;
356 }
357 return mFilterTouchEvents;
358}
359
360bool NativeInputManager::filterJumpyTouchEvents() {
361 if (mFilterJumpyTouchEvents < 0) {
362 JNIEnv* env = jniEnv();
363
364 jboolean result = env->CallBooleanMethod(mCallbacksObj,
365 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700366 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700367 result = false;
368 }
369
370 mFilterJumpyTouchEvents = result ? 1 : 0;
371 }
372 return mFilterJumpyTouchEvents;
373}
374
Jeff Brownfe508922011-01-18 15:10:10 -0800375nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
376 if (mVirtualKeyQuietTime < 0) {
377 JNIEnv* env = jniEnv();
378
379 jint result = env->CallIntMethod(mCallbacksObj,
380 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
381 if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
382 result = 0;
383 }
384 if (result < 0) {
385 result = 0;
386 }
387
388 mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
389 }
390 return mVirtualKeyQuietTime;
391}
392
Jeff Brown9c3cda02010-06-15 01:31:58 -0700393void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700394 outExcludedDeviceNames.clear();
395
Jeff Brown9c3cda02010-06-15 01:31:58 -0700396 JNIEnv* env = jniEnv();
397
398 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
399 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700400 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700401 jsize length = env->GetArrayLength(result);
402 for (jsize i = 0; i < length; i++) {
403 jstring item = jstring(env->GetObjectArrayElement(result, i));
404
405 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
406 outExcludedDeviceNames.add(String8(deviceNameChars));
407 env->ReleaseStringUTFChars(item, deviceNameChars);
408
409 env->DeleteLocalRef(item);
410 }
411 env->DeleteLocalRef(result);
412 }
413}
414
Jeff Brown83c09682010-12-23 17:50:18 -0800415sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
416 AutoMutex _l(mLock);
417
418 sp<PointerController> controller = mLocked.pointerController.promote();
419 if (controller == NULL) {
420 JNIEnv* env = jniEnv();
421 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800422 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
423 layer = -1;
424 }
Jeff Brown83c09682010-12-23 17:50:18 -0800425
Jeff Brown05dc66a2011-03-02 14:41:58 -0800426 controller = new PointerController(mLooper, layer);
Jeff Brown83c09682010-12-23 17:50:18 -0800427 mLocked.pointerController = controller;
428
429 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
430 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800431
432 jobject iconObj = env->CallObjectMethod(mCallbacksObj, gCallbacksClassInfo.getPointerIcon);
433 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon") && iconObj) {
434 jfloat iconHotSpotX = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotX);
435 jfloat iconHotSpotY = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotY);
436 jobject iconBitmapObj = env->GetObjectField(iconObj, gPointerIconClassInfo.bitmap);
437 if (iconBitmapObj) {
438 SkBitmap* iconBitmap = GraphicsJNI::getNativeBitmap(env, iconBitmapObj);
439 if (iconBitmap) {
440 controller->setPointerIcon(iconBitmap, iconHotSpotX, iconHotSpotY);
441 }
442 env->DeleteLocalRef(iconBitmapObj);
443 }
444 env->DeleteLocalRef(iconObj);
445 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800446
447 updateInactivityFadeDelayLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800448 }
449 return controller;
450}
451
Jeff Browne20c9e02010-10-11 14:20:19 -0700452void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
453 int32_t switchValue, uint32_t policyFlags) {
454#if DEBUG_INPUT_DISPATCHER_POLICY
455 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
456 when, switchCode, switchValue, policyFlags);
457#endif
458
459 JNIEnv* env = jniEnv();
460
461 switch (switchCode) {
462 case SW_LID:
463 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
464 when, switchValue == 0);
465 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
466 break;
467 }
468}
469
Jeff Brown9c3cda02010-06-15 01:31:58 -0700470void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
471#if DEBUG_INPUT_DISPATCHER_POLICY
472 LOGD("notifyConfigurationChanged - when=%lld", when);
473#endif
474
475 JNIEnv* env = jniEnv();
476
Jeff Brown57c59372010-09-21 18:22:55 -0700477 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700478 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700479}
480
Jeff Brown519e0242010-09-15 15:18:56 -0700481nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800482 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700483#if DEBUG_INPUT_DISPATCHER_POLICY
484 LOGD("notifyANR");
485#endif
486
487 JNIEnv* env = jniEnv();
488
Jeff Brown928e0542011-01-10 11:17:36 -0800489 jobject inputApplicationHandleObj =
490 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
491 jobject inputWindowHandleObj =
492 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700493
Jeff Brown519e0242010-09-15 15:18:56 -0700494 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800495 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700496 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
497 newTimeout = 0; // abort dispatch
498 } else {
499 assert(newTimeout >= 0);
500 }
501
Jeff Brown928e0542011-01-10 11:17:36 -0800502 env->DeleteLocalRef(inputWindowHandleObj);
503 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700504 return newTimeout;
505}
506
Jeff Brown928e0542011-01-10 11:17:36 -0800507void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700508#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800509 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700510#endif
511
Jeff Brown7fbdc842010-06-17 20:52:56 -0700512 JNIEnv* env = jniEnv();
513
Jeff Brown928e0542011-01-10 11:17:36 -0800514 jobject inputWindowHandleObj =
515 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
516 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700517 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800518 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700519 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
520
Jeff Brown928e0542011-01-10 11:17:36 -0800521 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700522 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700523}
524
Jeff Brown9c3cda02010-06-15 01:31:58 -0700525nsecs_t NativeInputManager::getKeyRepeatTimeout() {
526 if (! isScreenOn()) {
527 // Disable key repeat when the screen is off.
528 return -1;
529 } else {
Jeff Browna4547672011-03-02 21:38:11 -0800530 if (mKeyRepeatTimeout < 0) {
531 JNIEnv* env = jniEnv();
532
533 jint result = env->CallIntMethod(mCallbacksObj,
534 gCallbacksClassInfo.getKeyRepeatTimeout);
535 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
536 result = 500;
537 }
538
539 mKeyRepeatTimeout = milliseconds_to_nanoseconds(result);
540 }
541 return mKeyRepeatTimeout;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700542 }
543}
544
Jeff Brownb21fb102010-09-07 10:44:57 -0700545nsecs_t NativeInputManager::getKeyRepeatDelay() {
Jeff Browna4547672011-03-02 21:38:11 -0800546 if (mKeyRepeatDelay < 0) {
547 JNIEnv* env = jniEnv();
548
549 jint result = env->CallIntMethod(mCallbacksObj,
550 gCallbacksClassInfo.getKeyRepeatDelay);
551 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
552 result = 50;
553 }
554
555 mKeyRepeatDelay = milliseconds_to_nanoseconds(result);
556 }
557 return mKeyRepeatDelay;
Jeff Brownb21fb102010-09-07 10:44:57 -0700558}
559
Jeff Brownae9fc032010-08-18 15:51:08 -0700560int32_t NativeInputManager::getMaxEventsPerSecond() {
561 if (mMaxEventsPerSecond < 0) {
562 JNIEnv* env = jniEnv();
563
564 jint result = env->CallIntMethod(mCallbacksObj,
565 gCallbacksClassInfo.getMaxEventsPerSecond);
566 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700567 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700568 }
569
570 mMaxEventsPerSecond = result;
571 }
572 return mMaxEventsPerSecond;
573}
574
Jeff Brown349703e2010-06-22 01:27:15 -0700575void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700576 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700577
Jeff Brownb88102f2010-09-08 11:49:43 -0700578 jsize length = env->GetArrayLength(windowObjArray);
579 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800580 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
581 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700582 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700583 }
584
Jeff Brownb88102f2010-09-08 11:49:43 -0700585 windows.push();
586 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800587 android_server_InputWindow_toNative(env, windowObj, &window);
588 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700589 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700590 }
Jeff Brown928e0542011-01-10 11:17:36 -0800591 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700592 }
Jeff Brown349703e2010-06-22 01:27:15 -0700593
Jeff Brownb88102f2010-09-08 11:49:43 -0700594 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700595}
596
Jeff Brown349703e2010-06-22 01:27:15 -0700597void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700598 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700599 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800600 android_server_InputApplication_toNative(env, applicationObj, &application);
601 if (application.inputApplicationHandle != NULL) {
602 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Browna2cc28d2011-03-25 11:58:46 -0700603 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800604 }
Jeff Brown349703e2010-06-22 01:27:15 -0700605 }
Jeff Brown928e0542011-01-10 11:17:36 -0800606 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700607}
608
609void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700610 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700611}
612
Jeff Brown05dc66a2011-03-02 14:41:58 -0800613void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
614 AutoMutex _l(mLock);
615
616 if (mLocked.systemUiVisibility != visibility) {
617 mLocked.systemUiVisibility = visibility;
618
619 sp<PointerController> controller = mLocked.pointerController.promote();
620 if (controller != NULL) {
621 updateInactivityFadeDelayLocked(controller);
622 }
623 }
624}
625
626void NativeInputManager::updateInactivityFadeDelayLocked(const sp<PointerController>& controller) {
627 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
628 controller->setInactivityFadeDelay(lightsOut
629 ? PointerController::INACTIVITY_FADE_DELAY_SHORT
630 : PointerController::INACTIVITY_FADE_DELAY_NORMAL);
631}
632
Jeff Browne20c9e02010-10-11 14:20:19 -0700633bool NativeInputManager::isScreenOn() {
634 return android_server_PowerManagerService_isScreenOn();
635}
636
637bool NativeInputManager::isScreenBright() {
638 return android_server_PowerManagerService_isScreenBright();
639}
640
Jeff Brown1f245102010-11-18 20:53:46 -0800641void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
642 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700643 // Policy:
644 // - Ignore untrusted events and pass them along.
645 // - Ask the window manager what to do with normal events and trusted injected events.
646 // - For normal events wake and brighten the screen if currently off or dim.
647 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800648 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700649 bool isScreenOn = this->isScreenOn();
650 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700651
Jeff Brown3122e442010-10-11 23:32:49 -0700652 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800653 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
654 jint wmActions;
655 if (keyEventObj) {
656 wmActions = env->CallIntMethod(mCallbacksObj,
657 gCallbacksClassInfo.interceptKeyBeforeQueueing,
658 keyEventObj, policyFlags, isScreenOn);
659 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
660 wmActions = 0;
661 }
662 android_view_KeyEvent_recycle(env, keyEventObj);
663 env->DeleteLocalRef(keyEventObj);
664 } else {
665 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700666 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700667 }
668
Jeff Brown1f245102010-11-18 20:53:46 -0800669 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700670 if (!isScreenOn) {
671 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700672 }
673
674 if (!isScreenBright) {
675 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
676 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700677 }
678
Jeff Brown56194eb2011-03-02 19:23:13 -0800679 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700680 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700681 policyFlags |= POLICY_FLAG_PASS_TO_USER;
682 }
683}
684
Jeff Brown56194eb2011-03-02 19:23:13 -0800685void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700686 // Policy:
687 // - Ignore untrusted events and pass them along.
688 // - No special filtering for injected events required at this time.
689 // - Filter normal events based on screen state.
690 // - For normal events brighten (but do not wake) the screen if currently dim.
691 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
692 if (isScreenOn()) {
693 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700694
Jeff Brown3122e442010-10-11 23:32:49 -0700695 if (!isScreenBright()) {
696 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
697 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800698 } else {
699 JNIEnv* env = jniEnv();
700 jint wmActions = env->CallIntMethod(mCallbacksObj,
701 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
702 policyFlags);
703 if (checkAndClearExceptionFromCallback(env,
704 "interceptMotionBeforeQueueingWhenScreenOff")) {
705 wmActions = 0;
706 }
707
708 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
709 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700710 }
Jeff Brown3122e442010-10-11 23:32:49 -0700711 } else {
712 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700713 }
714}
715
Jeff Brown56194eb2011-03-02 19:23:13 -0800716void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
717 uint32_t& policyFlags) {
718 enum {
719 WM_ACTION_PASS_TO_USER = 1,
720 WM_ACTION_POKE_USER_ACTIVITY = 2,
721 WM_ACTION_GO_TO_SLEEP = 4,
722 };
723
724 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800725#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800726 LOGD("handleInterceptActions: Going to sleep.");
727#endif
728 android_server_PowerManagerService_goToSleep(when);
729 }
730
731 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800732#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800733 LOGD("handleInterceptActions: Poking user activity.");
734#endif
735 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
736 }
737
738 if (wmActions & WM_ACTION_PASS_TO_USER) {
739 policyFlags |= POLICY_FLAG_PASS_TO_USER;
740 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800741#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800742 LOGD("handleInterceptActions: Not passing key to user.");
743#endif
744 }
745}
746
Jeff Brown928e0542011-01-10 11:17:36 -0800747bool NativeInputManager::interceptKeyBeforeDispatching(
748 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700749 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700750 // Policy:
751 // - Ignore untrusted events and pass them along.
752 // - Filter normal events and trusted injected events through the window manager policy to
753 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800754 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700755 if (policyFlags & POLICY_FLAG_TRUSTED) {
756 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700757
Jeff Brown928e0542011-01-10 11:17:36 -0800758 // Note: inputWindowHandle may be null.
759 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800760 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
761 if (keyEventObj) {
762 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
763 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800764 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800765 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
766 android_view_KeyEvent_recycle(env, keyEventObj);
767 env->DeleteLocalRef(keyEventObj);
768 result = consumed && !error;
769 } else {
770 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800771 }
Jeff Brown928e0542011-01-10 11:17:36 -0800772 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700773 }
Jeff Brown1f245102010-11-18 20:53:46 -0800774 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700775}
776
Jeff Brown928e0542011-01-10 11:17:36 -0800777bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800778 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700779 // Policy:
780 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800781 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700782 if (policyFlags & POLICY_FLAG_TRUSTED) {
783 JNIEnv* env = jniEnv();
784
Jeff Brown928e0542011-01-10 11:17:36 -0800785 // Note: inputWindowHandle may be null.
786 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800787 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
788 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800789 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800790 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800791 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700792 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
793 fallbackKeyEventObj = NULL;
794 }
Jeff Brown1f245102010-11-18 20:53:46 -0800795 android_view_KeyEvent_recycle(env, keyEventObj);
796 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800797
798 if (fallbackKeyEventObj) {
799 // Note: outFallbackKeyEvent may be the same object as keyEvent.
800 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
801 outFallbackKeyEvent)) {
802 result = true;
803 }
804 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
805 env->DeleteLocalRef(fallbackKeyEventObj);
806 }
Jeff Brown1f245102010-11-18 20:53:46 -0800807 } else {
808 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800809 }
Jeff Brown928e0542011-01-10 11:17:36 -0800810 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700811 }
Jeff Brown1f245102010-11-18 20:53:46 -0800812 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700813}
814
Jeff Brown01ce2e92010-09-26 22:20:12 -0700815void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
816 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700817}
818
Jeff Brown349703e2010-06-22 01:27:15 -0700819
Jeff Brownb88102f2010-09-08 11:49:43 -0700820bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
821 int32_t injectorPid, int32_t injectorUid) {
822 JNIEnv* env = jniEnv();
823 jboolean result = env->CallBooleanMethod(mCallbacksObj,
824 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700825 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
826 result = false;
827 }
Jeff Brown349703e2010-06-22 01:27:15 -0700828 return result;
829}
830
Jeff Brown83c09682010-12-23 17:50:18 -0800831
Jeff Brown9c3cda02010-06-15 01:31:58 -0700832// ----------------------------------------------------------------------------
833
834static sp<NativeInputManager> gNativeInputManager;
835
Jeff Brown46b9ac02010-04-22 18:58:52 -0700836static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700837 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700838 LOGE("Input manager not initialized.");
839 jniThrowRuntimeException(env, "Input manager not initialized.");
840 return true;
841 }
842 return false;
843}
844
845static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown05dc66a2011-03-02 14:41:58 -0800846 jobject callbacks, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700847 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800848 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
849 gNativeInputManager = new NativeInputManager(callbacks, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700850 } else {
851 LOGE("Input manager already initialized.");
852 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700853 }
854}
855
856static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
857 if (checkInputManagerUnitialized(env)) {
858 return;
859 }
860
Jeff Brown9c3cda02010-06-15 01:31:58 -0700861 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700862 if (result) {
863 jniThrowRuntimeException(env, "Input manager could not be started.");
864 }
865}
866
867static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
868 jint displayId, jint width, jint height) {
869 if (checkInputManagerUnitialized(env)) {
870 return;
871 }
872
873 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
874 // to be passed in like this, not sure which is better but leaving it like this
875 // keeps the window manager in direct control of when display transitions propagate down
876 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700877 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700878}
879
880static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
881 jint displayId, jint orientation) {
882 if (checkInputManagerUnitialized(env)) {
883 return;
884 }
885
Jeff Brown9c3cda02010-06-15 01:31:58 -0700886 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700887}
888
889static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700890 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700891 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700892 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700893 }
894
Jeff Brownb88102f2010-09-08 11:49:43 -0700895 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700896 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700897}
898
899static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700900 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700901 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700902 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700903 }
904
Jeff Brownb88102f2010-09-08 11:49:43 -0700905 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700906 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700907}
908
909static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700910 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700911 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700912 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700913 }
914
Jeff Brownb88102f2010-09-08 11:49:43 -0700915 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700916 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700917}
918
919static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700920 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700921 if (checkInputManagerUnitialized(env)) {
922 return JNI_FALSE;
923 }
924
925 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
926 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
927 jsize numCodes = env->GetArrayLength(keyCodes);
928 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700929 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700930 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700931 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700932 } else {
933 result = JNI_FALSE;
934 }
935
936 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
937 env->ReleaseIntArrayElements(keyCodes, codes, 0);
938 return result;
939}
940
941static void throwInputChannelNotInitialized(JNIEnv* env) {
942 jniThrowException(env, "java/lang/IllegalStateException",
943 "inputChannel is not initialized");
944}
945
946static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
947 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
948 LOGW("Input channel object '%s' was disposed without first being unregistered with "
949 "the input manager!", inputChannel->getName().string());
950
Jeff Brown9c3cda02010-06-15 01:31:58 -0700951 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700952 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700953 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700954}
955
956static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -0800957 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700958 if (checkInputManagerUnitialized(env)) {
959 return;
960 }
961
962 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
963 inputChannelObj);
964 if (inputChannel == NULL) {
965 throwInputChannelNotInitialized(env);
966 return;
967 }
968
Jeff Brown928e0542011-01-10 11:17:36 -0800969 sp<InputWindowHandle> inputWindowHandle =
970 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700971
972 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -0800973 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700974 if (status) {
975 jniThrowRuntimeException(env, "Failed to register input channel. "
976 "Check logs for details.");
977 return;
978 }
979
Jeff Browna41ca772010-08-11 14:46:32 -0700980 if (! monitor) {
981 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
982 android_server_InputManager_handleInputChannelDisposed, NULL);
983 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700984}
985
986static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
987 jobject inputChannelObj) {
988 if (checkInputManagerUnitialized(env)) {
989 return;
990 }
991
992 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
993 inputChannelObj);
994 if (inputChannel == NULL) {
995 throwInputChannelNotInitialized(env);
996 return;
997 }
998
999 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1000
Jeff Brown7fbdc842010-06-17 20:52:56 -07001001 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001002 if (status) {
1003 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1004 "Check logs for details.");
1005 }
1006}
1007
Jeff Brown6ec402b2010-07-28 15:48:59 -07001008static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1009 jobject inputEventObj, jint injectorPid, jint injectorUid,
1010 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001011 if (checkInputManagerUnitialized(env)) {
1012 return INPUT_EVENT_INJECTION_FAILED;
1013 }
1014
Jeff Brown6ec402b2010-07-28 15:48:59 -07001015 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1016 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001017 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1018 if (status) {
1019 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1020 return INPUT_EVENT_INJECTION_FAILED;
1021 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001022
Jeff Brownb88102f2010-09-08 11:49:43 -07001023 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1024 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001025 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001026 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1027 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001028 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1029 return INPUT_EVENT_INJECTION_FAILED;
1030 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001031
Jeff Brownb88102f2010-09-08 11:49:43 -07001032 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown2ed24622011-03-14 19:39:54 -07001033 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001034 } else {
1035 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001036 return INPUT_EVENT_INJECTION_FAILED;
1037 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001038}
1039
Jeff Brown349703e2010-06-22 01:27:15 -07001040static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1041 jobjectArray windowObjArray) {
1042 if (checkInputManagerUnitialized(env)) {
1043 return;
1044 }
1045
1046 gNativeInputManager->setInputWindows(env, windowObjArray);
1047}
1048
1049static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1050 jobject applicationObj) {
1051 if (checkInputManagerUnitialized(env)) {
1052 return;
1053 }
1054
1055 gNativeInputManager->setFocusedApplication(env, applicationObj);
1056}
1057
1058static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1059 jclass clazz, jboolean enabled, jboolean frozen) {
1060 if (checkInputManagerUnitialized(env)) {
1061 return;
1062 }
1063
1064 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1065}
1066
Jeff Brown05dc66a2011-03-02 14:41:58 -08001067static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1068 jclass clazz, jint visibility) {
1069 if (checkInputManagerUnitialized(env)) {
1070 return;
1071 }
1072
1073 gNativeInputManager->setSystemUiVisibility(visibility);
1074}
1075
Jeff Brown8d608662010-08-30 03:02:23 -07001076static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1077 jclass clazz, jint deviceId) {
1078 if (checkInputManagerUnitialized(env)) {
1079 return NULL;
1080 }
1081
1082 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001083 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001084 deviceId, & deviceInfo);
1085 if (status) {
1086 return NULL;
1087 }
1088
1089 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1090 if (! deviceObj) {
1091 return NULL;
1092 }
1093
1094 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1095 if (! deviceNameObj) {
1096 return NULL;
1097 }
1098
1099 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1100 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1101 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1102 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1103
Jeff Brownefd32662011-03-08 15:13:06 -08001104 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001105 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001106 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001107 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001108 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001109 if (env->ExceptionCheck()) {
1110 return NULL;
1111 }
1112 }
1113
1114 return deviceObj;
1115}
1116
1117static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1118 jclass clazz) {
1119 if (checkInputManagerUnitialized(env)) {
1120 return NULL;
1121 }
1122
1123 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001124 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001125
1126 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1127 if (! deviceIdsObj) {
1128 return NULL;
1129 }
1130
1131 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1132 return deviceIdsObj;
1133}
1134
Jeff Brown57c59372010-09-21 18:22:55 -07001135static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1136 jclass clazz, jobject configObj) {
1137 if (checkInputManagerUnitialized(env)) {
1138 return;
1139 }
1140
1141 InputConfiguration config;
1142 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1143
1144 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1145 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1146 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1147}
1148
Jeff Browne6504122010-09-27 14:52:15 -07001149static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1150 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1151 if (checkInputManagerUnitialized(env)) {
1152 return false;
1153 }
1154
1155 sp<InputChannel> fromChannel =
1156 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1157 sp<InputChannel> toChannel =
1158 android_view_InputChannel_getInputChannel(env, toChannelObj);
1159
1160 if (fromChannel == NULL || toChannel == NULL) {
1161 return false;
1162 }
1163
1164 return gNativeInputManager->getInputManager()->getDispatcher()->
1165 transferTouchFocus(fromChannel, toChannel);
1166}
1167
Jeff Browne33348b2010-07-15 23:54:05 -07001168static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1169 if (checkInputManagerUnitialized(env)) {
1170 return NULL;
1171 }
1172
Jeff Brownb88102f2010-09-08 11:49:43 -07001173 String8 dump;
1174 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001175 return env->NewStringUTF(dump.string());
1176}
1177
Jeff Brown9c3cda02010-06-15 01:31:58 -07001178// ----------------------------------------------------------------------------
1179
Jeff Brown46b9ac02010-04-22 18:58:52 -07001180static JNINativeMethod gInputManagerMethods[] = {
1181 /* name, signature, funcPtr */
Jeff Brown05dc66a2011-03-02 14:41:58 -08001182 { "nativeInit", "(Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001183 (void*) android_server_InputManager_nativeInit },
1184 { "nativeStart", "()V",
1185 (void*) android_server_InputManager_nativeStart },
1186 { "nativeSetDisplaySize", "(III)V",
1187 (void*) android_server_InputManager_nativeSetDisplaySize },
1188 { "nativeSetDisplayOrientation", "(II)V",
1189 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1190 { "nativeGetScanCodeState", "(III)I",
1191 (void*) android_server_InputManager_nativeGetScanCodeState },
1192 { "nativeGetKeyCodeState", "(III)I",
1193 (void*) android_server_InputManager_nativeGetKeyCodeState },
1194 { "nativeGetSwitchState", "(III)I",
1195 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001196 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001197 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001198 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001199 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001200 (void*) android_server_InputManager_nativeRegisterInputChannel },
1201 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001202 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001203 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1204 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001205 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001206 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001207 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001208 (void*) android_server_InputManager_nativeSetFocusedApplication },
1209 { "nativeSetInputDispatchMode", "(ZZ)V",
1210 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001211 { "nativeSetSystemUiVisibility", "(I)V",
1212 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001213 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1214 (void*) android_server_InputManager_nativeGetInputDevice },
1215 { "nativeGetInputDeviceIds", "()[I",
1216 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001217 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1218 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001219 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1220 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001221 { "nativeDump", "()Ljava/lang/String;",
1222 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001223};
1224
1225#define FIND_CLASS(var, className) \
1226 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001227 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001228
1229#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1230 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1231 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1232
1233#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1234 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1235 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1236
1237int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001238 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001239 gInputManagerMethods, NELEM(gInputManagerMethods));
1240 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1241
Jeff Brown9c3cda02010-06-15 01:31:58 -07001242 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001243
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001244 jclass clazz;
1245 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001246
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001247 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001248 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001249
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001250 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001251 "notifyLidSwitchChanged", "(JZ)V");
1252
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001253 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001254 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001255
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001256 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001257 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001258 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001259
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001260 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001261 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001262
Jeff Brown56194eb2011-03-02 19:23:13 -08001263 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001264 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001265 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1266
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001267 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001268 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001269 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001270
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001271 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001272 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001273 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001274
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001275 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001276 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001277
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001278 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001279 "filterTouchEvents", "()Z");
1280
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001281 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001282 "filterJumpyTouchEvents", "()Z");
1283
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001284 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001285 "getVirtualKeyQuietTimeMillis", "()I");
1286
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001287 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001288 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1289
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001290 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001291 "getKeyRepeatTimeout", "()I");
1292
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001293 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001294 "getKeyRepeatDelay", "()I");
1295
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001296 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001297 "getMaxEventsPerSecond", "()I");
1298
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001299 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001300 "getPointerLayer", "()I");
1301
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001302 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001303 "getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001304
Jeff Brown6ec402b2010-07-28 15:48:59 -07001305 // KeyEvent
1306
1307 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001308 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1309
Jeff Brown6ec402b2010-07-28 15:48:59 -07001310
Jeff Brown8d608662010-08-30 03:02:23 -07001311 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001312
1313 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001314 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001315
Jeff Brown8d608662010-08-30 03:02:23 -07001316 // InputDevice
1317
1318 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001319 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001320
1321 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1322 "<init>", "()V");
1323
1324 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001325 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001326
1327 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1328 "mId", "I");
1329
1330 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1331 "mName", "Ljava/lang/String;");
1332
1333 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1334 "mSources", "I");
1335
1336 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1337 "mKeyboardType", "I");
1338
Jeff Brown57c59372010-09-21 18:22:55 -07001339 // Configuration
1340
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001341 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001342
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001343 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001344 "touchscreen", "I");
1345
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001346 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001347 "keyboard", "I");
1348
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001349 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001350 "navigation", "I");
1351
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001352 // PointerIcon
1353
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001354 FIND_CLASS(clazz, "com/android/server/wm/InputManager$PointerIcon");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001355
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001356 GET_FIELD_ID(gPointerIconClassInfo.bitmap, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001357 "bitmap", "Landroid/graphics/Bitmap;");
1358
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001359 GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001360 "hotSpotX", "F");
1361
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001362 GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001363 "hotSpotY", "F");
1364
Jeff Brown46b9ac02010-04-22 18:58:52 -07001365 return 0;
1366}
1367
Jeff Brown46b9ac02010-04-22 18:58:52 -07001368} /* namespace android */