blob: dde47765357275aafc35049991395f9a3e43346d [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 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 Brown46b9ac0a2010-04-22 18:58:52 -070053
54namespace android {
55
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070056static struct {
57 jclass clazz;
58
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070059 jmethodID notifyConfigurationChanged;
60 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070061 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070062 jmethodID notifyANR;
Jeff Brown349703e2010-06-22 01:27:15 -070063 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080064 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070065 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070066 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070067 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070068 jmethodID filterTouchEvents;
69 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080070 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070071 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080072 jmethodID getKeyRepeatTimeout;
73 jmethodID getKeyRepeatDelay;
Jeff Brownae9fc032010-08-18 15:51:08 -070074 jmethodID getMaxEventsPerSecond;
Jeff Brown83c09682010-12-23 17:50:18 -080075 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080076 jmethodID getPointerIcon;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070077} gCallbacksClassInfo;
78
79static struct {
80 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070081} gKeyEventClassInfo;
82
83static struct {
84 jclass clazz;
85} gMotionEventClassInfo;
86
Jeff Brown8d608662010-08-30 03:02:23 -070087static struct {
88 jclass clazz;
89
90 jmethodID ctor;
91 jmethodID addMotionRange;
92
93 jfieldID mId;
94 jfieldID mName;
95 jfieldID mSources;
96 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -070097} gInputDeviceClassInfo;
98
Jeff Brown57c59372010-09-21 18:22:55 -070099static struct {
100 jclass clazz;
101
102 jfieldID touchscreen;
103 jfieldID keyboard;
104 jfieldID navigation;
105} gConfigurationClassInfo;
106
Jeff Brown928e0542011-01-10 11:17:36 -0800107
108// --- Global functions ---
109
110static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
111 const sp<InputApplicationHandle>& inputApplicationHandle) {
112 if (inputApplicationHandle == NULL) {
113 return NULL;
114 }
115 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
116 getInputApplicationHandleObjLocalRef(env);
117}
118
119static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
120 const sp<InputWindowHandle>& inputWindowHandle) {
121 if (inputWindowHandle == NULL) {
122 return NULL;
123 }
124 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
125 getInputWindowHandleObjLocalRef(env);
126}
127
Jeff Brown86ea1f52011-04-12 22:39:53 -0700128static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
129 SpriteIcon* outSpriteIcon) {
130 PointerIcon pointerIcon;
131 status_t status = android_view_PointerIcon_loadSystemIcon(env,
132 contextObj, style, &pointerIcon);
133 if (!status) {
134 pointerIcon.bitmap.copyTo(&outSpriteIcon->bitmap, SkBitmap::kARGB_8888_Config);
135 outSpriteIcon->hotSpotX = pointerIcon.hotSpotX;
136 outSpriteIcon->hotSpotY = pointerIcon.hotSpotY;
137 }
138}
139
Jeff Brown928e0542011-01-10 11:17:36 -0800140
141// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800142
Jeff Brown9c3cda02010-06-15 01:31:58 -0700143class NativeInputManager : public virtual RefBase,
144 public virtual InputReaderPolicyInterface,
Jeff Brown86ea1f52011-04-12 22:39:53 -0700145 public virtual InputDispatcherPolicyInterface,
146 public virtual PointerControllerPolicyInterface {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700147protected:
148 virtual ~NativeInputManager();
149
150public:
Jeff Brown86ea1f52011-04-12 22:39:53 -0700151 NativeInputManager(jobject contextObj, jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700152
153 inline sp<InputManager> getInputManager() const { return mInputManager; }
154
Jeff Brownb88102f2010-09-08 11:49:43 -0700155 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700156
Jeff Brown9c3cda02010-06-15 01:31:58 -0700157 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
158 void setDisplayOrientation(int32_t displayId, int32_t orientation);
159
Jeff Brown7fbdc842010-06-17 20:52:56 -0700160 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800161 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700162 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
163
Jeff Brown349703e2010-06-22 01:27:15 -0700164 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
165 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
166 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800167 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700168
Jeff Brown9c3cda02010-06-15 01:31:58 -0700169 /* --- InputReaderPolicyInterface implementation --- */
170
171 virtual bool getDisplayInfo(int32_t displayId,
172 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700173 virtual bool filterTouchEvents();
174 virtual bool filterJumpyTouchEvents();
Jeff Brownfe508922011-01-18 15:10:10 -0800175 virtual nsecs_t getVirtualKeyQuietTime();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700176 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800177 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700178
179 /* --- InputDispatcherPolicyInterface implementation --- */
180
Jeff Browne20c9e02010-10-11 14:20:19 -0700181 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
182 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700183 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700184 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800185 const sp<InputWindowHandle>& inputWindowHandle);
186 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700187 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700188 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700189 virtual int32_t getMaxEventsPerSecond();
Jeff Brown1f245102010-11-18 20:53:46 -0800190 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800191 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800192 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700193 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800194 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800195 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700196 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700197 virtual bool checkInjectEventsPermissionNonReentrant(
198 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700199
Jeff Brown86ea1f52011-04-12 22:39:53 -0700200 /* --- PointerControllerPolicyInterface implementation --- */
201
202 virtual void loadPointerResources(PointerResources* outResources);
203
Jeff Brown9c3cda02010-06-15 01:31:58 -0700204private:
205 sp<InputManager> mInputManager;
206
Jeff Brown86ea1f52011-04-12 22:39:53 -0700207 jobject mContextObj;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700208 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800209 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700210
211 // Cached filtering policies.
212 int32_t mFilterTouchEvents;
213 int32_t mFilterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -0800214 nsecs_t mVirtualKeyQuietTime;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700215
Jeff Browna4547672011-03-02 21:38:11 -0800216 // Cached key repeat policy.
217 nsecs_t mKeyRepeatTimeout;
218 nsecs_t mKeyRepeatDelay;
219
Jeff Brownae9fc032010-08-18 15:51:08 -0700220 // Cached throttling policy.
221 int32_t mMaxEventsPerSecond;
222
Jeff Brown83c09682010-12-23 17:50:18 -0800223 Mutex mLock;
224 struct Locked {
225 // Display size information.
226 int32_t displayWidth, displayHeight; // -1 when initialized
227 int32_t displayOrientation;
228
Jeff Brown05dc66a2011-03-02 14:41:58 -0800229 // System UI visibility.
230 int32_t systemUiVisibility;
231
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700232 // Sprite controller singleton, created on first use.
233 sp<SpriteController> spriteController;
234
Jeff Brown83c09682010-12-23 17:50:18 -0800235 // Pointer controller singleton, created and destroyed as needed.
236 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800237 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700238
Jeff Brown86ea1f52011-04-12 22:39:53 -0700239 void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800240 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700241 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800242
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700243 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700244 bool isScreenOn();
245 bool isScreenBright();
246
Jeff Brownb88102f2010-09-08 11:49:43 -0700247 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700248
Jeff Brown9c3cda02010-06-15 01:31:58 -0700249 static inline JNIEnv* jniEnv() {
250 return AndroidRuntime::getJNIEnv();
251 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700252};
253
Jeff Brown928e0542011-01-10 11:17:36 -0800254
Jeff Brown9c3cda02010-06-15 01:31:58 -0700255
Jeff Brown86ea1f52011-04-12 22:39:53 -0700256NativeInputManager::NativeInputManager(jobject contextObj,
257 jobject callbacksObj, const sp<Looper>& looper) :
Jeff Brown05dc66a2011-03-02 14:41:58 -0800258 mLooper(looper),
259 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
Jeff Browna4547672011-03-02 21:38:11 -0800260 mKeyRepeatTimeout(-1), mKeyRepeatDelay(-1),
Jeff Brown05dc66a2011-03-02 14:41:58 -0800261 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700262 JNIEnv* env = jniEnv();
263
Jeff Brown86ea1f52011-04-12 22:39:53 -0700264 mContextObj = env->NewGlobalRef(contextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700265 mCallbacksObj = env->NewGlobalRef(callbacksObj);
266
Jeff Brown83c09682010-12-23 17:50:18 -0800267 {
268 AutoMutex _l(mLock);
269 mLocked.displayWidth = -1;
270 mLocked.displayHeight = -1;
271 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800272
273 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800274 }
275
Jeff Brown9c3cda02010-06-15 01:31:58 -0700276 sp<EventHub> eventHub = new EventHub();
277 mInputManager = new InputManager(eventHub, this, this);
278}
279
280NativeInputManager::~NativeInputManager() {
281 JNIEnv* env = jniEnv();
282
Jeff Brown86ea1f52011-04-12 22:39:53 -0700283 env->DeleteGlobalRef(mContextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700284 env->DeleteGlobalRef(mCallbacksObj);
285}
286
Jeff Brownb88102f2010-09-08 11:49:43 -0700287void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700288 mInputManager->getReader()->dump(dump);
289 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700290
Jeff Brownb88102f2010-09-08 11:49:43 -0700291 mInputManager->getDispatcher()->dump(dump);
292 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700293}
294
Jeff Brown7fbdc842010-06-17 20:52:56 -0700295bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700296 if (env->ExceptionCheck()) {
297 LOGE("An exception was thrown by callback '%s'.", methodName);
298 LOGE_EX(env);
299 env->ExceptionClear();
300 return true;
301 }
302 return false;
303}
304
305void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
306 if (displayId == 0) {
Jeff Brown86ea1f52011-04-12 22:39:53 -0700307 { // acquire lock
308 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700309
Jeff Brown86ea1f52011-04-12 22:39:53 -0700310 if (mLocked.displayWidth == width && mLocked.displayHeight == height) {
311 return;
312 }
313
Jeff Brown83c09682010-12-23 17:50:18 -0800314 mLocked.displayWidth = width;
315 mLocked.displayHeight = height;
316
317 sp<PointerController> controller = mLocked.pointerController.promote();
318 if (controller != NULL) {
319 controller->setDisplaySize(width, height);
320 }
Jeff Brown86ea1f52011-04-12 22:39:53 -0700321 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700322 }
323}
324
325void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
326 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800327 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700328
Jeff Brown83c09682010-12-23 17:50:18 -0800329 if (mLocked.displayOrientation != orientation) {
330 mLocked.displayOrientation = orientation;
331
332 sp<PointerController> controller = mLocked.pointerController.promote();
333 if (controller != NULL) {
334 controller->setDisplayOrientation(orientation);
335 }
336 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700337 }
338}
339
Jeff Brown7fbdc842010-06-17 20:52:56 -0700340status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800341 const sp<InputChannel>& inputChannel,
342 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
343 return mInputManager->getDispatcher()->registerInputChannel(
344 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700345}
346
347status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
348 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700349 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700350}
351
Jeff Brown9c3cda02010-06-15 01:31:58 -0700352bool NativeInputManager::getDisplayInfo(int32_t displayId,
353 int32_t* width, int32_t* height, int32_t* orientation) {
354 bool result = false;
355 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800356 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700357
Jeff Brown83c09682010-12-23 17:50:18 -0800358 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700359 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800360 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700361 }
362 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800363 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700364 }
365 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800366 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700367 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700368 result = true;
369 }
370 }
371 return result;
372}
373
Jeff Brown9c3cda02010-06-15 01:31:58 -0700374bool NativeInputManager::filterTouchEvents() {
375 if (mFilterTouchEvents < 0) {
376 JNIEnv* env = jniEnv();
377
378 jboolean result = env->CallBooleanMethod(mCallbacksObj,
379 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700380 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700381 result = false;
382 }
383
384 mFilterTouchEvents = result ? 1 : 0;
385 }
386 return mFilterTouchEvents;
387}
388
389bool NativeInputManager::filterJumpyTouchEvents() {
390 if (mFilterJumpyTouchEvents < 0) {
391 JNIEnv* env = jniEnv();
392
393 jboolean result = env->CallBooleanMethod(mCallbacksObj,
394 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700395 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700396 result = false;
397 }
398
399 mFilterJumpyTouchEvents = result ? 1 : 0;
400 }
401 return mFilterJumpyTouchEvents;
402}
403
Jeff Brownfe508922011-01-18 15:10:10 -0800404nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
405 if (mVirtualKeyQuietTime < 0) {
406 JNIEnv* env = jniEnv();
407
408 jint result = env->CallIntMethod(mCallbacksObj,
409 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
410 if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
411 result = 0;
412 }
413 if (result < 0) {
414 result = 0;
415 }
416
417 mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
418 }
419 return mVirtualKeyQuietTime;
420}
421
Jeff Brown9c3cda02010-06-15 01:31:58 -0700422void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700423 outExcludedDeviceNames.clear();
424
Jeff Brown9c3cda02010-06-15 01:31:58 -0700425 JNIEnv* env = jniEnv();
426
427 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
428 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700429 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700430 jsize length = env->GetArrayLength(result);
431 for (jsize i = 0; i < length; i++) {
432 jstring item = jstring(env->GetObjectArrayElement(result, i));
433
434 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
435 outExcludedDeviceNames.add(String8(deviceNameChars));
436 env->ReleaseStringUTFChars(item, deviceNameChars);
437
438 env->DeleteLocalRef(item);
439 }
440 env->DeleteLocalRef(result);
441 }
442}
443
Jeff Brown83c09682010-12-23 17:50:18 -0800444sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
445 AutoMutex _l(mLock);
446
447 sp<PointerController> controller = mLocked.pointerController.promote();
448 if (controller == NULL) {
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700449 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800450
Jeff Brown86ea1f52011-04-12 22:39:53 -0700451 controller = new PointerController(this, mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800452 mLocked.pointerController = controller;
453
454 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
455 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800456
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700457 JNIEnv* env = jniEnv();
Jeff Brown86ea1f52011-04-12 22:39:53 -0700458 jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
459 gCallbacksClassInfo.getPointerIcon);
460 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
461 PointerIcon pointerIcon;
462 status_t status = android_view_PointerIcon_load(env, pointerIconObj,
463 mContextObj, &pointerIcon);
464 if (!status && !pointerIcon.isNullIcon()) {
465 controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
466 pointerIcon.hotSpotX, pointerIcon.hotSpotY));
467 } else {
468 controller->setPointerIcon(SpriteIcon());
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800469 }
Jeff Brown86ea1f52011-04-12 22:39:53 -0700470 env->DeleteLocalRef(pointerIconObj);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800471 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800472
Jeff Brown86ea1f52011-04-12 22:39:53 -0700473 updateInactivityTimeoutLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800474 }
475 return controller;
476}
477
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700478void NativeInputManager::ensureSpriteControllerLocked() {
479 if (mLocked.spriteController == NULL) {
480 JNIEnv* env = jniEnv();
481 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
482 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
483 layer = -1;
484 }
485 mLocked.spriteController = new SpriteController(mLooper, layer);
486 }
487}
488
Jeff Browne20c9e02010-10-11 14:20:19 -0700489void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
490 int32_t switchValue, uint32_t policyFlags) {
491#if DEBUG_INPUT_DISPATCHER_POLICY
492 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
493 when, switchCode, switchValue, policyFlags);
494#endif
495
496 JNIEnv* env = jniEnv();
497
498 switch (switchCode) {
499 case SW_LID:
500 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
501 when, switchValue == 0);
502 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
503 break;
504 }
505}
506
Jeff Brown9c3cda02010-06-15 01:31:58 -0700507void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
508#if DEBUG_INPUT_DISPATCHER_POLICY
509 LOGD("notifyConfigurationChanged - when=%lld", when);
510#endif
511
512 JNIEnv* env = jniEnv();
513
Jeff Brown57c59372010-09-21 18:22:55 -0700514 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700515 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700516}
517
Jeff Brown519e0242010-09-15 15:18:56 -0700518nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800519 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700520#if DEBUG_INPUT_DISPATCHER_POLICY
521 LOGD("notifyANR");
522#endif
523
524 JNIEnv* env = jniEnv();
525
Jeff Brown928e0542011-01-10 11:17:36 -0800526 jobject inputApplicationHandleObj =
527 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
528 jobject inputWindowHandleObj =
529 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700530
Jeff Brown519e0242010-09-15 15:18:56 -0700531 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800532 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700533 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
534 newTimeout = 0; // abort dispatch
535 } else {
536 assert(newTimeout >= 0);
537 }
538
Jeff Brown928e0542011-01-10 11:17:36 -0800539 env->DeleteLocalRef(inputWindowHandleObj);
540 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700541 return newTimeout;
542}
543
Jeff Brown928e0542011-01-10 11:17:36 -0800544void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700545#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800546 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700547#endif
548
Jeff Brown7fbdc842010-06-17 20:52:56 -0700549 JNIEnv* env = jniEnv();
550
Jeff Brown928e0542011-01-10 11:17:36 -0800551 jobject inputWindowHandleObj =
552 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
553 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700554 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800555 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700556 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
557
Jeff Brown928e0542011-01-10 11:17:36 -0800558 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700559 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700560}
561
Jeff Brown9c3cda02010-06-15 01:31:58 -0700562nsecs_t NativeInputManager::getKeyRepeatTimeout() {
563 if (! isScreenOn()) {
564 // Disable key repeat when the screen is off.
565 return -1;
566 } else {
Jeff Browna4547672011-03-02 21:38:11 -0800567 if (mKeyRepeatTimeout < 0) {
568 JNIEnv* env = jniEnv();
569
570 jint result = env->CallIntMethod(mCallbacksObj,
571 gCallbacksClassInfo.getKeyRepeatTimeout);
572 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
573 result = 500;
574 }
575
576 mKeyRepeatTimeout = milliseconds_to_nanoseconds(result);
577 }
578 return mKeyRepeatTimeout;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700579 }
580}
581
Jeff Brownb21fb102010-09-07 10:44:57 -0700582nsecs_t NativeInputManager::getKeyRepeatDelay() {
Jeff Browna4547672011-03-02 21:38:11 -0800583 if (mKeyRepeatDelay < 0) {
584 JNIEnv* env = jniEnv();
585
586 jint result = env->CallIntMethod(mCallbacksObj,
587 gCallbacksClassInfo.getKeyRepeatDelay);
588 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
589 result = 50;
590 }
591
592 mKeyRepeatDelay = milliseconds_to_nanoseconds(result);
593 }
594 return mKeyRepeatDelay;
Jeff Brownb21fb102010-09-07 10:44:57 -0700595}
596
Jeff Brownae9fc032010-08-18 15:51:08 -0700597int32_t NativeInputManager::getMaxEventsPerSecond() {
598 if (mMaxEventsPerSecond < 0) {
599 JNIEnv* env = jniEnv();
600
601 jint result = env->CallIntMethod(mCallbacksObj,
602 gCallbacksClassInfo.getMaxEventsPerSecond);
603 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700604 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700605 }
606
607 mMaxEventsPerSecond = result;
608 }
609 return mMaxEventsPerSecond;
610}
611
Jeff Brown349703e2010-06-22 01:27:15 -0700612void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700613 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700614
Jeff Brownb88102f2010-09-08 11:49:43 -0700615 jsize length = env->GetArrayLength(windowObjArray);
616 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800617 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
618 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700619 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700620 }
621
Jeff Brownb88102f2010-09-08 11:49:43 -0700622 windows.push();
623 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800624 android_server_InputWindow_toNative(env, windowObj, &window);
625 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700626 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700627 }
Jeff Brown928e0542011-01-10 11:17:36 -0800628 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700629 }
Jeff Brown349703e2010-06-22 01:27:15 -0700630
Jeff Brownb88102f2010-09-08 11:49:43 -0700631 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700632}
633
Jeff Brown349703e2010-06-22 01:27:15 -0700634void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700635 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700636 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800637 android_server_InputApplication_toNative(env, applicationObj, &application);
638 if (application.inputApplicationHandle != NULL) {
639 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Brown22d789d2011-03-25 11:58:46 -0700640 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800641 }
Jeff Brown349703e2010-06-22 01:27:15 -0700642 }
Jeff Brown928e0542011-01-10 11:17:36 -0800643 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700644}
645
646void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700647 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700648}
649
Jeff Brown05dc66a2011-03-02 14:41:58 -0800650void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
651 AutoMutex _l(mLock);
652
653 if (mLocked.systemUiVisibility != visibility) {
654 mLocked.systemUiVisibility = visibility;
655
656 sp<PointerController> controller = mLocked.pointerController.promote();
657 if (controller != NULL) {
Jeff Brown86ea1f52011-04-12 22:39:53 -0700658 updateInactivityTimeoutLocked(controller);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800659 }
660 }
661}
662
Jeff Brown86ea1f52011-04-12 22:39:53 -0700663void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800664 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
Jeff Brown86ea1f52011-04-12 22:39:53 -0700665 controller->setInactivityTimeout(lightsOut
666 ? PointerController::INACTIVITY_TIMEOUT_SHORT
667 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800668}
669
Jeff Browne20c9e02010-10-11 14:20:19 -0700670bool NativeInputManager::isScreenOn() {
671 return android_server_PowerManagerService_isScreenOn();
672}
673
674bool NativeInputManager::isScreenBright() {
675 return android_server_PowerManagerService_isScreenBright();
676}
677
Jeff Brown1f245102010-11-18 20:53:46 -0800678void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
679 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700680 // Policy:
681 // - Ignore untrusted events and pass them along.
682 // - Ask the window manager what to do with normal events and trusted injected events.
683 // - For normal events wake and brighten the screen if currently off or dim.
684 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800685 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700686 bool isScreenOn = this->isScreenOn();
687 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700688
Jeff Brown3122e442010-10-11 23:32:49 -0700689 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800690 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
691 jint wmActions;
692 if (keyEventObj) {
693 wmActions = env->CallIntMethod(mCallbacksObj,
694 gCallbacksClassInfo.interceptKeyBeforeQueueing,
695 keyEventObj, policyFlags, isScreenOn);
696 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
697 wmActions = 0;
698 }
699 android_view_KeyEvent_recycle(env, keyEventObj);
700 env->DeleteLocalRef(keyEventObj);
701 } else {
702 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700703 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700704 }
705
Jeff Brown1f245102010-11-18 20:53:46 -0800706 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700707 if (!isScreenOn) {
708 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700709 }
710
711 if (!isScreenBright) {
712 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
713 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700714 }
715
Jeff Brown56194eb2011-03-02 19:23:13 -0800716 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700717 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700718 policyFlags |= POLICY_FLAG_PASS_TO_USER;
719 }
720}
721
Jeff Brown56194eb2011-03-02 19:23:13 -0800722void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700723 // Policy:
724 // - Ignore untrusted events and pass them along.
725 // - No special filtering for injected events required at this time.
726 // - Filter normal events based on screen state.
727 // - For normal events brighten (but do not wake) the screen if currently dim.
728 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
729 if (isScreenOn()) {
730 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700731
Jeff Brown3122e442010-10-11 23:32:49 -0700732 if (!isScreenBright()) {
733 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
734 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800735 } else {
736 JNIEnv* env = jniEnv();
737 jint wmActions = env->CallIntMethod(mCallbacksObj,
738 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
739 policyFlags);
740 if (checkAndClearExceptionFromCallback(env,
741 "interceptMotionBeforeQueueingWhenScreenOff")) {
742 wmActions = 0;
743 }
744
745 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
746 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700747 }
Jeff Brown3122e442010-10-11 23:32:49 -0700748 } else {
749 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700750 }
751}
752
Jeff Brown56194eb2011-03-02 19:23:13 -0800753void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
754 uint32_t& policyFlags) {
755 enum {
756 WM_ACTION_PASS_TO_USER = 1,
757 WM_ACTION_POKE_USER_ACTIVITY = 2,
758 WM_ACTION_GO_TO_SLEEP = 4,
759 };
760
761 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800762#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800763 LOGD("handleInterceptActions: Going to sleep.");
764#endif
765 android_server_PowerManagerService_goToSleep(when);
766 }
767
768 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800769#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800770 LOGD("handleInterceptActions: Poking user activity.");
771#endif
772 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
773 }
774
775 if (wmActions & WM_ACTION_PASS_TO_USER) {
776 policyFlags |= POLICY_FLAG_PASS_TO_USER;
777 } else {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800778#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800779 LOGD("handleInterceptActions: Not passing key to user.");
780#endif
781 }
782}
783
Jeff Brown928e0542011-01-10 11:17:36 -0800784bool NativeInputManager::interceptKeyBeforeDispatching(
785 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700786 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700787 // Policy:
788 // - Ignore untrusted events and pass them along.
789 // - Filter normal events and trusted injected events through the window manager policy to
790 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800791 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700792 if (policyFlags & POLICY_FLAG_TRUSTED) {
793 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700794
Jeff Brown928e0542011-01-10 11:17:36 -0800795 // Note: inputWindowHandle may be null.
796 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800797 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
798 if (keyEventObj) {
799 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
800 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800801 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800802 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
803 android_view_KeyEvent_recycle(env, keyEventObj);
804 env->DeleteLocalRef(keyEventObj);
805 result = consumed && !error;
806 } else {
807 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800808 }
Jeff Brown928e0542011-01-10 11:17:36 -0800809 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700810 }
Jeff Brown1f245102010-11-18 20:53:46 -0800811 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700812}
813
Jeff Brown928e0542011-01-10 11:17:36 -0800814bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800815 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700816 // Policy:
817 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800818 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700819 if (policyFlags & POLICY_FLAG_TRUSTED) {
820 JNIEnv* env = jniEnv();
821
Jeff Brown928e0542011-01-10 11:17:36 -0800822 // Note: inputWindowHandle may be null.
823 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800824 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
825 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800826 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800827 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800828 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown524ee642011-03-29 15:11:34 -0700829 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
830 fallbackKeyEventObj = NULL;
831 }
Jeff Brown1f245102010-11-18 20:53:46 -0800832 android_view_KeyEvent_recycle(env, keyEventObj);
833 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800834
835 if (fallbackKeyEventObj) {
836 // Note: outFallbackKeyEvent may be the same object as keyEvent.
837 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
838 outFallbackKeyEvent)) {
839 result = true;
840 }
841 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
842 env->DeleteLocalRef(fallbackKeyEventObj);
843 }
Jeff Brown1f245102010-11-18 20:53:46 -0800844 } else {
845 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800846 }
Jeff Brown928e0542011-01-10 11:17:36 -0800847 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700848 }
Jeff Brown1f245102010-11-18 20:53:46 -0800849 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700850}
851
Jeff Brown01ce2e92010-09-26 22:20:12 -0700852void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
853 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700854}
855
Jeff Brown349703e2010-06-22 01:27:15 -0700856
Jeff Brownb88102f2010-09-08 11:49:43 -0700857bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
858 int32_t injectorPid, int32_t injectorUid) {
859 JNIEnv* env = jniEnv();
860 jboolean result = env->CallBooleanMethod(mCallbacksObj,
861 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brown524ee642011-03-29 15:11:34 -0700862 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
863 result = false;
864 }
Jeff Brown349703e2010-06-22 01:27:15 -0700865 return result;
866}
867
Jeff Brown86ea1f52011-04-12 22:39:53 -0700868void NativeInputManager::loadPointerResources(PointerResources* outResources) {
869 JNIEnv* env = jniEnv();
870
871 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER,
872 &outResources->spotHover);
873 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH,
874 &outResources->spotTouch);
875 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR,
876 &outResources->spotAnchor);
877}
878
Jeff Brown83c09682010-12-23 17:50:18 -0800879
Jeff Brown9c3cda02010-06-15 01:31:58 -0700880// ----------------------------------------------------------------------------
881
882static sp<NativeInputManager> gNativeInputManager;
883
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700884static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700885 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700886 LOGE("Input manager not initialized.");
887 jniThrowRuntimeException(env, "Input manager not initialized.");
888 return true;
889 }
890 return false;
891}
892
893static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown86ea1f52011-04-12 22:39:53 -0700894 jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700895 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800896 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
Jeff Brown86ea1f52011-04-12 22:39:53 -0700897 gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700898 } else {
899 LOGE("Input manager already initialized.");
900 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700901 }
902}
903
904static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
905 if (checkInputManagerUnitialized(env)) {
906 return;
907 }
908
Jeff Brown9c3cda02010-06-15 01:31:58 -0700909 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700910 if (result) {
911 jniThrowRuntimeException(env, "Input manager could not be started.");
912 }
913}
914
915static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
916 jint displayId, jint width, jint height) {
917 if (checkInputManagerUnitialized(env)) {
918 return;
919 }
920
921 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
922 // to be passed in like this, not sure which is better but leaving it like this
923 // keeps the window manager in direct control of when display transitions propagate down
924 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700925 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700926}
927
928static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
929 jint displayId, jint orientation) {
930 if (checkInputManagerUnitialized(env)) {
931 return;
932 }
933
Jeff Brown9c3cda02010-06-15 01:31:58 -0700934 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700935}
936
937static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700938 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700939 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700940 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700941 }
942
Jeff Brownb88102f2010-09-08 11:49:43 -0700943 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700944 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700945}
946
947static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700948 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700949 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700950 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700951 }
952
Jeff Brownb88102f2010-09-08 11:49:43 -0700953 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700954 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700955}
956
957static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700958 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700959 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700960 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700961 }
962
Jeff Brownb88102f2010-09-08 11:49:43 -0700963 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700964 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700965}
966
967static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700968 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700969 if (checkInputManagerUnitialized(env)) {
970 return JNI_FALSE;
971 }
972
973 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
974 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
975 jsize numCodes = env->GetArrayLength(keyCodes);
976 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700977 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700978 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700979 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700980 } else {
981 result = JNI_FALSE;
982 }
983
984 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
985 env->ReleaseIntArrayElements(keyCodes, codes, 0);
986 return result;
987}
988
989static void throwInputChannelNotInitialized(JNIEnv* env) {
990 jniThrowException(env, "java/lang/IllegalStateException",
991 "inputChannel is not initialized");
992}
993
994static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
995 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
996 LOGW("Input channel object '%s' was disposed without first being unregistered with "
997 "the input manager!", inputChannel->getName().string());
998
Jeff Brown9c3cda02010-06-15 01:31:58 -0700999 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001000 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001001 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001002}
1003
1004static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001005 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001006 if (checkInputManagerUnitialized(env)) {
1007 return;
1008 }
1009
1010 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1011 inputChannelObj);
1012 if (inputChannel == NULL) {
1013 throwInputChannelNotInitialized(env);
1014 return;
1015 }
1016
Jeff Brown928e0542011-01-10 11:17:36 -08001017 sp<InputWindowHandle> inputWindowHandle =
1018 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001019
1020 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001021 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001022 if (status) {
1023 jniThrowRuntimeException(env, "Failed to register input channel. "
1024 "Check logs for details.");
1025 return;
1026 }
1027
Jeff Browna41ca772010-08-11 14:46:32 -07001028 if (! monitor) {
1029 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1030 android_server_InputManager_handleInputChannelDisposed, NULL);
1031 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001032}
1033
1034static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1035 jobject inputChannelObj) {
1036 if (checkInputManagerUnitialized(env)) {
1037 return;
1038 }
1039
1040 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1041 inputChannelObj);
1042 if (inputChannel == NULL) {
1043 throwInputChannelNotInitialized(env);
1044 return;
1045 }
1046
1047 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1048
Jeff Brown7fbdc842010-06-17 20:52:56 -07001049 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001050 if (status) {
1051 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1052 "Check logs for details.");
1053 }
1054}
1055
Jeff Brown6ec402b2010-07-28 15:48:59 -07001056static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1057 jobject inputEventObj, jint injectorPid, jint injectorUid,
1058 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001059 if (checkInputManagerUnitialized(env)) {
1060 return INPUT_EVENT_INJECTION_FAILED;
1061 }
1062
Jeff Brown6ec402b2010-07-28 15:48:59 -07001063 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1064 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001065 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1066 if (status) {
1067 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1068 return INPUT_EVENT_INJECTION_FAILED;
1069 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001070
Jeff Brownb88102f2010-09-08 11:49:43 -07001071 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1072 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001073 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown5b2b4d92011-03-14 19:39:54 -07001074 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1075 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001076 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1077 return INPUT_EVENT_INJECTION_FAILED;
1078 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001079
Jeff Brownb88102f2010-09-08 11:49:43 -07001080 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown5b2b4d92011-03-14 19:39:54 -07001081 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001082 } else {
1083 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001084 return INPUT_EVENT_INJECTION_FAILED;
1085 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001086}
1087
Jeff Brown349703e2010-06-22 01:27:15 -07001088static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1089 jobjectArray windowObjArray) {
1090 if (checkInputManagerUnitialized(env)) {
1091 return;
1092 }
1093
1094 gNativeInputManager->setInputWindows(env, windowObjArray);
1095}
1096
1097static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1098 jobject applicationObj) {
1099 if (checkInputManagerUnitialized(env)) {
1100 return;
1101 }
1102
1103 gNativeInputManager->setFocusedApplication(env, applicationObj);
1104}
1105
1106static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1107 jclass clazz, jboolean enabled, jboolean frozen) {
1108 if (checkInputManagerUnitialized(env)) {
1109 return;
1110 }
1111
1112 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1113}
1114
Jeff Brown05dc66a2011-03-02 14:41:58 -08001115static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1116 jclass clazz, jint visibility) {
1117 if (checkInputManagerUnitialized(env)) {
1118 return;
1119 }
1120
1121 gNativeInputManager->setSystemUiVisibility(visibility);
1122}
1123
Jeff Brown8d608662010-08-30 03:02:23 -07001124static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1125 jclass clazz, jint deviceId) {
1126 if (checkInputManagerUnitialized(env)) {
1127 return NULL;
1128 }
1129
1130 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001131 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001132 deviceId, & deviceInfo);
1133 if (status) {
1134 return NULL;
1135 }
1136
1137 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1138 if (! deviceObj) {
1139 return NULL;
1140 }
1141
1142 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1143 if (! deviceNameObj) {
1144 return NULL;
1145 }
1146
1147 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1148 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1149 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1150 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1151
Jeff Brownefd32662011-03-08 15:13:06 -08001152 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001153 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001154 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001155 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001156 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001157 if (env->ExceptionCheck()) {
1158 return NULL;
1159 }
1160 }
1161
1162 return deviceObj;
1163}
1164
1165static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1166 jclass clazz) {
1167 if (checkInputManagerUnitialized(env)) {
1168 return NULL;
1169 }
1170
1171 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001172 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001173
1174 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1175 if (! deviceIdsObj) {
1176 return NULL;
1177 }
1178
1179 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1180 return deviceIdsObj;
1181}
1182
Jeff Brown57c59372010-09-21 18:22:55 -07001183static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1184 jclass clazz, jobject configObj) {
1185 if (checkInputManagerUnitialized(env)) {
1186 return;
1187 }
1188
1189 InputConfiguration config;
1190 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1191
1192 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1193 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1194 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1195}
1196
Jeff Browne6504122010-09-27 14:52:15 -07001197static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1198 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1199 if (checkInputManagerUnitialized(env)) {
1200 return false;
1201 }
1202
1203 sp<InputChannel> fromChannel =
1204 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1205 sp<InputChannel> toChannel =
1206 android_view_InputChannel_getInputChannel(env, toChannelObj);
1207
1208 if (fromChannel == NULL || toChannel == NULL) {
1209 return false;
1210 }
1211
1212 return gNativeInputManager->getInputManager()->getDispatcher()->
1213 transferTouchFocus(fromChannel, toChannel);
1214}
1215
Jeff Browne33348b2010-07-15 23:54:05 -07001216static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1217 if (checkInputManagerUnitialized(env)) {
1218 return NULL;
1219 }
1220
Jeff Brownb88102f2010-09-08 11:49:43 -07001221 String8 dump;
1222 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001223 return env->NewStringUTF(dump.string());
1224}
1225
Jeff Brown9c3cda02010-06-15 01:31:58 -07001226// ----------------------------------------------------------------------------
1227
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001228static JNINativeMethod gInputManagerMethods[] = {
1229 /* name, signature, funcPtr */
Jeff Brown86ea1f52011-04-12 22:39:53 -07001230 { "nativeInit", "(Landroid/content/Context;"
1231 "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001232 (void*) android_server_InputManager_nativeInit },
1233 { "nativeStart", "()V",
1234 (void*) android_server_InputManager_nativeStart },
1235 { "nativeSetDisplaySize", "(III)V",
1236 (void*) android_server_InputManager_nativeSetDisplaySize },
1237 { "nativeSetDisplayOrientation", "(II)V",
1238 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1239 { "nativeGetScanCodeState", "(III)I",
1240 (void*) android_server_InputManager_nativeGetScanCodeState },
1241 { "nativeGetKeyCodeState", "(III)I",
1242 (void*) android_server_InputManager_nativeGetKeyCodeState },
1243 { "nativeGetSwitchState", "(III)I",
1244 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001245 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001246 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001247 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001248 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001249 (void*) android_server_InputManager_nativeRegisterInputChannel },
1250 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001251 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001252 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1253 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001254 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001255 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001256 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001257 (void*) android_server_InputManager_nativeSetFocusedApplication },
1258 { "nativeSetInputDispatchMode", "(ZZ)V",
1259 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001260 { "nativeSetSystemUiVisibility", "(I)V",
1261 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001262 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1263 (void*) android_server_InputManager_nativeGetInputDevice },
1264 { "nativeGetInputDeviceIds", "()[I",
1265 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001266 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1267 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001268 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1269 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001270 { "nativeDump", "()Ljava/lang/String;",
1271 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001272};
1273
1274#define FIND_CLASS(var, className) \
1275 var = env->FindClass(className); \
1276 LOG_FATAL_IF(! var, "Unable to find class " className); \
1277 var = jclass(env->NewGlobalRef(var));
1278
1279#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1280 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1281 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1282
1283#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1284 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1285 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1286
1287int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001288 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001289 gInputManagerMethods, NELEM(gInputManagerMethods));
1290 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1291
Jeff Brown9c3cda02010-06-15 01:31:58 -07001292 // Callbacks
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001293
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001294 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001295
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001296 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001297 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001298
1299 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1300 "notifyLidSwitchChanged", "(JZ)V");
1301
Jeff Brown7fbdc842010-06-17 20:52:56 -07001302 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001303 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001304
Jeff Brown349703e2010-06-22 01:27:15 -07001305 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001306 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001307 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001308
Jeff Brown349703e2010-06-22 01:27:15 -07001309 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001310 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001311
Jeff Brown56194eb2011-03-02 19:23:13 -08001312 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
1313 gCallbacksClassInfo.clazz,
1314 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1315
Jeff Brown349703e2010-06-22 01:27:15 -07001316 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001317 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001318 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001319
Jeff Brown3915bb82010-11-05 15:02:16 -07001320 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001321 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001322 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001323
Jeff Brown349703e2010-06-22 01:27:15 -07001324 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1325 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001326
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001327 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1328 "filterTouchEvents", "()Z");
1329
1330 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1331 "filterJumpyTouchEvents", "()Z");
1332
Jeff Brownfe508922011-01-18 15:10:10 -08001333 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
1334 "getVirtualKeyQuietTimeMillis", "()I");
1335
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001336 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1337 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1338
Jeff Browna4547672011-03-02 21:38:11 -08001339 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, gCallbacksClassInfo.clazz,
1340 "getKeyRepeatTimeout", "()I");
1341
1342 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, gCallbacksClassInfo.clazz,
1343 "getKeyRepeatDelay", "()I");
1344
Jeff Brownae9fc032010-08-18 15:51:08 -07001345 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1346 "getMaxEventsPerSecond", "()I");
1347
Jeff Brown83c09682010-12-23 17:50:18 -08001348 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, gCallbacksClassInfo.clazz,
1349 "getPointerLayer", "()I");
1350
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001351 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, gCallbacksClassInfo.clazz,
Jeff Brown86ea1f52011-04-12 22:39:53 -07001352 "getPointerIcon", "()Landroid/view/PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001353
Jeff Brown6ec402b2010-07-28 15:48:59 -07001354 // KeyEvent
1355
1356 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1357
Jeff Brown8d608662010-08-30 03:02:23 -07001358 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001359
1360 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1361
Jeff Brown8d608662010-08-30 03:02:23 -07001362 // InputDevice
1363
1364 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1365
1366 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1367 "<init>", "()V");
1368
1369 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001370 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001371
1372 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1373 "mId", "I");
1374
1375 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1376 "mName", "Ljava/lang/String;");
1377
1378 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1379 "mSources", "I");
1380
1381 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1382 "mKeyboardType", "I");
1383
Jeff Brown57c59372010-09-21 18:22:55 -07001384 // Configuration
1385
1386 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1387
1388 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1389 "touchscreen", "I");
1390
1391 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1392 "keyboard", "I");
1393
1394 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1395 "navigation", "I");
1396
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001397 return 0;
1398}
1399
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001400} /* namespace android */