blob: 0ee3217e49a6fe97a5e1a5b2fa1bad78392e3942 [file] [log] [blame]
Jeff Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-04-22 18:58:52 -070031#include <android_runtime/AndroidRuntime.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080032
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070033#include <utils/Log.h>
Jeff Brown05dc66a2011-03-02 14:41:58 -080034#include <utils/Looper.h>
Jeff Brown46b9ac0a2010-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>
Jeff Brown5541de92011-04-11 11:54:25 -070039#include <input/SpriteController.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080040
Jeff Brown05dc66a2011-03-02 14:41:58 -080041#include <android_os_MessageQueue.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080042#include <android_view_KeyEvent.h>
43#include <android_view_MotionEvent.h>
44#include <android_view_InputChannel.h>
Jeff Brown2352b972011-04-12 22:39:53 -070045#include <android_view_PointerIcon.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080046#include <android/graphics/GraphicsJNI.h>
47
Jeff Brown00fa7bd2010-07-02 15:37:36 -070048#include "com_android_server_PowerManagerService.h"
Jeff Brown928e0542011-01-10 11:17:36 -080049#include "com_android_server_InputApplication.h"
50#include "com_android_server_InputApplicationHandle.h"
51#include "com_android_server_InputWindow.h"
52#include "com_android_server_InputWindowHandle.h"
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070053
54namespace android {
55
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070056static struct {
Jeff Brown46b9ac0a2010-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 Brown0029c662011-03-30 02:25:18 -070061 jmethodID filterInputEvent;
Jeff Brown349703e2010-06-22 01:27:15 -070062 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080063 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070064 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070065 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070066 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070067 jmethodID filterTouchEvents;
68 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080069 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070070 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080071 jmethodID getKeyRepeatTimeout;
72 jmethodID getKeyRepeatDelay;
Jeff Brownae9fc032010-08-18 15:51:08 -070073 jmethodID getMaxEventsPerSecond;
Jeff Brown214eaf42011-05-26 19:17:02 -070074 jmethodID getTapTimeout;
75 jmethodID getDoubleTapTimeout;
76 jmethodID getLongPressTimeout;
77 jmethodID getTouchSlop;
Jeff Brown83c09682010-12-23 17:50:18 -080078 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080079 jmethodID getPointerIcon;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070080} gCallbacksClassInfo;
81
82static struct {
83 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070084} gKeyEventClassInfo;
85
86static struct {
87 jclass clazz;
88} gMotionEventClassInfo;
89
Jeff Brown8d608662010-08-30 03:02:23 -070090static struct {
91 jclass clazz;
92
93 jmethodID ctor;
94 jmethodID addMotionRange;
95
96 jfieldID mId;
97 jfieldID mName;
98 jfieldID mSources;
99 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -0700100} gInputDeviceClassInfo;
101
Jeff Brown57c59372010-09-21 18:22:55 -0700102static struct {
Jeff Brown57c59372010-09-21 18:22:55 -0700103 jfieldID touchscreen;
104 jfieldID keyboard;
105 jfieldID navigation;
106} gConfigurationClassInfo;
107
Jeff Brown928e0542011-01-10 11:17:36 -0800108
109// --- Global functions ---
110
Jeff Brown214eaf42011-05-26 19:17:02 -0700111template<typename T>
112inline static T min(const T& a, const T& b) {
113 return a < b ? a : b;
114}
115
116template<typename T>
117inline static T max(const T& a, const T& b) {
118 return a > b ? a : b;
119}
120
Jeff Brown928e0542011-01-10 11:17:36 -0800121static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
122 const sp<InputApplicationHandle>& inputApplicationHandle) {
123 if (inputApplicationHandle == NULL) {
124 return NULL;
125 }
126 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
127 getInputApplicationHandleObjLocalRef(env);
128}
129
130static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
131 const sp<InputWindowHandle>& inputWindowHandle) {
132 if (inputWindowHandle == NULL) {
133 return NULL;
134 }
135 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
136 getInputWindowHandleObjLocalRef(env);
137}
138
Jeff Brown2352b972011-04-12 22:39:53 -0700139static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
140 SpriteIcon* outSpriteIcon) {
141 PointerIcon pointerIcon;
142 status_t status = android_view_PointerIcon_loadSystemIcon(env,
143 contextObj, style, &pointerIcon);
144 if (!status) {
145 pointerIcon.bitmap.copyTo(&outSpriteIcon->bitmap, SkBitmap::kARGB_8888_Config);
146 outSpriteIcon->hotSpotX = pointerIcon.hotSpotX;
147 outSpriteIcon->hotSpotY = pointerIcon.hotSpotY;
148 }
149}
150
Jeff Brown928e0542011-01-10 11:17:36 -0800151
152// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800153
Jeff Brown9c3cda02010-06-15 01:31:58 -0700154class NativeInputManager : public virtual RefBase,
155 public virtual InputReaderPolicyInterface,
Jeff Brown2352b972011-04-12 22:39:53 -0700156 public virtual InputDispatcherPolicyInterface,
157 public virtual PointerControllerPolicyInterface {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700158protected:
159 virtual ~NativeInputManager();
160
161public:
Jeff Brown2352b972011-04-12 22:39:53 -0700162 NativeInputManager(jobject contextObj, jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700163
164 inline sp<InputManager> getInputManager() const { return mInputManager; }
165
Jeff Brownb88102f2010-09-08 11:49:43 -0700166 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700167
Jeff Brown9c3cda02010-06-15 01:31:58 -0700168 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
169 void setDisplayOrientation(int32_t displayId, int32_t orientation);
170
Jeff Brown7fbdc842010-06-17 20:52:56 -0700171 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800172 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700173 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
174
Jeff Brown349703e2010-06-22 01:27:15 -0700175 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
176 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
177 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800178 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700179
Jeff Brown9c3cda02010-06-15 01:31:58 -0700180 /* --- InputReaderPolicyInterface implementation --- */
181
182 virtual bool getDisplayInfo(int32_t displayId,
183 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown214eaf42011-05-26 19:17:02 -0700184 virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);
Jeff Brown83c09682010-12-23 17:50:18 -0800185 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700186
187 /* --- InputDispatcherPolicyInterface implementation --- */
188
Jeff Browne20c9e02010-10-11 14:20:19 -0700189 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
190 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700191 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700192 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800193 const sp<InputWindowHandle>& inputWindowHandle);
194 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown0029c662011-03-30 02:25:18 -0700195 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
Jeff Brown214eaf42011-05-26 19:17:02 -0700196 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
197 virtual bool isKeyRepeatEnabled();
Jeff Brown1f245102010-11-18 20:53:46 -0800198 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800199 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800200 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700201 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800202 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800203 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700204 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700205 virtual bool checkInjectEventsPermissionNonReentrant(
206 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700207
Jeff Brown2352b972011-04-12 22:39:53 -0700208 /* --- PointerControllerPolicyInterface implementation --- */
209
210 virtual void loadPointerResources(PointerResources* outResources);
211
Jeff Brown9c3cda02010-06-15 01:31:58 -0700212private:
213 sp<InputManager> mInputManager;
214
Jeff Brown2352b972011-04-12 22:39:53 -0700215 jobject mContextObj;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700216 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800217 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700218
Jeff Brown83c09682010-12-23 17:50:18 -0800219 Mutex mLock;
220 struct Locked {
221 // Display size information.
222 int32_t displayWidth, displayHeight; // -1 when initialized
223 int32_t displayOrientation;
224
Jeff Brown05dc66a2011-03-02 14:41:58 -0800225 // System UI visibility.
226 int32_t systemUiVisibility;
227
Jeff Brown5541de92011-04-11 11:54:25 -0700228 // Sprite controller singleton, created on first use.
229 sp<SpriteController> spriteController;
230
Jeff Brown83c09682010-12-23 17:50:18 -0800231 // Pointer controller singleton, created and destroyed as needed.
232 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800233 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700234
Jeff Brown2352b972011-04-12 22:39:53 -0700235 void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800236 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown5541de92011-04-11 11:54:25 -0700237 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800238
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700239 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700240 bool isScreenOn();
241 bool isScreenBright();
242
Jeff Brownb88102f2010-09-08 11:49:43 -0700243 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700244
Jeff Brown9c3cda02010-06-15 01:31:58 -0700245 static inline JNIEnv* jniEnv() {
246 return AndroidRuntime::getJNIEnv();
247 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700248};
249
Jeff Brown928e0542011-01-10 11:17:36 -0800250
Jeff Brown9c3cda02010-06-15 01:31:58 -0700251
Jeff Brown2352b972011-04-12 22:39:53 -0700252NativeInputManager::NativeInputManager(jobject contextObj,
253 jobject callbacksObj, const sp<Looper>& looper) :
Jeff Brown214eaf42011-05-26 19:17:02 -0700254 mLooper(looper) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700255 JNIEnv* env = jniEnv();
256
Jeff Brown2352b972011-04-12 22:39:53 -0700257 mContextObj = env->NewGlobalRef(contextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700258 mCallbacksObj = env->NewGlobalRef(callbacksObj);
259
Jeff Brown83c09682010-12-23 17:50:18 -0800260 {
261 AutoMutex _l(mLock);
262 mLocked.displayWidth = -1;
263 mLocked.displayHeight = -1;
264 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800265
266 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800267 }
268
Jeff Brown9c3cda02010-06-15 01:31:58 -0700269 sp<EventHub> eventHub = new EventHub();
270 mInputManager = new InputManager(eventHub, this, this);
271}
272
273NativeInputManager::~NativeInputManager() {
274 JNIEnv* env = jniEnv();
275
Jeff Brown2352b972011-04-12 22:39:53 -0700276 env->DeleteGlobalRef(mContextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700277 env->DeleteGlobalRef(mCallbacksObj);
278}
279
Jeff Brownb88102f2010-09-08 11:49:43 -0700280void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700281 mInputManager->getReader()->dump(dump);
282 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700283
Jeff Brownb88102f2010-09-08 11:49:43 -0700284 mInputManager->getDispatcher()->dump(dump);
285 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700286}
287
Jeff Brown7fbdc842010-06-17 20:52:56 -0700288bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700289 if (env->ExceptionCheck()) {
290 LOGE("An exception was thrown by callback '%s'.", methodName);
291 LOGE_EX(env);
292 env->ExceptionClear();
293 return true;
294 }
295 return false;
296}
297
298void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
299 if (displayId == 0) {
Jeff Brown2352b972011-04-12 22:39:53 -0700300 { // acquire lock
301 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700302
Jeff Brown2352b972011-04-12 22:39:53 -0700303 if (mLocked.displayWidth == width && mLocked.displayHeight == height) {
304 return;
305 }
306
Jeff Brown83c09682010-12-23 17:50:18 -0800307 mLocked.displayWidth = width;
308 mLocked.displayHeight = height;
309
310 sp<PointerController> controller = mLocked.pointerController.promote();
311 if (controller != NULL) {
312 controller->setDisplaySize(width, height);
313 }
Jeff Brown2352b972011-04-12 22:39:53 -0700314 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700315 }
316}
317
318void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
319 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800320 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700321
Jeff Brown83c09682010-12-23 17:50:18 -0800322 if (mLocked.displayOrientation != orientation) {
323 mLocked.displayOrientation = orientation;
324
325 sp<PointerController> controller = mLocked.pointerController.promote();
326 if (controller != NULL) {
327 controller->setDisplayOrientation(orientation);
328 }
329 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700330 }
331}
332
Jeff Brown7fbdc842010-06-17 20:52:56 -0700333status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800334 const sp<InputChannel>& inputChannel,
335 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
336 return mInputManager->getDispatcher()->registerInputChannel(
337 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700338}
339
340status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
341 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700342 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700343}
344
Jeff Brown9c3cda02010-06-15 01:31:58 -0700345bool NativeInputManager::getDisplayInfo(int32_t displayId,
346 int32_t* width, int32_t* height, int32_t* orientation) {
347 bool result = false;
348 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800349 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700350
Jeff Brown83c09682010-12-23 17:50:18 -0800351 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700352 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800353 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700354 }
355 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800356 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700357 }
358 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800359 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700360 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700361 result = true;
362 }
363 }
364 return result;
365}
366
Jeff Brown214eaf42011-05-26 19:17:02 -0700367void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700368 JNIEnv* env = jniEnv();
369
Jeff Brown214eaf42011-05-26 19:17:02 -0700370 jboolean filterTouchEvents = env->CallBooleanMethod(mCallbacksObj,
371 gCallbacksClassInfo.filterTouchEvents);
372 if (!checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
373 outConfig->filterTouchEvents = filterTouchEvents;
374 }
375
376 jboolean filterJumpyTouchEvents = env->CallBooleanMethod(mCallbacksObj,
377 gCallbacksClassInfo.filterJumpyTouchEvents);
378 if (!checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
379 outConfig->filterJumpyTouchEvents = filterJumpyTouchEvents;
380 }
381
382 jint virtualKeyQuietTime = env->CallIntMethod(mCallbacksObj,
383 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
384 if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
385 outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
386 }
387
388 outConfig->excludedDeviceNames.clear();
389 jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mCallbacksObj,
Jeff Brown9c3cda02010-06-15 01:31:58 -0700390 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown214eaf42011-05-26 19:17:02 -0700391 if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
392 jsize length = env->GetArrayLength(excludedDeviceNames);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700393 for (jsize i = 0; i < length; i++) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700394 jstring item = jstring(env->GetObjectArrayElement(excludedDeviceNames, i));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700395 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
Jeff Brown214eaf42011-05-26 19:17:02 -0700396 outConfig->excludedDeviceNames.add(String8(deviceNameChars));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700397 env->ReleaseStringUTFChars(item, deviceNameChars);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700398 env->DeleteLocalRef(item);
399 }
Jeff Brown214eaf42011-05-26 19:17:02 -0700400 env->DeleteLocalRef(excludedDeviceNames);
401 }
402
403 jint tapTimeout = env->CallIntMethod(mCallbacksObj,
404 gCallbacksClassInfo.getTapTimeout);
405 if (!checkAndClearExceptionFromCallback(env, "getTapTimeout")) {
406 jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
407 gCallbacksClassInfo.getDoubleTapTimeout);
408 if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
409 jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
410 gCallbacksClassInfo.getLongPressTimeout);
411 if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
412 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(tapTimeout);
413
414 // We must ensure that the tap-drag interval is significantly shorter than
415 // the long-press timeout because the tap is held down for the entire duration
416 // of the double-tap timeout.
417 jint tapDragInterval = max(min(longPressTimeout - 100,
418 doubleTapTimeout), tapTimeout);
419 outConfig->pointerGestureTapDragInterval =
420 milliseconds_to_nanoseconds(tapDragInterval);
421 }
422 }
423 }
424
425 jint touchSlop = env->CallIntMethod(mCallbacksObj,
426 gCallbacksClassInfo.getTouchSlop);
427 if (!checkAndClearExceptionFromCallback(env, "getTouchSlop")) {
428 outConfig->pointerGestureTapSlop = touchSlop;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700429 }
430}
431
Jeff Brown83c09682010-12-23 17:50:18 -0800432sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
433 AutoMutex _l(mLock);
434
435 sp<PointerController> controller = mLocked.pointerController.promote();
436 if (controller == NULL) {
Jeff Brown5541de92011-04-11 11:54:25 -0700437 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800438
Jeff Brown2352b972011-04-12 22:39:53 -0700439 controller = new PointerController(this, mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800440 mLocked.pointerController = controller;
441
442 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
443 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800444
Jeff Brown5541de92011-04-11 11:54:25 -0700445 JNIEnv* env = jniEnv();
Jeff Brown2352b972011-04-12 22:39:53 -0700446 jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
447 gCallbacksClassInfo.getPointerIcon);
448 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
449 PointerIcon pointerIcon;
450 status_t status = android_view_PointerIcon_load(env, pointerIconObj,
451 mContextObj, &pointerIcon);
452 if (!status && !pointerIcon.isNullIcon()) {
453 controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
454 pointerIcon.hotSpotX, pointerIcon.hotSpotY));
455 } else {
456 controller->setPointerIcon(SpriteIcon());
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800457 }
Jeff Brown2352b972011-04-12 22:39:53 -0700458 env->DeleteLocalRef(pointerIconObj);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800459 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800460
Jeff Brown2352b972011-04-12 22:39:53 -0700461 updateInactivityTimeoutLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800462 }
463 return controller;
464}
465
Jeff Brown5541de92011-04-11 11:54:25 -0700466void NativeInputManager::ensureSpriteControllerLocked() {
467 if (mLocked.spriteController == NULL) {
468 JNIEnv* env = jniEnv();
469 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
470 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
471 layer = -1;
472 }
473 mLocked.spriteController = new SpriteController(mLooper, layer);
474 }
475}
476
Jeff Browne20c9e02010-10-11 14:20:19 -0700477void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
478 int32_t switchValue, uint32_t policyFlags) {
479#if DEBUG_INPUT_DISPATCHER_POLICY
480 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
481 when, switchCode, switchValue, policyFlags);
482#endif
483
484 JNIEnv* env = jniEnv();
485
486 switch (switchCode) {
487 case SW_LID:
488 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
489 when, switchValue == 0);
490 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
491 break;
492 }
493}
494
Jeff Brown9c3cda02010-06-15 01:31:58 -0700495void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
496#if DEBUG_INPUT_DISPATCHER_POLICY
497 LOGD("notifyConfigurationChanged - when=%lld", when);
498#endif
499
500 JNIEnv* env = jniEnv();
501
Jeff Brown57c59372010-09-21 18:22:55 -0700502 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700503 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700504}
505
Jeff Brown519e0242010-09-15 15:18:56 -0700506nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800507 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700508#if DEBUG_INPUT_DISPATCHER_POLICY
509 LOGD("notifyANR");
510#endif
511
512 JNIEnv* env = jniEnv();
513
Jeff Brown928e0542011-01-10 11:17:36 -0800514 jobject inputApplicationHandleObj =
515 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
516 jobject inputWindowHandleObj =
517 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700518
Jeff Brown519e0242010-09-15 15:18:56 -0700519 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800520 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700521 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
522 newTimeout = 0; // abort dispatch
523 } else {
524 assert(newTimeout >= 0);
525 }
526
Jeff Brown928e0542011-01-10 11:17:36 -0800527 env->DeleteLocalRef(inputWindowHandleObj);
528 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700529 return newTimeout;
530}
531
Jeff Brown928e0542011-01-10 11:17:36 -0800532void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700533#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800534 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700535#endif
536
Jeff Brown7fbdc842010-06-17 20:52:56 -0700537 JNIEnv* env = jniEnv();
538
Jeff Brown928e0542011-01-10 11:17:36 -0800539 jobject inputWindowHandleObj =
540 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
541 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700542 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800543 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700544 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
545
Jeff Brown928e0542011-01-10 11:17:36 -0800546 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700547 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700548}
549
Jeff Brown214eaf42011-05-26 19:17:02 -0700550void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
551 JNIEnv* env = jniEnv();
Jeff Browna4547672011-03-02 21:38:11 -0800552
Jeff Brown214eaf42011-05-26 19:17:02 -0700553 jint keyRepeatTimeout = env->CallIntMethod(mCallbacksObj,
554 gCallbacksClassInfo.getKeyRepeatTimeout);
555 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
556 outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
557 }
Jeff Browna4547672011-03-02 21:38:11 -0800558
Jeff Brown214eaf42011-05-26 19:17:02 -0700559 jint keyRepeatDelay = env->CallIntMethod(mCallbacksObj,
560 gCallbacksClassInfo.getKeyRepeatDelay);
561 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
562 outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
563 }
564
565 jint maxEventsPerSecond = env->CallIntMethod(mCallbacksObj,
566 gCallbacksClassInfo.getMaxEventsPerSecond);
567 if (!checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
568 outConfig->maxEventsPerSecond = maxEventsPerSecond;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700569 }
570}
571
Jeff Brown214eaf42011-05-26 19:17:02 -0700572bool NativeInputManager::isKeyRepeatEnabled() {
573 // Only enable automatic key repeating when the screen is on.
574 return isScreenOn();
Jeff Brownae9fc032010-08-18 15:51:08 -0700575}
576
Jeff Brown349703e2010-06-22 01:27:15 -0700577void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700578 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700579
Jeff Brownb88102f2010-09-08 11:49:43 -0700580 jsize length = env->GetArrayLength(windowObjArray);
581 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800582 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
583 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700584 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700585 }
586
Jeff Brownb88102f2010-09-08 11:49:43 -0700587 windows.push();
588 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800589 android_server_InputWindow_toNative(env, windowObj, &window);
590 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700591 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700592 }
Jeff Brown928e0542011-01-10 11:17:36 -0800593 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700594 }
Jeff Brown349703e2010-06-22 01:27:15 -0700595
Jeff Brownb88102f2010-09-08 11:49:43 -0700596 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700597}
598
Jeff Brown349703e2010-06-22 01:27:15 -0700599void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700600 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700601 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800602 android_server_InputApplication_toNative(env, applicationObj, &application);
603 if (application.inputApplicationHandle != NULL) {
604 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Browna2cc28d2011-03-25 11:58:46 -0700605 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800606 }
Jeff Brown349703e2010-06-22 01:27:15 -0700607 }
Jeff Brown928e0542011-01-10 11:17:36 -0800608 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700609}
610
611void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700612 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700613}
614
Jeff Brown05dc66a2011-03-02 14:41:58 -0800615void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
616 AutoMutex _l(mLock);
617
618 if (mLocked.systemUiVisibility != visibility) {
619 mLocked.systemUiVisibility = visibility;
620
621 sp<PointerController> controller = mLocked.pointerController.promote();
622 if (controller != NULL) {
Jeff Brown2352b972011-04-12 22:39:53 -0700623 updateInactivityTimeoutLocked(controller);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800624 }
625 }
626}
627
Jeff Brown2352b972011-04-12 22:39:53 -0700628void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800629 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
Jeff Brown2352b972011-04-12 22:39:53 -0700630 controller->setInactivityTimeout(lightsOut
631 ? PointerController::INACTIVITY_TIMEOUT_SHORT
632 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800633}
634
Jeff Browne20c9e02010-10-11 14:20:19 -0700635bool NativeInputManager::isScreenOn() {
636 return android_server_PowerManagerService_isScreenOn();
637}
638
639bool NativeInputManager::isScreenBright() {
640 return android_server_PowerManagerService_isScreenBright();
641}
642
Jeff Brown0029c662011-03-30 02:25:18 -0700643bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
644 jobject inputEventObj;
645
646 JNIEnv* env = jniEnv();
647 switch (inputEvent->getType()) {
648 case AINPUT_EVENT_TYPE_KEY:
649 inputEventObj = android_view_KeyEvent_fromNative(env,
650 static_cast<const KeyEvent*>(inputEvent));
651 break;
652 case AINPUT_EVENT_TYPE_MOTION:
653 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
654 static_cast<const MotionEvent*>(inputEvent));
655 break;
656 default:
657 return true; // dispatch the event normally
658 }
659
660 if (!inputEventObj) {
661 LOGE("Failed to obtain input event object for filterInputEvent.");
662 return true; // dispatch the event normally
663 }
664
665 // The callee is responsible for recycling the event.
666 jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
667 inputEventObj, policyFlags);
668 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
669 pass = true;
670 }
671 env->DeleteLocalRef(inputEventObj);
672 return pass;
673}
674
Jeff Brown1f245102010-11-18 20:53:46 -0800675void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
676 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700677 // Policy:
678 // - Ignore untrusted events and pass them along.
679 // - Ask the window manager what to do with normal events and trusted injected events.
680 // - For normal events wake and brighten the screen if currently off or dim.
681 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800682 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700683 bool isScreenOn = this->isScreenOn();
684 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700685
Jeff Brown3122e442010-10-11 23:32:49 -0700686 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800687 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
688 jint wmActions;
689 if (keyEventObj) {
690 wmActions = env->CallIntMethod(mCallbacksObj,
691 gCallbacksClassInfo.interceptKeyBeforeQueueing,
692 keyEventObj, policyFlags, isScreenOn);
693 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
694 wmActions = 0;
695 }
696 android_view_KeyEvent_recycle(env, keyEventObj);
697 env->DeleteLocalRef(keyEventObj);
698 } else {
699 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700700 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700701 }
702
Jeff Brown1f245102010-11-18 20:53:46 -0800703 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700704 if (!isScreenOn) {
705 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700706 }
707
708 if (!isScreenBright) {
709 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
710 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700711 }
712
Jeff Brown56194eb2011-03-02 19:23:13 -0800713 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700714 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700715 policyFlags |= POLICY_FLAG_PASS_TO_USER;
716 }
717}
718
Jeff Brown56194eb2011-03-02 19:23:13 -0800719void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700720 // Policy:
721 // - Ignore untrusted events and pass them along.
722 // - No special filtering for injected events required at this time.
723 // - Filter normal events based on screen state.
724 // - For normal events brighten (but do not wake) the screen if currently dim.
725 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
726 if (isScreenOn()) {
727 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700728
Jeff Brown3122e442010-10-11 23:32:49 -0700729 if (!isScreenBright()) {
730 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
731 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800732 } else {
733 JNIEnv* env = jniEnv();
734 jint wmActions = env->CallIntMethod(mCallbacksObj,
735 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
736 policyFlags);
737 if (checkAndClearExceptionFromCallback(env,
738 "interceptMotionBeforeQueueingWhenScreenOff")) {
739 wmActions = 0;
740 }
741
742 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
743 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700744 }
Jeff Brown3122e442010-10-11 23:32:49 -0700745 } else {
746 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700747 }
748}
749
Jeff Brown56194eb2011-03-02 19:23:13 -0800750void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
751 uint32_t& policyFlags) {
752 enum {
753 WM_ACTION_PASS_TO_USER = 1,
754 WM_ACTION_POKE_USER_ACTIVITY = 2,
755 WM_ACTION_GO_TO_SLEEP = 4,
756 };
757
758 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800759#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800760 LOGD("handleInterceptActions: Going to sleep.");
761#endif
762 android_server_PowerManagerService_goToSleep(when);
763 }
764
765 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800766#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800767 LOGD("handleInterceptActions: Poking user activity.");
768#endif
769 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
770 }
771
772 if (wmActions & WM_ACTION_PASS_TO_USER) {
773 policyFlags |= POLICY_FLAG_PASS_TO_USER;
774 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800775#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800776 LOGD("handleInterceptActions: Not passing key to user.");
777#endif
778 }
779}
780
Jeff Brown928e0542011-01-10 11:17:36 -0800781bool NativeInputManager::interceptKeyBeforeDispatching(
782 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700783 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700784 // Policy:
785 // - Ignore untrusted events and pass them along.
786 // - Filter normal events and trusted injected events through the window manager policy to
787 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800788 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700789 if (policyFlags & POLICY_FLAG_TRUSTED) {
790 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700791
Jeff Brown928e0542011-01-10 11:17:36 -0800792 // Note: inputWindowHandle may be null.
793 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800794 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
795 if (keyEventObj) {
796 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
797 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800798 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800799 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
800 android_view_KeyEvent_recycle(env, keyEventObj);
801 env->DeleteLocalRef(keyEventObj);
802 result = consumed && !error;
803 } else {
804 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800805 }
Jeff Brown928e0542011-01-10 11:17:36 -0800806 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700807 }
Jeff Brown1f245102010-11-18 20:53:46 -0800808 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700809}
810
Jeff Brown928e0542011-01-10 11:17:36 -0800811bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800812 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700813 // Policy:
814 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800815 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700816 if (policyFlags & POLICY_FLAG_TRUSTED) {
817 JNIEnv* env = jniEnv();
818
Jeff Brown928e0542011-01-10 11:17:36 -0800819 // Note: inputWindowHandle may be null.
820 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800821 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
822 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800823 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800824 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800825 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700826 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
827 fallbackKeyEventObj = NULL;
828 }
Jeff Brown1f245102010-11-18 20:53:46 -0800829 android_view_KeyEvent_recycle(env, keyEventObj);
830 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800831
832 if (fallbackKeyEventObj) {
833 // Note: outFallbackKeyEvent may be the same object as keyEvent.
834 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
835 outFallbackKeyEvent)) {
836 result = true;
837 }
838 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
839 env->DeleteLocalRef(fallbackKeyEventObj);
840 }
Jeff Brown1f245102010-11-18 20:53:46 -0800841 } else {
842 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800843 }
Jeff Brown928e0542011-01-10 11:17:36 -0800844 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700845 }
Jeff Brown1f245102010-11-18 20:53:46 -0800846 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700847}
848
Jeff Brown01ce2e92010-09-26 22:20:12 -0700849void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
850 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700851}
852
Jeff Brown349703e2010-06-22 01:27:15 -0700853
Jeff Brownb88102f2010-09-08 11:49:43 -0700854bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
855 int32_t injectorPid, int32_t injectorUid) {
856 JNIEnv* env = jniEnv();
857 jboolean result = env->CallBooleanMethod(mCallbacksObj,
858 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700859 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
860 result = false;
861 }
Jeff Brown349703e2010-06-22 01:27:15 -0700862 return result;
863}
864
Jeff Brown2352b972011-04-12 22:39:53 -0700865void NativeInputManager::loadPointerResources(PointerResources* outResources) {
866 JNIEnv* env = jniEnv();
867
868 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER,
869 &outResources->spotHover);
870 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH,
871 &outResources->spotTouch);
872 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR,
873 &outResources->spotAnchor);
874}
875
Jeff Brown83c09682010-12-23 17:50:18 -0800876
Jeff Brown9c3cda02010-06-15 01:31:58 -0700877// ----------------------------------------------------------------------------
878
879static sp<NativeInputManager> gNativeInputManager;
880
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700881static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700882 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700883 LOGE("Input manager not initialized.");
884 jniThrowRuntimeException(env, "Input manager not initialized.");
885 return true;
886 }
887 return false;
888}
889
890static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown2352b972011-04-12 22:39:53 -0700891 jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700892 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800893 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
Jeff Brown2352b972011-04-12 22:39:53 -0700894 gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700895 } else {
896 LOGE("Input manager already initialized.");
897 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700898 }
899}
900
901static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
902 if (checkInputManagerUnitialized(env)) {
903 return;
904 }
905
Jeff Brown9c3cda02010-06-15 01:31:58 -0700906 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700907 if (result) {
908 jniThrowRuntimeException(env, "Input manager could not be started.");
909 }
910}
911
912static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
913 jint displayId, jint width, jint height) {
914 if (checkInputManagerUnitialized(env)) {
915 return;
916 }
917
918 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
919 // to be passed in like this, not sure which is better but leaving it like this
920 // keeps the window manager in direct control of when display transitions propagate down
921 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700922 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700923}
924
925static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
926 jint displayId, jint orientation) {
927 if (checkInputManagerUnitialized(env)) {
928 return;
929 }
930
Jeff Brown9c3cda02010-06-15 01:31:58 -0700931 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700932}
933
934static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700935 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700936 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700937 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700938 }
939
Jeff Brownb88102f2010-09-08 11:49:43 -0700940 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700941 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700942}
943
944static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700945 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700946 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700947 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700948 }
949
Jeff Brownb88102f2010-09-08 11:49:43 -0700950 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700951 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700952}
953
954static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700955 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700956 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700957 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700958 }
959
Jeff Brownb88102f2010-09-08 11:49:43 -0700960 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700961 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700962}
963
964static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700965 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700966 if (checkInputManagerUnitialized(env)) {
967 return JNI_FALSE;
968 }
969
970 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
971 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
972 jsize numCodes = env->GetArrayLength(keyCodes);
973 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700974 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700975 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700976 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700977 } else {
978 result = JNI_FALSE;
979 }
980
981 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
982 env->ReleaseIntArrayElements(keyCodes, codes, 0);
983 return result;
984}
985
986static void throwInputChannelNotInitialized(JNIEnv* env) {
987 jniThrowException(env, "java/lang/IllegalStateException",
988 "inputChannel is not initialized");
989}
990
991static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
992 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
993 LOGW("Input channel object '%s' was disposed without first being unregistered with "
994 "the input manager!", inputChannel->getName().string());
995
Jeff Brown9c3cda02010-06-15 01:31:58 -0700996 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700997 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700998 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700999}
1000
1001static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001002 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001003 if (checkInputManagerUnitialized(env)) {
1004 return;
1005 }
1006
1007 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1008 inputChannelObj);
1009 if (inputChannel == NULL) {
1010 throwInputChannelNotInitialized(env);
1011 return;
1012 }
1013
Jeff Brown928e0542011-01-10 11:17:36 -08001014 sp<InputWindowHandle> inputWindowHandle =
1015 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001016
1017 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001018 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001019 if (status) {
1020 jniThrowRuntimeException(env, "Failed to register input channel. "
1021 "Check logs for details.");
1022 return;
1023 }
1024
Jeff Browna41ca772010-08-11 14:46:32 -07001025 if (! monitor) {
1026 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1027 android_server_InputManager_handleInputChannelDisposed, NULL);
1028 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001029}
1030
1031static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1032 jobject inputChannelObj) {
1033 if (checkInputManagerUnitialized(env)) {
1034 return;
1035 }
1036
1037 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1038 inputChannelObj);
1039 if (inputChannel == NULL) {
1040 throwInputChannelNotInitialized(env);
1041 return;
1042 }
1043
1044 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1045
Jeff Brown7fbdc842010-06-17 20:52:56 -07001046 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001047 if (status) {
1048 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1049 "Check logs for details.");
1050 }
1051}
1052
Jeff Brown0029c662011-03-30 02:25:18 -07001053static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
1054 jboolean enabled) {
1055 if (checkInputManagerUnitialized(env)) {
1056 return;
1057 }
1058
1059 gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1060}
1061
Jeff Brown6ec402b2010-07-28 15:48:59 -07001062static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1063 jobject inputEventObj, jint injectorPid, jint injectorUid,
Jeff Brown0029c662011-03-30 02:25:18 -07001064 jint syncMode, jint timeoutMillis, jint policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001065 if (checkInputManagerUnitialized(env)) {
1066 return INPUT_EVENT_INJECTION_FAILED;
1067 }
1068
Jeff Brown6ec402b2010-07-28 15:48:59 -07001069 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1070 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001071 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1072 if (status) {
1073 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1074 return INPUT_EVENT_INJECTION_FAILED;
1075 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001076
Jeff Brownb88102f2010-09-08 11:49:43 -07001077 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001078 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1079 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001080 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001081 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1082 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001083 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1084 return INPUT_EVENT_INJECTION_FAILED;
1085 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001086
Jeff Brownb88102f2010-09-08 11:49:43 -07001087 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001088 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1089 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001090 } else {
1091 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001092 return INPUT_EVENT_INJECTION_FAILED;
1093 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001094}
1095
Jeff Brown349703e2010-06-22 01:27:15 -07001096static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1097 jobjectArray windowObjArray) {
1098 if (checkInputManagerUnitialized(env)) {
1099 return;
1100 }
1101
1102 gNativeInputManager->setInputWindows(env, windowObjArray);
1103}
1104
1105static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1106 jobject applicationObj) {
1107 if (checkInputManagerUnitialized(env)) {
1108 return;
1109 }
1110
1111 gNativeInputManager->setFocusedApplication(env, applicationObj);
1112}
1113
1114static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1115 jclass clazz, jboolean enabled, jboolean frozen) {
1116 if (checkInputManagerUnitialized(env)) {
1117 return;
1118 }
1119
1120 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1121}
1122
Jeff Brown05dc66a2011-03-02 14:41:58 -08001123static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1124 jclass clazz, jint visibility) {
1125 if (checkInputManagerUnitialized(env)) {
1126 return;
1127 }
1128
1129 gNativeInputManager->setSystemUiVisibility(visibility);
1130}
1131
Jeff Brown8d608662010-08-30 03:02:23 -07001132static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1133 jclass clazz, jint deviceId) {
1134 if (checkInputManagerUnitialized(env)) {
1135 return NULL;
1136 }
1137
1138 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001139 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001140 deviceId, & deviceInfo);
1141 if (status) {
1142 return NULL;
1143 }
1144
1145 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1146 if (! deviceObj) {
1147 return NULL;
1148 }
1149
1150 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1151 if (! deviceNameObj) {
1152 return NULL;
1153 }
1154
1155 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1156 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1157 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1158 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1159
Jeff Brownefd32662011-03-08 15:13:06 -08001160 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001161 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001162 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001163 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001164 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001165 if (env->ExceptionCheck()) {
1166 return NULL;
1167 }
1168 }
1169
1170 return deviceObj;
1171}
1172
1173static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1174 jclass clazz) {
1175 if (checkInputManagerUnitialized(env)) {
1176 return NULL;
1177 }
1178
1179 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001180 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001181
1182 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1183 if (! deviceIdsObj) {
1184 return NULL;
1185 }
1186
1187 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1188 return deviceIdsObj;
1189}
1190
Jeff Brown57c59372010-09-21 18:22:55 -07001191static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1192 jclass clazz, jobject configObj) {
1193 if (checkInputManagerUnitialized(env)) {
1194 return;
1195 }
1196
1197 InputConfiguration config;
1198 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1199
1200 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1201 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1202 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1203}
1204
Jeff Browne6504122010-09-27 14:52:15 -07001205static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1206 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1207 if (checkInputManagerUnitialized(env)) {
1208 return false;
1209 }
1210
1211 sp<InputChannel> fromChannel =
1212 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1213 sp<InputChannel> toChannel =
1214 android_view_InputChannel_getInputChannel(env, toChannelObj);
1215
1216 if (fromChannel == NULL || toChannel == NULL) {
1217 return false;
1218 }
1219
1220 return gNativeInputManager->getInputManager()->getDispatcher()->
1221 transferTouchFocus(fromChannel, toChannel);
1222}
1223
Jeff Browne33348b2010-07-15 23:54:05 -07001224static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1225 if (checkInputManagerUnitialized(env)) {
1226 return NULL;
1227 }
1228
Jeff Brownb88102f2010-09-08 11:49:43 -07001229 String8 dump;
1230 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001231 return env->NewStringUTF(dump.string());
1232}
1233
Jeff Brown9c3cda02010-06-15 01:31:58 -07001234// ----------------------------------------------------------------------------
1235
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001236static JNINativeMethod gInputManagerMethods[] = {
1237 /* name, signature, funcPtr */
Jeff Brown2352b972011-04-12 22:39:53 -07001238 { "nativeInit", "(Landroid/content/Context;"
1239 "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001240 (void*) android_server_InputManager_nativeInit },
1241 { "nativeStart", "()V",
1242 (void*) android_server_InputManager_nativeStart },
1243 { "nativeSetDisplaySize", "(III)V",
1244 (void*) android_server_InputManager_nativeSetDisplaySize },
1245 { "nativeSetDisplayOrientation", "(II)V",
1246 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1247 { "nativeGetScanCodeState", "(III)I",
1248 (void*) android_server_InputManager_nativeGetScanCodeState },
1249 { "nativeGetKeyCodeState", "(III)I",
1250 (void*) android_server_InputManager_nativeGetKeyCodeState },
1251 { "nativeGetSwitchState", "(III)I",
1252 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001253 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001254 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001255 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001256 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001257 (void*) android_server_InputManager_nativeRegisterInputChannel },
1258 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001259 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown0029c662011-03-30 02:25:18 -07001260 { "nativeSetInputFilterEnabled", "(Z)V",
1261 (void*) android_server_InputManager_nativeSetInputFilterEnabled },
1262 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
Jeff Brown6ec402b2010-07-28 15:48:59 -07001263 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001264 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001265 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001266 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001267 (void*) android_server_InputManager_nativeSetFocusedApplication },
1268 { "nativeSetInputDispatchMode", "(ZZ)V",
1269 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001270 { "nativeSetSystemUiVisibility", "(I)V",
1271 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001272 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1273 (void*) android_server_InputManager_nativeGetInputDevice },
1274 { "nativeGetInputDeviceIds", "()[I",
1275 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001276 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1277 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001278 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1279 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001280 { "nativeDump", "()Ljava/lang/String;",
1281 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001282};
1283
1284#define FIND_CLASS(var, className) \
1285 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001286 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001287
1288#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1289 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1290 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1291
1292#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1293 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1294 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1295
1296int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001297 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001298 gInputManagerMethods, NELEM(gInputManagerMethods));
1299 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1300
Jeff Brown9c3cda02010-06-15 01:31:58 -07001301 // Callbacks
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001302
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001303 jclass clazz;
1304 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001305
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001306 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001307 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001308
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001309 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001310 "notifyLidSwitchChanged", "(JZ)V");
1311
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001312 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001313 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001314
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001315 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001316 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001317 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001318
Jeff Brown0029c662011-03-30 02:25:18 -07001319 GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
1320 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1321
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001322 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001323 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001324
Jeff Brown56194eb2011-03-02 19:23:13 -08001325 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001326 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001327 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1328
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001329 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001330 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001331 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001332
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001333 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001334 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001335 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001336
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001337 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001338 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001339
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001340 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, clazz,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001341 "filterTouchEvents", "()Z");
1342
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001343 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, clazz,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001344 "filterJumpyTouchEvents", "()Z");
1345
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001346 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001347 "getVirtualKeyQuietTimeMillis", "()I");
1348
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001349 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001350 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1351
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001352 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001353 "getKeyRepeatTimeout", "()I");
1354
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001355 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001356 "getKeyRepeatDelay", "()I");
1357
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001358 GET_METHOD_ID(gCallbacksClassInfo.getTapTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001359 "getTapTimeout", "()I");
1360
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001361 GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001362 "getDoubleTapTimeout", "()I");
1363
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001364 GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001365 "getLongPressTimeout", "()I");
1366
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001367 GET_METHOD_ID(gCallbacksClassInfo.getTouchSlop, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001368 "getTouchSlop", "()I");
1369
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001370 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001371 "getMaxEventsPerSecond", "()I");
1372
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001373 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001374 "getPointerLayer", "()I");
1375
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001376 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Jeff Brown2352b972011-04-12 22:39:53 -07001377 "getPointerIcon", "()Landroid/view/PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001378
Jeff Brown6ec402b2010-07-28 15:48:59 -07001379 // KeyEvent
1380
1381 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001382 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1383
Jeff Brown6ec402b2010-07-28 15:48:59 -07001384
Jeff Brown8d608662010-08-30 03:02:23 -07001385 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001386
1387 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001388 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001389
Jeff Brown8d608662010-08-30 03:02:23 -07001390 // InputDevice
1391
1392 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001393 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001394
1395 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1396 "<init>", "()V");
1397
1398 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001399 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001400
1401 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1402 "mId", "I");
1403
1404 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1405 "mName", "Ljava/lang/String;");
1406
1407 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1408 "mSources", "I");
1409
1410 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1411 "mKeyboardType", "I");
1412
Jeff Brown57c59372010-09-21 18:22:55 -07001413 // Configuration
1414
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001415 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001416
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001417 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001418 "touchscreen", "I");
1419
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001420 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001421 "keyboard", "I");
1422
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001423 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001424 "navigation", "I");
1425
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001426 return 0;
1427}
1428
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001429} /* namespace android */