blob: 270464754c30fabfb9bbe4ef9a95afe2ff74dc65 [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>
Jeff Browna6dbfdd2011-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 Brown86ea1f52011-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 Brown46b9ac02010-04-22 18:58:52 -070053
54namespace android {
55
Jeff Brown1a84fd12011-06-02 01:26:32 -070056// The exponent used to calculate the pointer speed scaling factor.
57// The scaling factor is calculated as 2 ^ (speed * exponent),
58// where the speed ranges from -7 to + 7 and is supplied by the user.
59static const float POINTER_SPEED_EXPONENT = 1.0f / 3;
60
Jeff Brown46b9ac02010-04-22 18:58:52 -070061static struct {
62 jclass clazz;
63
Jeff Brown46b9ac02010-04-22 18:58:52 -070064 jmethodID notifyConfigurationChanged;
65 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070066 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070067 jmethodID notifyANR;
Jeff Brown349703e2010-06-22 01:27:15 -070068 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080069 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070070 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070071 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070072 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070073 jmethodID filterTouchEvents;
74 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080075 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac02010-04-22 18:58:52 -070076 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080077 jmethodID getKeyRepeatTimeout;
78 jmethodID getKeyRepeatDelay;
Jeff Brownae9fc032010-08-18 15:51:08 -070079 jmethodID getMaxEventsPerSecond;
Jeff Brown214eaf42011-05-26 19:17:02 -070080 jmethodID getTapTimeout;
81 jmethodID getDoubleTapTimeout;
82 jmethodID getLongPressTimeout;
83 jmethodID getTouchSlop;
Jeff Brown83c09682010-12-23 17:50:18 -080084 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080085 jmethodID getPointerIcon;
Jeff Brown46b9ac02010-04-22 18:58:52 -070086} gCallbacksClassInfo;
87
88static struct {
89 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070090} gKeyEventClassInfo;
91
92static struct {
93 jclass clazz;
94} gMotionEventClassInfo;
95
Jeff Brown8d608662010-08-30 03:02:23 -070096static struct {
97 jclass clazz;
98
99 jmethodID ctor;
100 jmethodID addMotionRange;
101
102 jfieldID mId;
103 jfieldID mName;
104 jfieldID mSources;
105 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -0700106} gInputDeviceClassInfo;
107
Jeff Brown57c59372010-09-21 18:22:55 -0700108static struct {
109 jclass clazz;
110
111 jfieldID touchscreen;
112 jfieldID keyboard;
113 jfieldID navigation;
114} gConfigurationClassInfo;
115
Jeff Brown928e0542011-01-10 11:17:36 -0800116
117// --- Global functions ---
118
Jeff Brown214eaf42011-05-26 19:17:02 -0700119template<typename T>
120inline static T min(const T& a, const T& b) {
121 return a < b ? a : b;
122}
123
124template<typename T>
125inline static T max(const T& a, const T& b) {
126 return a > b ? a : b;
127}
128
Jeff Brown928e0542011-01-10 11:17:36 -0800129static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
130 const sp<InputApplicationHandle>& inputApplicationHandle) {
131 if (inputApplicationHandle == NULL) {
132 return NULL;
133 }
134 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
135 getInputApplicationHandleObjLocalRef(env);
136}
137
138static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
139 const sp<InputWindowHandle>& inputWindowHandle) {
140 if (inputWindowHandle == NULL) {
141 return NULL;
142 }
143 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
144 getInputWindowHandleObjLocalRef(env);
145}
146
Jeff Brown86ea1f52011-04-12 22:39:53 -0700147static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
148 SpriteIcon* outSpriteIcon) {
149 PointerIcon pointerIcon;
150 status_t status = android_view_PointerIcon_loadSystemIcon(env,
151 contextObj, style, &pointerIcon);
152 if (!status) {
153 pointerIcon.bitmap.copyTo(&outSpriteIcon->bitmap, SkBitmap::kARGB_8888_Config);
154 outSpriteIcon->hotSpotX = pointerIcon.hotSpotX;
155 outSpriteIcon->hotSpotY = pointerIcon.hotSpotY;
156 }
157}
158
Jeff Brown928e0542011-01-10 11:17:36 -0800159
160// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800161
Jeff Brown9c3cda02010-06-15 01:31:58 -0700162class NativeInputManager : public virtual RefBase,
163 public virtual InputReaderPolicyInterface,
Jeff Brown86ea1f52011-04-12 22:39:53 -0700164 public virtual InputDispatcherPolicyInterface,
165 public virtual PointerControllerPolicyInterface {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700166protected:
167 virtual ~NativeInputManager();
168
169public:
Jeff Brown86ea1f52011-04-12 22:39:53 -0700170 NativeInputManager(jobject contextObj, jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700171
172 inline sp<InputManager> getInputManager() const { return mInputManager; }
173
Jeff Brownb88102f2010-09-08 11:49:43 -0700174 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700175
Jeff Brown9c3cda02010-06-15 01:31:58 -0700176 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
177 void setDisplayOrientation(int32_t displayId, int32_t orientation);
178
Jeff Brown7fbdc842010-06-17 20:52:56 -0700179 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800180 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700181 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
182
Jeff Brown349703e2010-06-22 01:27:15 -0700183 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
184 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
185 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800186 void setSystemUiVisibility(int32_t visibility);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700187 void setPointerSpeed(int32_t speed);
Jeff Brown349703e2010-06-22 01:27:15 -0700188
Jeff Brown9c3cda02010-06-15 01:31:58 -0700189 /* --- InputReaderPolicyInterface implementation --- */
190
191 virtual bool getDisplayInfo(int32_t displayId,
192 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown214eaf42011-05-26 19:17:02 -0700193 virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);
Jeff Brown83c09682010-12-23 17:50:18 -0800194 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700195
196 /* --- InputDispatcherPolicyInterface implementation --- */
197
Jeff Browne20c9e02010-10-11 14:20:19 -0700198 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
199 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700200 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700201 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800202 const sp<InputWindowHandle>& inputWindowHandle);
203 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown214eaf42011-05-26 19:17:02 -0700204 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
205 virtual bool isKeyRepeatEnabled();
Jeff Brown1f245102010-11-18 20:53:46 -0800206 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800207 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800208 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700209 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800210 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800211 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700212 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700213 virtual bool checkInjectEventsPermissionNonReentrant(
214 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700215
Jeff Brown86ea1f52011-04-12 22:39:53 -0700216 /* --- PointerControllerPolicyInterface implementation --- */
217
218 virtual void loadPointerResources(PointerResources* outResources);
219
Jeff Brown9c3cda02010-06-15 01:31:58 -0700220private:
221 sp<InputManager> mInputManager;
222
Jeff Brown86ea1f52011-04-12 22:39:53 -0700223 jobject mContextObj;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700224 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800225 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700226
Jeff Brown83c09682010-12-23 17:50:18 -0800227 Mutex mLock;
228 struct Locked {
229 // Display size information.
230 int32_t displayWidth, displayHeight; // -1 when initialized
231 int32_t displayOrientation;
232
Jeff Brown05dc66a2011-03-02 14:41:58 -0800233 // System UI visibility.
234 int32_t systemUiVisibility;
235
Jeff Brown1a84fd12011-06-02 01:26:32 -0700236 // Pointer speed.
237 int32_t pointerSpeed;
238
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700239 // Sprite controller singleton, created on first use.
240 sp<SpriteController> spriteController;
241
Jeff Brown83c09682010-12-23 17:50:18 -0800242 // Pointer controller singleton, created and destroyed as needed.
243 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800244 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700245
Jeff Brown86ea1f52011-04-12 22:39:53 -0700246 void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800247 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700248 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800249
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700250 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700251 bool isScreenOn();
252 bool isScreenBright();
253
Jeff Brownb88102f2010-09-08 11:49:43 -0700254 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700255
Jeff Brown9c3cda02010-06-15 01:31:58 -0700256 static inline JNIEnv* jniEnv() {
257 return AndroidRuntime::getJNIEnv();
258 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700259};
260
Jeff Brown928e0542011-01-10 11:17:36 -0800261
Jeff Brown9c3cda02010-06-15 01:31:58 -0700262
Jeff Brown86ea1f52011-04-12 22:39:53 -0700263NativeInputManager::NativeInputManager(jobject contextObj,
264 jobject callbacksObj, const sp<Looper>& looper) :
Jeff Brown214eaf42011-05-26 19:17:02 -0700265 mLooper(looper) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700266 JNIEnv* env = jniEnv();
267
Jeff Brown86ea1f52011-04-12 22:39:53 -0700268 mContextObj = env->NewGlobalRef(contextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700269 mCallbacksObj = env->NewGlobalRef(callbacksObj);
270
Jeff Brown83c09682010-12-23 17:50:18 -0800271 {
272 AutoMutex _l(mLock);
273 mLocked.displayWidth = -1;
274 mLocked.displayHeight = -1;
275 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800276
277 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700278 mLocked.pointerSpeed = 0;
Jeff Brown83c09682010-12-23 17:50:18 -0800279 }
280
Jeff Brown9c3cda02010-06-15 01:31:58 -0700281 sp<EventHub> eventHub = new EventHub();
282 mInputManager = new InputManager(eventHub, this, this);
283}
284
285NativeInputManager::~NativeInputManager() {
286 JNIEnv* env = jniEnv();
287
Jeff Brown86ea1f52011-04-12 22:39:53 -0700288 env->DeleteGlobalRef(mContextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700289 env->DeleteGlobalRef(mCallbacksObj);
290}
291
Jeff Brownb88102f2010-09-08 11:49:43 -0700292void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700293 mInputManager->getReader()->dump(dump);
294 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700295
Jeff Brownb88102f2010-09-08 11:49:43 -0700296 mInputManager->getDispatcher()->dump(dump);
297 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700298}
299
Jeff Brown7fbdc842010-06-17 20:52:56 -0700300bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700301 if (env->ExceptionCheck()) {
302 LOGE("An exception was thrown by callback '%s'.", methodName);
303 LOGE_EX(env);
304 env->ExceptionClear();
305 return true;
306 }
307 return false;
308}
309
310void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
311 if (displayId == 0) {
Jeff Brown86ea1f52011-04-12 22:39:53 -0700312 { // acquire lock
313 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700314
Jeff Brown86ea1f52011-04-12 22:39:53 -0700315 if (mLocked.displayWidth == width && mLocked.displayHeight == height) {
316 return;
317 }
318
Jeff Brown83c09682010-12-23 17:50:18 -0800319 mLocked.displayWidth = width;
320 mLocked.displayHeight = height;
321
322 sp<PointerController> controller = mLocked.pointerController.promote();
323 if (controller != NULL) {
324 controller->setDisplaySize(width, height);
325 }
Jeff Brown86ea1f52011-04-12 22:39:53 -0700326 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700327 }
328}
329
330void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
331 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800332 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700333
Jeff Brown83c09682010-12-23 17:50:18 -0800334 if (mLocked.displayOrientation != orientation) {
335 mLocked.displayOrientation = orientation;
336
337 sp<PointerController> controller = mLocked.pointerController.promote();
338 if (controller != NULL) {
339 controller->setDisplayOrientation(orientation);
340 }
341 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700342 }
343}
344
Jeff Brown7fbdc842010-06-17 20:52:56 -0700345status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800346 const sp<InputChannel>& inputChannel,
347 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
348 return mInputManager->getDispatcher()->registerInputChannel(
349 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700350}
351
352status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
353 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700354 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700355}
356
Jeff Brown9c3cda02010-06-15 01:31:58 -0700357bool NativeInputManager::getDisplayInfo(int32_t displayId,
358 int32_t* width, int32_t* height, int32_t* orientation) {
359 bool result = false;
360 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800361 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700362
Jeff Brown83c09682010-12-23 17:50:18 -0800363 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700364 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800365 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700366 }
367 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800368 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700369 }
370 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800371 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700372 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700373 result = true;
374 }
375 }
376 return result;
377}
378
Jeff Brown214eaf42011-05-26 19:17:02 -0700379void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700380 JNIEnv* env = jniEnv();
381
Jeff Brown214eaf42011-05-26 19:17:02 -0700382 jboolean filterTouchEvents = env->CallBooleanMethod(mCallbacksObj,
383 gCallbacksClassInfo.filterTouchEvents);
384 if (!checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
385 outConfig->filterTouchEvents = filterTouchEvents;
386 }
387
388 jboolean filterJumpyTouchEvents = env->CallBooleanMethod(mCallbacksObj,
389 gCallbacksClassInfo.filterJumpyTouchEvents);
390 if (!checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
391 outConfig->filterJumpyTouchEvents = filterJumpyTouchEvents;
392 }
393
394 jint virtualKeyQuietTime = env->CallIntMethod(mCallbacksObj,
395 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
396 if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
397 outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
398 }
399
400 outConfig->excludedDeviceNames.clear();
401 jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mCallbacksObj,
Jeff Brown9c3cda02010-06-15 01:31:58 -0700402 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown214eaf42011-05-26 19:17:02 -0700403 if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
404 jsize length = env->GetArrayLength(excludedDeviceNames);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700405 for (jsize i = 0; i < length; i++) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700406 jstring item = jstring(env->GetObjectArrayElement(excludedDeviceNames, i));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700407 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
Jeff Brown214eaf42011-05-26 19:17:02 -0700408 outConfig->excludedDeviceNames.add(String8(deviceNameChars));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700409 env->ReleaseStringUTFChars(item, deviceNameChars);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700410 env->DeleteLocalRef(item);
411 }
Jeff Brown214eaf42011-05-26 19:17:02 -0700412 env->DeleteLocalRef(excludedDeviceNames);
413 }
414
415 jint tapTimeout = env->CallIntMethod(mCallbacksObj,
416 gCallbacksClassInfo.getTapTimeout);
417 if (!checkAndClearExceptionFromCallback(env, "getTapTimeout")) {
418 jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
419 gCallbacksClassInfo.getDoubleTapTimeout);
420 if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
421 jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
422 gCallbacksClassInfo.getLongPressTimeout);
423 if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
424 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(tapTimeout);
425
426 // We must ensure that the tap-drag interval is significantly shorter than
427 // the long-press timeout because the tap is held down for the entire duration
428 // of the double-tap timeout.
429 jint tapDragInterval = max(min(longPressTimeout - 100,
430 doubleTapTimeout), tapTimeout);
431 outConfig->pointerGestureTapDragInterval =
432 milliseconds_to_nanoseconds(tapDragInterval);
433 }
434 }
435 }
436
437 jint touchSlop = env->CallIntMethod(mCallbacksObj,
438 gCallbacksClassInfo.getTouchSlop);
439 if (!checkAndClearExceptionFromCallback(env, "getTouchSlop")) {
440 outConfig->pointerGestureTapSlop = touchSlop;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700441 }
Jeff Brown1a84fd12011-06-02 01:26:32 -0700442
443 { // acquire lock
444 AutoMutex _l(mLock);
445
446 outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
447 * POINTER_SPEED_EXPONENT);
448 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700449}
450
Jeff Brown83c09682010-12-23 17:50:18 -0800451sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
452 AutoMutex _l(mLock);
453
454 sp<PointerController> controller = mLocked.pointerController.promote();
455 if (controller == NULL) {
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700456 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800457
Jeff Brown86ea1f52011-04-12 22:39:53 -0700458 controller = new PointerController(this, mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800459 mLocked.pointerController = controller;
460
461 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
462 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800463
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700464 JNIEnv* env = jniEnv();
Jeff Brown86ea1f52011-04-12 22:39:53 -0700465 jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
466 gCallbacksClassInfo.getPointerIcon);
467 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
468 PointerIcon pointerIcon;
469 status_t status = android_view_PointerIcon_load(env, pointerIconObj,
470 mContextObj, &pointerIcon);
471 if (!status && !pointerIcon.isNullIcon()) {
472 controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
473 pointerIcon.hotSpotX, pointerIcon.hotSpotY));
474 } else {
475 controller->setPointerIcon(SpriteIcon());
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800476 }
Jeff Brown86ea1f52011-04-12 22:39:53 -0700477 env->DeleteLocalRef(pointerIconObj);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800478 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800479
Jeff Brown86ea1f52011-04-12 22:39:53 -0700480 updateInactivityTimeoutLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800481 }
482 return controller;
483}
484
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700485void NativeInputManager::ensureSpriteControllerLocked() {
486 if (mLocked.spriteController == NULL) {
487 JNIEnv* env = jniEnv();
488 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
489 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
490 layer = -1;
491 }
492 mLocked.spriteController = new SpriteController(mLooper, layer);
493 }
494}
495
Jeff Browne20c9e02010-10-11 14:20:19 -0700496void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
497 int32_t switchValue, uint32_t policyFlags) {
498#if DEBUG_INPUT_DISPATCHER_POLICY
499 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
500 when, switchCode, switchValue, policyFlags);
501#endif
502
503 JNIEnv* env = jniEnv();
504
505 switch (switchCode) {
506 case SW_LID:
507 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
508 when, switchValue == 0);
509 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
510 break;
511 }
512}
513
Jeff Brown9c3cda02010-06-15 01:31:58 -0700514void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
515#if DEBUG_INPUT_DISPATCHER_POLICY
516 LOGD("notifyConfigurationChanged - when=%lld", when);
517#endif
518
519 JNIEnv* env = jniEnv();
520
Jeff Brown57c59372010-09-21 18:22:55 -0700521 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700522 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700523}
524
Jeff Brown519e0242010-09-15 15:18:56 -0700525nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800526 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700527#if DEBUG_INPUT_DISPATCHER_POLICY
528 LOGD("notifyANR");
529#endif
530
531 JNIEnv* env = jniEnv();
532
Jeff Brown928e0542011-01-10 11:17:36 -0800533 jobject inputApplicationHandleObj =
534 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
535 jobject inputWindowHandleObj =
536 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700537
Jeff Brown519e0242010-09-15 15:18:56 -0700538 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800539 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700540 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
541 newTimeout = 0; // abort dispatch
542 } else {
543 assert(newTimeout >= 0);
544 }
545
Jeff Brown928e0542011-01-10 11:17:36 -0800546 env->DeleteLocalRef(inputWindowHandleObj);
547 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700548 return newTimeout;
549}
550
Jeff Brown928e0542011-01-10 11:17:36 -0800551void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700552#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800553 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700554#endif
555
Jeff Brown7fbdc842010-06-17 20:52:56 -0700556 JNIEnv* env = jniEnv();
557
Jeff Brown928e0542011-01-10 11:17:36 -0800558 jobject inputWindowHandleObj =
559 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
560 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700561 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800562 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700563 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
564
Jeff Brown928e0542011-01-10 11:17:36 -0800565 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700566 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700567}
568
Jeff Brown214eaf42011-05-26 19:17:02 -0700569void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
570 JNIEnv* env = jniEnv();
Jeff Browna4547672011-03-02 21:38:11 -0800571
Jeff Brown214eaf42011-05-26 19:17:02 -0700572 jint keyRepeatTimeout = env->CallIntMethod(mCallbacksObj,
573 gCallbacksClassInfo.getKeyRepeatTimeout);
574 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
575 outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
576 }
Jeff Browna4547672011-03-02 21:38:11 -0800577
Jeff Brown214eaf42011-05-26 19:17:02 -0700578 jint keyRepeatDelay = env->CallIntMethod(mCallbacksObj,
579 gCallbacksClassInfo.getKeyRepeatDelay);
580 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
581 outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
582 }
583
584 jint maxEventsPerSecond = env->CallIntMethod(mCallbacksObj,
585 gCallbacksClassInfo.getMaxEventsPerSecond);
586 if (!checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
587 outConfig->maxEventsPerSecond = maxEventsPerSecond;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700588 }
589}
590
Jeff Brown214eaf42011-05-26 19:17:02 -0700591bool NativeInputManager::isKeyRepeatEnabled() {
592 // Only enable automatic key repeating when the screen is on.
593 return isScreenOn();
Jeff Brownae9fc032010-08-18 15:51:08 -0700594}
595
Jeff Brown349703e2010-06-22 01:27:15 -0700596void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700597 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700598
Jeff Brownb88102f2010-09-08 11:49:43 -0700599 jsize length = env->GetArrayLength(windowObjArray);
600 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800601 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
602 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700603 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700604 }
605
Jeff Brownb88102f2010-09-08 11:49:43 -0700606 windows.push();
607 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800608 android_server_InputWindow_toNative(env, windowObj, &window);
609 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700610 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700611 }
Jeff Brown928e0542011-01-10 11:17:36 -0800612 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700613 }
Jeff Brown349703e2010-06-22 01:27:15 -0700614
Jeff Brownb88102f2010-09-08 11:49:43 -0700615 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700616}
617
Jeff Brown349703e2010-06-22 01:27:15 -0700618void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700619 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700620 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800621 android_server_InputApplication_toNative(env, applicationObj, &application);
622 if (application.inputApplicationHandle != NULL) {
623 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Brown22d789d2011-03-25 11:58:46 -0700624 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800625 }
Jeff Brown349703e2010-06-22 01:27:15 -0700626 }
Jeff Brown928e0542011-01-10 11:17:36 -0800627 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700628}
629
630void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700631 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700632}
633
Jeff Brown05dc66a2011-03-02 14:41:58 -0800634void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
635 AutoMutex _l(mLock);
636
637 if (mLocked.systemUiVisibility != visibility) {
638 mLocked.systemUiVisibility = visibility;
639
640 sp<PointerController> controller = mLocked.pointerController.promote();
641 if (controller != NULL) {
Jeff Brown86ea1f52011-04-12 22:39:53 -0700642 updateInactivityTimeoutLocked(controller);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800643 }
644 }
645}
646
Jeff Brown86ea1f52011-04-12 22:39:53 -0700647void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800648 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
Jeff Brown86ea1f52011-04-12 22:39:53 -0700649 controller->setInactivityTimeout(lightsOut
650 ? PointerController::INACTIVITY_TIMEOUT_SHORT
651 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800652}
653
Jeff Brown1a84fd12011-06-02 01:26:32 -0700654void NativeInputManager::setPointerSpeed(int32_t speed) {
655 AutoMutex _l(mLock);
656
657 if (mLocked.pointerSpeed != speed) {
658 LOGI("Setting pointer speed to %d.", speed);
659 mLocked.pointerSpeed = speed;
660
661 mInputManager->getReader()->refreshConfiguration();
662 }
663}
664
Jeff Browne20c9e02010-10-11 14:20:19 -0700665bool NativeInputManager::isScreenOn() {
666 return android_server_PowerManagerService_isScreenOn();
667}
668
669bool NativeInputManager::isScreenBright() {
670 return android_server_PowerManagerService_isScreenBright();
671}
672
Jeff Brown1f245102010-11-18 20:53:46 -0800673void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
674 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700675 // Policy:
676 // - Ignore untrusted events and pass them along.
677 // - Ask the window manager what to do with normal events and trusted injected events.
678 // - For normal events wake and brighten the screen if currently off or dim.
679 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800680 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700681 bool isScreenOn = this->isScreenOn();
682 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700683
Jeff Brown3122e442010-10-11 23:32:49 -0700684 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800685 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
686 jint wmActions;
687 if (keyEventObj) {
688 wmActions = env->CallIntMethod(mCallbacksObj,
689 gCallbacksClassInfo.interceptKeyBeforeQueueing,
690 keyEventObj, policyFlags, isScreenOn);
691 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
692 wmActions = 0;
693 }
694 android_view_KeyEvent_recycle(env, keyEventObj);
695 env->DeleteLocalRef(keyEventObj);
696 } else {
697 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700698 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700699 }
700
Jeff Brown1f245102010-11-18 20:53:46 -0800701 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700702 if (!isScreenOn) {
703 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700704 }
705
706 if (!isScreenBright) {
707 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
708 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700709 }
710
Jeff Brown56194eb2011-03-02 19:23:13 -0800711 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700712 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700713 policyFlags |= POLICY_FLAG_PASS_TO_USER;
714 }
715}
716
Jeff Brown56194eb2011-03-02 19:23:13 -0800717void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700718 // Policy:
719 // - Ignore untrusted events and pass them along.
720 // - No special filtering for injected events required at this time.
721 // - Filter normal events based on screen state.
722 // - For normal events brighten (but do not wake) the screen if currently dim.
723 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
724 if (isScreenOn()) {
725 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700726
Jeff Brown3122e442010-10-11 23:32:49 -0700727 if (!isScreenBright()) {
728 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
729 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800730 } else {
731 JNIEnv* env = jniEnv();
732 jint wmActions = env->CallIntMethod(mCallbacksObj,
733 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
734 policyFlags);
735 if (checkAndClearExceptionFromCallback(env,
736 "interceptMotionBeforeQueueingWhenScreenOff")) {
737 wmActions = 0;
738 }
739
740 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
741 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700742 }
Jeff Brown3122e442010-10-11 23:32:49 -0700743 } else {
744 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700745 }
746}
747
Jeff Brown56194eb2011-03-02 19:23:13 -0800748void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
749 uint32_t& policyFlags) {
750 enum {
751 WM_ACTION_PASS_TO_USER = 1,
752 WM_ACTION_POKE_USER_ACTIVITY = 2,
753 WM_ACTION_GO_TO_SLEEP = 4,
754 };
755
756 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800757#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800758 LOGD("handleInterceptActions: Going to sleep.");
759#endif
760 android_server_PowerManagerService_goToSleep(when);
761 }
762
763 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800764#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800765 LOGD("handleInterceptActions: Poking user activity.");
766#endif
767 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
768 }
769
770 if (wmActions & WM_ACTION_PASS_TO_USER) {
771 policyFlags |= POLICY_FLAG_PASS_TO_USER;
772 } else {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800773#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800774 LOGD("handleInterceptActions: Not passing key to user.");
775#endif
776 }
777}
778
Jeff Brown928e0542011-01-10 11:17:36 -0800779bool NativeInputManager::interceptKeyBeforeDispatching(
780 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700781 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700782 // Policy:
783 // - Ignore untrusted events and pass them along.
784 // - Filter normal events and trusted injected events through the window manager policy to
785 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800786 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700787 if (policyFlags & POLICY_FLAG_TRUSTED) {
788 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700789
Jeff Brown928e0542011-01-10 11:17:36 -0800790 // Note: inputWindowHandle may be null.
791 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800792 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
793 if (keyEventObj) {
794 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
795 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800796 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800797 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
798 android_view_KeyEvent_recycle(env, keyEventObj);
799 env->DeleteLocalRef(keyEventObj);
800 result = consumed && !error;
801 } else {
802 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800803 }
Jeff Brown928e0542011-01-10 11:17:36 -0800804 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700805 }
Jeff Brown1f245102010-11-18 20:53:46 -0800806 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700807}
808
Jeff Brown928e0542011-01-10 11:17:36 -0800809bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800810 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700811 // Policy:
812 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800813 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700814 if (policyFlags & POLICY_FLAG_TRUSTED) {
815 JNIEnv* env = jniEnv();
816
Jeff Brown928e0542011-01-10 11:17:36 -0800817 // Note: inputWindowHandle may be null.
818 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800819 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
820 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800821 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800822 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800823 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown524ee642011-03-29 15:11:34 -0700824 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
825 fallbackKeyEventObj = NULL;
826 }
Jeff Brown1f245102010-11-18 20:53:46 -0800827 android_view_KeyEvent_recycle(env, keyEventObj);
828 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800829
830 if (fallbackKeyEventObj) {
831 // Note: outFallbackKeyEvent may be the same object as keyEvent.
832 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
833 outFallbackKeyEvent)) {
834 result = true;
835 }
836 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
837 env->DeleteLocalRef(fallbackKeyEventObj);
838 }
Jeff Brown1f245102010-11-18 20:53:46 -0800839 } else {
840 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800841 }
Jeff Brown928e0542011-01-10 11:17:36 -0800842 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700843 }
Jeff Brown1f245102010-11-18 20:53:46 -0800844 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700845}
846
Jeff Brown01ce2e92010-09-26 22:20:12 -0700847void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
848 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700849}
850
Jeff Brown349703e2010-06-22 01:27:15 -0700851
Jeff Brownb88102f2010-09-08 11:49:43 -0700852bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
853 int32_t injectorPid, int32_t injectorUid) {
854 JNIEnv* env = jniEnv();
855 jboolean result = env->CallBooleanMethod(mCallbacksObj,
856 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brown524ee642011-03-29 15:11:34 -0700857 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
858 result = false;
859 }
Jeff Brown349703e2010-06-22 01:27:15 -0700860 return result;
861}
862
Jeff Brown86ea1f52011-04-12 22:39:53 -0700863void NativeInputManager::loadPointerResources(PointerResources* outResources) {
864 JNIEnv* env = jniEnv();
865
866 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER,
867 &outResources->spotHover);
868 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH,
869 &outResources->spotTouch);
870 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR,
871 &outResources->spotAnchor);
872}
873
Jeff Brown83c09682010-12-23 17:50:18 -0800874
Jeff Brown9c3cda02010-06-15 01:31:58 -0700875// ----------------------------------------------------------------------------
876
877static sp<NativeInputManager> gNativeInputManager;
878
Jeff Brown46b9ac02010-04-22 18:58:52 -0700879static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700880 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700881 LOGE("Input manager not initialized.");
882 jniThrowRuntimeException(env, "Input manager not initialized.");
883 return true;
884 }
885 return false;
886}
887
888static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown86ea1f52011-04-12 22:39:53 -0700889 jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700890 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800891 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
Jeff Brown86ea1f52011-04-12 22:39:53 -0700892 gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700893 } else {
894 LOGE("Input manager already initialized.");
895 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700896 }
897}
898
899static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
900 if (checkInputManagerUnitialized(env)) {
901 return;
902 }
903
Jeff Brown9c3cda02010-06-15 01:31:58 -0700904 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700905 if (result) {
906 jniThrowRuntimeException(env, "Input manager could not be started.");
907 }
908}
909
910static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
911 jint displayId, jint width, jint height) {
912 if (checkInputManagerUnitialized(env)) {
913 return;
914 }
915
916 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
917 // to be passed in like this, not sure which is better but leaving it like this
918 // keeps the window manager in direct control of when display transitions propagate down
919 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700920 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700921}
922
923static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
924 jint displayId, jint orientation) {
925 if (checkInputManagerUnitialized(env)) {
926 return;
927 }
928
Jeff Brown9c3cda02010-06-15 01:31:58 -0700929 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700930}
931
932static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700933 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700934 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700935 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700936 }
937
Jeff Brownb88102f2010-09-08 11:49:43 -0700938 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700939 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700940}
941
942static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700943 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700944 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700945 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700946 }
947
Jeff Brownb88102f2010-09-08 11:49:43 -0700948 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700949 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700950}
951
952static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700953 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700954 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700955 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700956 }
957
Jeff Brownb88102f2010-09-08 11:49:43 -0700958 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700959 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700960}
961
962static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700963 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700964 if (checkInputManagerUnitialized(env)) {
965 return JNI_FALSE;
966 }
967
968 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
969 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
970 jsize numCodes = env->GetArrayLength(keyCodes);
971 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700972 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700973 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700974 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700975 } else {
976 result = JNI_FALSE;
977 }
978
979 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
980 env->ReleaseIntArrayElements(keyCodes, codes, 0);
981 return result;
982}
983
984static void throwInputChannelNotInitialized(JNIEnv* env) {
985 jniThrowException(env, "java/lang/IllegalStateException",
986 "inputChannel is not initialized");
987}
988
989static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
990 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
991 LOGW("Input channel object '%s' was disposed without first being unregistered with "
992 "the input manager!", inputChannel->getName().string());
993
Jeff Brown9c3cda02010-06-15 01:31:58 -0700994 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700995 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700996 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700997}
998
999static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001000 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001001 if (checkInputManagerUnitialized(env)) {
1002 return;
1003 }
1004
1005 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1006 inputChannelObj);
1007 if (inputChannel == NULL) {
1008 throwInputChannelNotInitialized(env);
1009 return;
1010 }
1011
Jeff Brown928e0542011-01-10 11:17:36 -08001012 sp<InputWindowHandle> inputWindowHandle =
1013 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001014
1015 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001016 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001017 if (status) {
1018 jniThrowRuntimeException(env, "Failed to register input channel. "
1019 "Check logs for details.");
1020 return;
1021 }
1022
Jeff Browna41ca772010-08-11 14:46:32 -07001023 if (! monitor) {
1024 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1025 android_server_InputManager_handleInputChannelDisposed, NULL);
1026 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001027}
1028
1029static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1030 jobject inputChannelObj) {
1031 if (checkInputManagerUnitialized(env)) {
1032 return;
1033 }
1034
1035 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1036 inputChannelObj);
1037 if (inputChannel == NULL) {
1038 throwInputChannelNotInitialized(env);
1039 return;
1040 }
1041
1042 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1043
Jeff Brown7fbdc842010-06-17 20:52:56 -07001044 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001045 if (status) {
1046 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1047 "Check logs for details.");
1048 }
1049}
1050
Jeff Brown6ec402b2010-07-28 15:48:59 -07001051static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1052 jobject inputEventObj, jint injectorPid, jint injectorUid,
1053 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001054 if (checkInputManagerUnitialized(env)) {
1055 return INPUT_EVENT_INJECTION_FAILED;
1056 }
1057
Jeff Brown6ec402b2010-07-28 15:48:59 -07001058 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1059 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001060 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1061 if (status) {
1062 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1063 return INPUT_EVENT_INJECTION_FAILED;
1064 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001065
Jeff Brownb88102f2010-09-08 11:49:43 -07001066 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1067 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001068 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown5b2b4d92011-03-14 19:39:54 -07001069 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1070 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001071 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1072 return INPUT_EVENT_INJECTION_FAILED;
1073 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001074
Jeff Brownb88102f2010-09-08 11:49:43 -07001075 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown5b2b4d92011-03-14 19:39:54 -07001076 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001077 } else {
1078 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001079 return INPUT_EVENT_INJECTION_FAILED;
1080 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001081}
1082
Jeff Brown349703e2010-06-22 01:27:15 -07001083static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1084 jobjectArray windowObjArray) {
1085 if (checkInputManagerUnitialized(env)) {
1086 return;
1087 }
1088
1089 gNativeInputManager->setInputWindows(env, windowObjArray);
1090}
1091
1092static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1093 jobject applicationObj) {
1094 if (checkInputManagerUnitialized(env)) {
1095 return;
1096 }
1097
1098 gNativeInputManager->setFocusedApplication(env, applicationObj);
1099}
1100
1101static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1102 jclass clazz, jboolean enabled, jboolean frozen) {
1103 if (checkInputManagerUnitialized(env)) {
1104 return;
1105 }
1106
1107 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1108}
1109
Jeff Brown05dc66a2011-03-02 14:41:58 -08001110static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1111 jclass clazz, jint visibility) {
1112 if (checkInputManagerUnitialized(env)) {
1113 return;
1114 }
1115
1116 gNativeInputManager->setSystemUiVisibility(visibility);
1117}
1118
Jeff Brown8d608662010-08-30 03:02:23 -07001119static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1120 jclass clazz, jint deviceId) {
1121 if (checkInputManagerUnitialized(env)) {
1122 return NULL;
1123 }
1124
1125 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001126 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001127 deviceId, & deviceInfo);
1128 if (status) {
1129 return NULL;
1130 }
1131
1132 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1133 if (! deviceObj) {
1134 return NULL;
1135 }
1136
1137 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1138 if (! deviceNameObj) {
1139 return NULL;
1140 }
1141
1142 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1143 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1144 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1145 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1146
Jeff Brownefd32662011-03-08 15:13:06 -08001147 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001148 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001149 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001150 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001151 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001152 if (env->ExceptionCheck()) {
1153 return NULL;
1154 }
1155 }
1156
1157 return deviceObj;
1158}
1159
1160static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1161 jclass clazz) {
1162 if (checkInputManagerUnitialized(env)) {
1163 return NULL;
1164 }
1165
1166 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001167 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001168
1169 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1170 if (! deviceIdsObj) {
1171 return NULL;
1172 }
1173
1174 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1175 return deviceIdsObj;
1176}
1177
Jeff Brown57c59372010-09-21 18:22:55 -07001178static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1179 jclass clazz, jobject configObj) {
1180 if (checkInputManagerUnitialized(env)) {
1181 return;
1182 }
1183
1184 InputConfiguration config;
1185 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1186
1187 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1188 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1189 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1190}
1191
Jeff Browne6504122010-09-27 14:52:15 -07001192static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1193 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1194 if (checkInputManagerUnitialized(env)) {
1195 return false;
1196 }
1197
1198 sp<InputChannel> fromChannel =
1199 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1200 sp<InputChannel> toChannel =
1201 android_view_InputChannel_getInputChannel(env, toChannelObj);
1202
1203 if (fromChannel == NULL || toChannel == NULL) {
1204 return false;
1205 }
1206
1207 return gNativeInputManager->getInputManager()->getDispatcher()->
1208 transferTouchFocus(fromChannel, toChannel);
1209}
1210
Jeff Brown1a84fd12011-06-02 01:26:32 -07001211static void android_server_InputManager_nativeSetPointerSpeed(JNIEnv* env,
1212 jclass clazz, jint speed) {
1213 if (checkInputManagerUnitialized(env)) {
1214 return;
1215 }
1216
1217 gNativeInputManager->setPointerSpeed(speed);
1218}
1219
Jeff Browne33348b2010-07-15 23:54:05 -07001220static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1221 if (checkInputManagerUnitialized(env)) {
1222 return NULL;
1223 }
1224
Jeff Brownb88102f2010-09-08 11:49:43 -07001225 String8 dump;
1226 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001227 return env->NewStringUTF(dump.string());
1228}
1229
Jeff Brown9c3cda02010-06-15 01:31:58 -07001230// ----------------------------------------------------------------------------
1231
Jeff Brown46b9ac02010-04-22 18:58:52 -07001232static JNINativeMethod gInputManagerMethods[] = {
1233 /* name, signature, funcPtr */
Jeff Brown86ea1f52011-04-12 22:39:53 -07001234 { "nativeInit", "(Landroid/content/Context;"
1235 "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001236 (void*) android_server_InputManager_nativeInit },
1237 { "nativeStart", "()V",
1238 (void*) android_server_InputManager_nativeStart },
1239 { "nativeSetDisplaySize", "(III)V",
1240 (void*) android_server_InputManager_nativeSetDisplaySize },
1241 { "nativeSetDisplayOrientation", "(II)V",
1242 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1243 { "nativeGetScanCodeState", "(III)I",
1244 (void*) android_server_InputManager_nativeGetScanCodeState },
1245 { "nativeGetKeyCodeState", "(III)I",
1246 (void*) android_server_InputManager_nativeGetKeyCodeState },
1247 { "nativeGetSwitchState", "(III)I",
1248 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001249 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001250 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001251 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001252 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001253 (void*) android_server_InputManager_nativeRegisterInputChannel },
1254 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001255 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001256 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1257 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001258 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001259 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001260 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001261 (void*) android_server_InputManager_nativeSetFocusedApplication },
1262 { "nativeSetInputDispatchMode", "(ZZ)V",
1263 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001264 { "nativeSetSystemUiVisibility", "(I)V",
1265 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001266 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1267 (void*) android_server_InputManager_nativeGetInputDevice },
1268 { "nativeGetInputDeviceIds", "()[I",
1269 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001270 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1271 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001272 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1273 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Brown1a84fd12011-06-02 01:26:32 -07001274 { "nativeSetPointerSpeed", "(I)V",
1275 (void*) android_server_InputManager_nativeSetPointerSpeed },
Jeff Browne33348b2010-07-15 23:54:05 -07001276 { "nativeDump", "()Ljava/lang/String;",
1277 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001278};
1279
1280#define FIND_CLASS(var, className) \
1281 var = env->FindClass(className); \
1282 LOG_FATAL_IF(! var, "Unable to find class " className); \
1283 var = jclass(env->NewGlobalRef(var));
1284
1285#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1286 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1287 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1288
1289#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1290 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1291 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1292
1293int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001294 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001295 gInputManagerMethods, NELEM(gInputManagerMethods));
1296 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1297
Jeff Brown9c3cda02010-06-15 01:31:58 -07001298 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001299
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001300 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001301
Jeff Brown46b9ac02010-04-22 18:58:52 -07001302 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001303 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001304
1305 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1306 "notifyLidSwitchChanged", "(JZ)V");
1307
Jeff Brown7fbdc842010-06-17 20:52:56 -07001308 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001309 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001310
Jeff Brown349703e2010-06-22 01:27:15 -07001311 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001312 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001313 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001314
Jeff Brown349703e2010-06-22 01:27:15 -07001315 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001316 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001317
Jeff Brown56194eb2011-03-02 19:23:13 -08001318 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
1319 gCallbacksClassInfo.clazz,
1320 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1321
Jeff Brown349703e2010-06-22 01:27:15 -07001322 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001323 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001324 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001325
Jeff Brown3915bb82010-11-05 15:02:16 -07001326 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001327 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001328 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001329
Jeff Brown349703e2010-06-22 01:27:15 -07001330 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1331 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001332
Jeff Brown46b9ac02010-04-22 18:58:52 -07001333 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1334 "filterTouchEvents", "()Z");
1335
1336 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1337 "filterJumpyTouchEvents", "()Z");
1338
Jeff Brownfe508922011-01-18 15:10:10 -08001339 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
1340 "getVirtualKeyQuietTimeMillis", "()I");
1341
Jeff Brown46b9ac02010-04-22 18:58:52 -07001342 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1343 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1344
Jeff Browna4547672011-03-02 21:38:11 -08001345 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, gCallbacksClassInfo.clazz,
1346 "getKeyRepeatTimeout", "()I");
1347
1348 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, gCallbacksClassInfo.clazz,
1349 "getKeyRepeatDelay", "()I");
1350
Jeff Brown214eaf42011-05-26 19:17:02 -07001351 GET_METHOD_ID(gCallbacksClassInfo.getTapTimeout, gCallbacksClassInfo.clazz,
1352 "getTapTimeout", "()I");
1353
1354 GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, gCallbacksClassInfo.clazz,
1355 "getDoubleTapTimeout", "()I");
1356
1357 GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, gCallbacksClassInfo.clazz,
1358 "getLongPressTimeout", "()I");
1359
1360 GET_METHOD_ID(gCallbacksClassInfo.getTouchSlop, gCallbacksClassInfo.clazz,
1361 "getTouchSlop", "()I");
1362
Jeff Brownae9fc032010-08-18 15:51:08 -07001363 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1364 "getMaxEventsPerSecond", "()I");
1365
Jeff Brown83c09682010-12-23 17:50:18 -08001366 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, gCallbacksClassInfo.clazz,
1367 "getPointerLayer", "()I");
1368
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001369 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, gCallbacksClassInfo.clazz,
Jeff Brown86ea1f52011-04-12 22:39:53 -07001370 "getPointerIcon", "()Landroid/view/PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001371
Jeff Brown6ec402b2010-07-28 15:48:59 -07001372 // KeyEvent
1373
1374 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1375
Jeff Brown8d608662010-08-30 03:02:23 -07001376 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001377
1378 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1379
Jeff Brown8d608662010-08-30 03:02:23 -07001380 // InputDevice
1381
1382 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1383
1384 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1385 "<init>", "()V");
1386
1387 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001388 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001389
1390 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1391 "mId", "I");
1392
1393 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1394 "mName", "Ljava/lang/String;");
1395
1396 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1397 "mSources", "I");
1398
1399 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1400 "mKeyboardType", "I");
1401
Jeff Brown57c59372010-09-21 18:22:55 -07001402 // Configuration
1403
1404 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1405
1406 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1407 "touchscreen", "I");
1408
1409 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1410 "keyboard", "I");
1411
1412 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1413 "navigation", "I");
1414
Jeff Brown46b9ac02010-04-22 18:58:52 -07001415 return 0;
1416}
1417
Jeff Brown46b9ac02010-04-22 18:58:52 -07001418} /* namespace android */