blob: 1f10d9cd7af924eec85e1a46b7a2a9e85378c232 [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 Brown5541de92011-04-11 11:54:25 -070039#include <input/SpriteController.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080040
Jeff Brown05dc66a2011-03-02 14:41:58 -080041#include <android_os_MessageQueue.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080042#include <android_view_KeyEvent.h>
43#include <android_view_MotionEvent.h>
44#include <android_view_InputChannel.h>
Jeff Brown2352b972011-04-12 22:39:53 -070045#include <android_view_PointerIcon.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080046#include <android/graphics/GraphicsJNI.h>
47
Jeff Brown00fa7bd2010-07-02 15:37:36 -070048#include "com_android_server_PowerManagerService.h"
Jeff Brown928e0542011-01-10 11:17:36 -080049#include "com_android_server_InputApplication.h"
50#include "com_android_server_InputApplicationHandle.h"
51#include "com_android_server_InputWindow.h"
52#include "com_android_server_InputWindowHandle.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070053
54namespace android {
55
Jeff Brown46b9ac02010-04-22 18:58:52 -070056static struct {
Jeff Brown46b9ac02010-04-22 18:58:52 -070057 jmethodID notifyConfigurationChanged;
58 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070059 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070060 jmethodID notifyANR;
Jeff Brown0029c662011-03-30 02:25:18 -070061 jmethodID filterInputEvent;
Jeff Brown349703e2010-06-22 01:27:15 -070062 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080063 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070064 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070065 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070066 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070067 jmethodID filterTouchEvents;
68 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080069 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac02010-04-22 18:58:52 -070070 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080071 jmethodID getKeyRepeatTimeout;
72 jmethodID getKeyRepeatDelay;
Jeff Brownae9fc032010-08-18 15:51:08 -070073 jmethodID getMaxEventsPerSecond;
Jeff Brown83c09682010-12-23 17:50:18 -080074 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080075 jmethodID getPointerIcon;
Jeff Brown46b9ac02010-04-22 18:58:52 -070076} gCallbacksClassInfo;
77
78static struct {
79 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070080} gKeyEventClassInfo;
81
82static struct {
83 jclass clazz;
84} gMotionEventClassInfo;
85
Jeff Brown8d608662010-08-30 03:02:23 -070086static struct {
87 jclass clazz;
88
89 jmethodID ctor;
90 jmethodID addMotionRange;
91
92 jfieldID mId;
93 jfieldID mName;
94 jfieldID mSources;
95 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -070096} gInputDeviceClassInfo;
97
Jeff Brown57c59372010-09-21 18:22:55 -070098static struct {
Jeff Brown57c59372010-09-21 18:22:55 -070099 jfieldID touchscreen;
100 jfieldID keyboard;
101 jfieldID navigation;
102} gConfigurationClassInfo;
103
Jeff Brown928e0542011-01-10 11:17:36 -0800104
105// --- Global functions ---
106
107static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
108 const sp<InputApplicationHandle>& inputApplicationHandle) {
109 if (inputApplicationHandle == NULL) {
110 return NULL;
111 }
112 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
113 getInputApplicationHandleObjLocalRef(env);
114}
115
116static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
117 const sp<InputWindowHandle>& inputWindowHandle) {
118 if (inputWindowHandle == NULL) {
119 return NULL;
120 }
121 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
122 getInputWindowHandleObjLocalRef(env);
123}
124
Jeff Brown2352b972011-04-12 22:39:53 -0700125static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
126 SpriteIcon* outSpriteIcon) {
127 PointerIcon pointerIcon;
128 status_t status = android_view_PointerIcon_loadSystemIcon(env,
129 contextObj, style, &pointerIcon);
130 if (!status) {
131 pointerIcon.bitmap.copyTo(&outSpriteIcon->bitmap, SkBitmap::kARGB_8888_Config);
132 outSpriteIcon->hotSpotX = pointerIcon.hotSpotX;
133 outSpriteIcon->hotSpotY = pointerIcon.hotSpotY;
134 }
135}
136
Jeff Brown928e0542011-01-10 11:17:36 -0800137
138// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800139
Jeff Brown9c3cda02010-06-15 01:31:58 -0700140class NativeInputManager : public virtual RefBase,
141 public virtual InputReaderPolicyInterface,
Jeff Brown2352b972011-04-12 22:39:53 -0700142 public virtual InputDispatcherPolicyInterface,
143 public virtual PointerControllerPolicyInterface {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700144protected:
145 virtual ~NativeInputManager();
146
147public:
Jeff Brown2352b972011-04-12 22:39:53 -0700148 NativeInputManager(jobject contextObj, jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700149
150 inline sp<InputManager> getInputManager() const { return mInputManager; }
151
Jeff Brownb88102f2010-09-08 11:49:43 -0700152 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700153
Jeff Brown9c3cda02010-06-15 01:31:58 -0700154 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
155 void setDisplayOrientation(int32_t displayId, int32_t orientation);
156
Jeff Brown7fbdc842010-06-17 20:52:56 -0700157 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800158 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700159 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
160
Jeff Brown349703e2010-06-22 01:27:15 -0700161 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
162 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
163 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800164 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700165
Jeff Brown9c3cda02010-06-15 01:31:58 -0700166 /* --- InputReaderPolicyInterface implementation --- */
167
168 virtual bool getDisplayInfo(int32_t displayId,
169 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700170 virtual bool filterTouchEvents();
171 virtual bool filterJumpyTouchEvents();
Jeff Brownfe508922011-01-18 15:10:10 -0800172 virtual nsecs_t getVirtualKeyQuietTime();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700173 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800174 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700175
176 /* --- InputDispatcherPolicyInterface implementation --- */
177
Jeff Browne20c9e02010-10-11 14:20:19 -0700178 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
179 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700180 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700181 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800182 const sp<InputWindowHandle>& inputWindowHandle);
183 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700184 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700185 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700186 virtual int32_t getMaxEventsPerSecond();
Jeff Brown0029c662011-03-30 02:25:18 -0700187 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800188 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800189 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800190 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700191 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800192 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800193 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700194 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700195 virtual bool checkInjectEventsPermissionNonReentrant(
196 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197
Jeff Brown2352b972011-04-12 22:39:53 -0700198 /* --- PointerControllerPolicyInterface implementation --- */
199
200 virtual void loadPointerResources(PointerResources* outResources);
201
Jeff Brown9c3cda02010-06-15 01:31:58 -0700202private:
203 sp<InputManager> mInputManager;
204
Jeff Brown2352b972011-04-12 22:39:53 -0700205 jobject mContextObj;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700206 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800207 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700208
209 // Cached filtering policies.
210 int32_t mFilterTouchEvents;
211 int32_t mFilterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -0800212 nsecs_t mVirtualKeyQuietTime;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700213
Jeff Browna4547672011-03-02 21:38:11 -0800214 // Cached key repeat policy.
215 nsecs_t mKeyRepeatTimeout;
216 nsecs_t mKeyRepeatDelay;
217
Jeff Brownae9fc032010-08-18 15:51:08 -0700218 // Cached throttling policy.
219 int32_t mMaxEventsPerSecond;
220
Jeff Brown83c09682010-12-23 17:50:18 -0800221 Mutex mLock;
222 struct Locked {
223 // Display size information.
224 int32_t displayWidth, displayHeight; // -1 when initialized
225 int32_t displayOrientation;
226
Jeff Brown05dc66a2011-03-02 14:41:58 -0800227 // System UI visibility.
228 int32_t systemUiVisibility;
229
Jeff Brown5541de92011-04-11 11:54:25 -0700230 // Sprite controller singleton, created on first use.
231 sp<SpriteController> spriteController;
232
Jeff Brown83c09682010-12-23 17:50:18 -0800233 // Pointer controller singleton, created and destroyed as needed.
234 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800235 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700236
Jeff Brown2352b972011-04-12 22:39:53 -0700237 void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800238 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown5541de92011-04-11 11:54:25 -0700239 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800240
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700241 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700242 bool isScreenOn();
243 bool isScreenBright();
244
Jeff Brownb88102f2010-09-08 11:49:43 -0700245 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700246
Jeff Brown9c3cda02010-06-15 01:31:58 -0700247 static inline JNIEnv* jniEnv() {
248 return AndroidRuntime::getJNIEnv();
249 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700250};
251
Jeff Brown928e0542011-01-10 11:17:36 -0800252
Jeff Brown9c3cda02010-06-15 01:31:58 -0700253
Jeff Brown2352b972011-04-12 22:39:53 -0700254NativeInputManager::NativeInputManager(jobject contextObj,
255 jobject callbacksObj, const sp<Looper>& looper) :
Jeff Brown05dc66a2011-03-02 14:41:58 -0800256 mLooper(looper),
257 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
Jeff Browna4547672011-03-02 21:38:11 -0800258 mKeyRepeatTimeout(-1), mKeyRepeatDelay(-1),
Jeff Brown05dc66a2011-03-02 14:41:58 -0800259 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700260 JNIEnv* env = jniEnv();
261
Jeff Brown2352b972011-04-12 22:39:53 -0700262 mContextObj = env->NewGlobalRef(contextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700263 mCallbacksObj = env->NewGlobalRef(callbacksObj);
264
Jeff Brown83c09682010-12-23 17:50:18 -0800265 {
266 AutoMutex _l(mLock);
267 mLocked.displayWidth = -1;
268 mLocked.displayHeight = -1;
269 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800270
271 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800272 }
273
Jeff Brown9c3cda02010-06-15 01:31:58 -0700274 sp<EventHub> eventHub = new EventHub();
275 mInputManager = new InputManager(eventHub, this, this);
276}
277
278NativeInputManager::~NativeInputManager() {
279 JNIEnv* env = jniEnv();
280
Jeff Brown2352b972011-04-12 22:39:53 -0700281 env->DeleteGlobalRef(mContextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700282 env->DeleteGlobalRef(mCallbacksObj);
283}
284
Jeff Brownb88102f2010-09-08 11:49:43 -0700285void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700286 mInputManager->getReader()->dump(dump);
287 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700288
Jeff Brownb88102f2010-09-08 11:49:43 -0700289 mInputManager->getDispatcher()->dump(dump);
290 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700291}
292
Jeff Brown7fbdc842010-06-17 20:52:56 -0700293bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700294 if (env->ExceptionCheck()) {
295 LOGE("An exception was thrown by callback '%s'.", methodName);
296 LOGE_EX(env);
297 env->ExceptionClear();
298 return true;
299 }
300 return false;
301}
302
303void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
304 if (displayId == 0) {
Jeff Brown2352b972011-04-12 22:39:53 -0700305 { // acquire lock
306 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700307
Jeff Brown2352b972011-04-12 22:39:53 -0700308 if (mLocked.displayWidth == width && mLocked.displayHeight == height) {
309 return;
310 }
311
Jeff Brown83c09682010-12-23 17:50:18 -0800312 mLocked.displayWidth = width;
313 mLocked.displayHeight = height;
314
315 sp<PointerController> controller = mLocked.pointerController.promote();
316 if (controller != NULL) {
317 controller->setDisplaySize(width, height);
318 }
Jeff Brown2352b972011-04-12 22:39:53 -0700319 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700320 }
321}
322
323void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
324 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800325 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700326
Jeff Brown83c09682010-12-23 17:50:18 -0800327 if (mLocked.displayOrientation != orientation) {
328 mLocked.displayOrientation = orientation;
329
330 sp<PointerController> controller = mLocked.pointerController.promote();
331 if (controller != NULL) {
332 controller->setDisplayOrientation(orientation);
333 }
334 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700335 }
336}
337
Jeff Brown7fbdc842010-06-17 20:52:56 -0700338status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800339 const sp<InputChannel>& inputChannel,
340 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
341 return mInputManager->getDispatcher()->registerInputChannel(
342 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700343}
344
345status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
346 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700347 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700348}
349
Jeff Brown9c3cda02010-06-15 01:31:58 -0700350bool NativeInputManager::getDisplayInfo(int32_t displayId,
351 int32_t* width, int32_t* height, int32_t* orientation) {
352 bool result = false;
353 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800354 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700355
Jeff Brown83c09682010-12-23 17:50:18 -0800356 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700357 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800358 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700359 }
360 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800361 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700362 }
363 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800364 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700365 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700366 result = true;
367 }
368 }
369 return result;
370}
371
Jeff Brown9c3cda02010-06-15 01:31:58 -0700372bool NativeInputManager::filterTouchEvents() {
373 if (mFilterTouchEvents < 0) {
374 JNIEnv* env = jniEnv();
375
376 jboolean result = env->CallBooleanMethod(mCallbacksObj,
377 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700378 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700379 result = false;
380 }
381
382 mFilterTouchEvents = result ? 1 : 0;
383 }
384 return mFilterTouchEvents;
385}
386
387bool NativeInputManager::filterJumpyTouchEvents() {
388 if (mFilterJumpyTouchEvents < 0) {
389 JNIEnv* env = jniEnv();
390
391 jboolean result = env->CallBooleanMethod(mCallbacksObj,
392 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700393 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700394 result = false;
395 }
396
397 mFilterJumpyTouchEvents = result ? 1 : 0;
398 }
399 return mFilterJumpyTouchEvents;
400}
401
Jeff Brownfe508922011-01-18 15:10:10 -0800402nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
403 if (mVirtualKeyQuietTime < 0) {
404 JNIEnv* env = jniEnv();
405
406 jint result = env->CallIntMethod(mCallbacksObj,
407 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
408 if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
409 result = 0;
410 }
411 if (result < 0) {
412 result = 0;
413 }
414
415 mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
416 }
417 return mVirtualKeyQuietTime;
418}
419
Jeff Brown9c3cda02010-06-15 01:31:58 -0700420void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700421 outExcludedDeviceNames.clear();
422
Jeff Brown9c3cda02010-06-15 01:31:58 -0700423 JNIEnv* env = jniEnv();
424
425 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
426 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700427 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700428 jsize length = env->GetArrayLength(result);
429 for (jsize i = 0; i < length; i++) {
430 jstring item = jstring(env->GetObjectArrayElement(result, i));
431
432 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
433 outExcludedDeviceNames.add(String8(deviceNameChars));
434 env->ReleaseStringUTFChars(item, deviceNameChars);
435
436 env->DeleteLocalRef(item);
437 }
438 env->DeleteLocalRef(result);
439 }
440}
441
Jeff Brown83c09682010-12-23 17:50:18 -0800442sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
443 AutoMutex _l(mLock);
444
445 sp<PointerController> controller = mLocked.pointerController.promote();
446 if (controller == NULL) {
Jeff Brown5541de92011-04-11 11:54:25 -0700447 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800448
Jeff Brown2352b972011-04-12 22:39:53 -0700449 controller = new PointerController(this, mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800450 mLocked.pointerController = controller;
451
452 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
453 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800454
Jeff Brown5541de92011-04-11 11:54:25 -0700455 JNIEnv* env = jniEnv();
Jeff Brown2352b972011-04-12 22:39:53 -0700456 jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
457 gCallbacksClassInfo.getPointerIcon);
458 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
459 PointerIcon pointerIcon;
460 status_t status = android_view_PointerIcon_load(env, pointerIconObj,
461 mContextObj, &pointerIcon);
462 if (!status && !pointerIcon.isNullIcon()) {
463 controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
464 pointerIcon.hotSpotX, pointerIcon.hotSpotY));
465 } else {
466 controller->setPointerIcon(SpriteIcon());
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800467 }
Jeff Brown2352b972011-04-12 22:39:53 -0700468 env->DeleteLocalRef(pointerIconObj);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800469 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800470
Jeff Brown2352b972011-04-12 22:39:53 -0700471 updateInactivityTimeoutLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800472 }
473 return controller;
474}
475
Jeff Brown5541de92011-04-11 11:54:25 -0700476void NativeInputManager::ensureSpriteControllerLocked() {
477 if (mLocked.spriteController == NULL) {
478 JNIEnv* env = jniEnv();
479 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
480 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
481 layer = -1;
482 }
483 mLocked.spriteController = new SpriteController(mLooper, layer);
484 }
485}
486
Jeff Browne20c9e02010-10-11 14:20:19 -0700487void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
488 int32_t switchValue, uint32_t policyFlags) {
489#if DEBUG_INPUT_DISPATCHER_POLICY
490 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
491 when, switchCode, switchValue, policyFlags);
492#endif
493
494 JNIEnv* env = jniEnv();
495
496 switch (switchCode) {
497 case SW_LID:
498 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
499 when, switchValue == 0);
500 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
501 break;
502 }
503}
504
Jeff Brown9c3cda02010-06-15 01:31:58 -0700505void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
506#if DEBUG_INPUT_DISPATCHER_POLICY
507 LOGD("notifyConfigurationChanged - when=%lld", when);
508#endif
509
510 JNIEnv* env = jniEnv();
511
Jeff Brown57c59372010-09-21 18:22:55 -0700512 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700513 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700514}
515
Jeff Brown519e0242010-09-15 15:18:56 -0700516nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800517 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700518#if DEBUG_INPUT_DISPATCHER_POLICY
519 LOGD("notifyANR");
520#endif
521
522 JNIEnv* env = jniEnv();
523
Jeff Brown928e0542011-01-10 11:17:36 -0800524 jobject inputApplicationHandleObj =
525 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
526 jobject inputWindowHandleObj =
527 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700528
Jeff Brown519e0242010-09-15 15:18:56 -0700529 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800530 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700531 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
532 newTimeout = 0; // abort dispatch
533 } else {
534 assert(newTimeout >= 0);
535 }
536
Jeff Brown928e0542011-01-10 11:17:36 -0800537 env->DeleteLocalRef(inputWindowHandleObj);
538 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700539 return newTimeout;
540}
541
Jeff Brown928e0542011-01-10 11:17:36 -0800542void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700543#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800544 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700545#endif
546
Jeff Brown7fbdc842010-06-17 20:52:56 -0700547 JNIEnv* env = jniEnv();
548
Jeff Brown928e0542011-01-10 11:17:36 -0800549 jobject inputWindowHandleObj =
550 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
551 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700552 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800553 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700554 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
555
Jeff Brown928e0542011-01-10 11:17:36 -0800556 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700557 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700558}
559
Jeff Brown9c3cda02010-06-15 01:31:58 -0700560nsecs_t NativeInputManager::getKeyRepeatTimeout() {
561 if (! isScreenOn()) {
562 // Disable key repeat when the screen is off.
563 return -1;
564 } else {
Jeff Browna4547672011-03-02 21:38:11 -0800565 if (mKeyRepeatTimeout < 0) {
566 JNIEnv* env = jniEnv();
567
568 jint result = env->CallIntMethod(mCallbacksObj,
569 gCallbacksClassInfo.getKeyRepeatTimeout);
570 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
571 result = 500;
572 }
573
574 mKeyRepeatTimeout = milliseconds_to_nanoseconds(result);
575 }
576 return mKeyRepeatTimeout;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700577 }
578}
579
Jeff Brownb21fb102010-09-07 10:44:57 -0700580nsecs_t NativeInputManager::getKeyRepeatDelay() {
Jeff Browna4547672011-03-02 21:38:11 -0800581 if (mKeyRepeatDelay < 0) {
582 JNIEnv* env = jniEnv();
583
584 jint result = env->CallIntMethod(mCallbacksObj,
585 gCallbacksClassInfo.getKeyRepeatDelay);
586 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
587 result = 50;
588 }
589
590 mKeyRepeatDelay = milliseconds_to_nanoseconds(result);
591 }
592 return mKeyRepeatDelay;
Jeff Brownb21fb102010-09-07 10:44:57 -0700593}
594
Jeff Brownae9fc032010-08-18 15:51:08 -0700595int32_t NativeInputManager::getMaxEventsPerSecond() {
596 if (mMaxEventsPerSecond < 0) {
597 JNIEnv* env = jniEnv();
598
599 jint result = env->CallIntMethod(mCallbacksObj,
600 gCallbacksClassInfo.getMaxEventsPerSecond);
601 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700602 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700603 }
604
605 mMaxEventsPerSecond = result;
606 }
607 return mMaxEventsPerSecond;
608}
609
Jeff Brown349703e2010-06-22 01:27:15 -0700610void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700611 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700612
Jeff Brownb88102f2010-09-08 11:49:43 -0700613 jsize length = env->GetArrayLength(windowObjArray);
614 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800615 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
616 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700617 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700618 }
619
Jeff Brownb88102f2010-09-08 11:49:43 -0700620 windows.push();
621 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800622 android_server_InputWindow_toNative(env, windowObj, &window);
623 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700624 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700625 }
Jeff Brown928e0542011-01-10 11:17:36 -0800626 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700627 }
Jeff Brown349703e2010-06-22 01:27:15 -0700628
Jeff Brownb88102f2010-09-08 11:49:43 -0700629 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700630}
631
Jeff Brown349703e2010-06-22 01:27:15 -0700632void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700633 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700634 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800635 android_server_InputApplication_toNative(env, applicationObj, &application);
636 if (application.inputApplicationHandle != NULL) {
637 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Browna2cc28d2011-03-25 11:58:46 -0700638 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800639 }
Jeff Brown349703e2010-06-22 01:27:15 -0700640 }
Jeff Brown928e0542011-01-10 11:17:36 -0800641 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700642}
643
644void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700645 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700646}
647
Jeff Brown05dc66a2011-03-02 14:41:58 -0800648void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
649 AutoMutex _l(mLock);
650
651 if (mLocked.systemUiVisibility != visibility) {
652 mLocked.systemUiVisibility = visibility;
653
654 sp<PointerController> controller = mLocked.pointerController.promote();
655 if (controller != NULL) {
Jeff Brown2352b972011-04-12 22:39:53 -0700656 updateInactivityTimeoutLocked(controller);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800657 }
658 }
659}
660
Jeff Brown2352b972011-04-12 22:39:53 -0700661void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800662 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
Jeff Brown2352b972011-04-12 22:39:53 -0700663 controller->setInactivityTimeout(lightsOut
664 ? PointerController::INACTIVITY_TIMEOUT_SHORT
665 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800666}
667
Jeff Browne20c9e02010-10-11 14:20:19 -0700668bool NativeInputManager::isScreenOn() {
669 return android_server_PowerManagerService_isScreenOn();
670}
671
672bool NativeInputManager::isScreenBright() {
673 return android_server_PowerManagerService_isScreenBright();
674}
675
Jeff Brown0029c662011-03-30 02:25:18 -0700676bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
677 jobject inputEventObj;
678
679 JNIEnv* env = jniEnv();
680 switch (inputEvent->getType()) {
681 case AINPUT_EVENT_TYPE_KEY:
682 inputEventObj = android_view_KeyEvent_fromNative(env,
683 static_cast<const KeyEvent*>(inputEvent));
684 break;
685 case AINPUT_EVENT_TYPE_MOTION:
686 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
687 static_cast<const MotionEvent*>(inputEvent));
688 break;
689 default:
690 return true; // dispatch the event normally
691 }
692
693 if (!inputEventObj) {
694 LOGE("Failed to obtain input event object for filterInputEvent.");
695 return true; // dispatch the event normally
696 }
697
698 // The callee is responsible for recycling the event.
699 jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
700 inputEventObj, policyFlags);
701 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
702 pass = true;
703 }
704 env->DeleteLocalRef(inputEventObj);
705 return pass;
706}
707
Jeff Brown1f245102010-11-18 20:53:46 -0800708void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
709 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700710 // Policy:
711 // - Ignore untrusted events and pass them along.
712 // - Ask the window manager what to do with normal events and trusted injected events.
713 // - For normal events wake and brighten the screen if currently off or dim.
714 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800715 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700716 bool isScreenOn = this->isScreenOn();
717 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700718
Jeff Brown3122e442010-10-11 23:32:49 -0700719 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800720 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
721 jint wmActions;
722 if (keyEventObj) {
723 wmActions = env->CallIntMethod(mCallbacksObj,
724 gCallbacksClassInfo.interceptKeyBeforeQueueing,
725 keyEventObj, policyFlags, isScreenOn);
726 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
727 wmActions = 0;
728 }
729 android_view_KeyEvent_recycle(env, keyEventObj);
730 env->DeleteLocalRef(keyEventObj);
731 } else {
732 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700733 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700734 }
735
Jeff Brown1f245102010-11-18 20:53:46 -0800736 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700737 if (!isScreenOn) {
738 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700739 }
740
741 if (!isScreenBright) {
742 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
743 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700744 }
745
Jeff Brown56194eb2011-03-02 19:23:13 -0800746 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700747 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700748 policyFlags |= POLICY_FLAG_PASS_TO_USER;
749 }
750}
751
Jeff Brown56194eb2011-03-02 19:23:13 -0800752void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700753 // Policy:
754 // - Ignore untrusted events and pass them along.
755 // - No special filtering for injected events required at this time.
756 // - Filter normal events based on screen state.
757 // - For normal events brighten (but do not wake) the screen if currently dim.
758 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
759 if (isScreenOn()) {
760 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700761
Jeff Brown3122e442010-10-11 23:32:49 -0700762 if (!isScreenBright()) {
763 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
764 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800765 } else {
766 JNIEnv* env = jniEnv();
767 jint wmActions = env->CallIntMethod(mCallbacksObj,
768 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
769 policyFlags);
770 if (checkAndClearExceptionFromCallback(env,
771 "interceptMotionBeforeQueueingWhenScreenOff")) {
772 wmActions = 0;
773 }
774
775 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
776 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700777 }
Jeff Brown3122e442010-10-11 23:32:49 -0700778 } else {
779 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700780 }
781}
782
Jeff Brown56194eb2011-03-02 19:23:13 -0800783void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
784 uint32_t& policyFlags) {
785 enum {
786 WM_ACTION_PASS_TO_USER = 1,
787 WM_ACTION_POKE_USER_ACTIVITY = 2,
788 WM_ACTION_GO_TO_SLEEP = 4,
789 };
790
791 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800792#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800793 LOGD("handleInterceptActions: Going to sleep.");
794#endif
795 android_server_PowerManagerService_goToSleep(when);
796 }
797
798 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800799#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800800 LOGD("handleInterceptActions: Poking user activity.");
801#endif
802 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
803 }
804
805 if (wmActions & WM_ACTION_PASS_TO_USER) {
806 policyFlags |= POLICY_FLAG_PASS_TO_USER;
807 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800808#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800809 LOGD("handleInterceptActions: Not passing key to user.");
810#endif
811 }
812}
813
Jeff Brown928e0542011-01-10 11:17:36 -0800814bool NativeInputManager::interceptKeyBeforeDispatching(
815 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700816 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700817 // Policy:
818 // - Ignore untrusted events and pass them along.
819 // - Filter normal events and trusted injected events through the window manager policy to
820 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800821 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700822 if (policyFlags & POLICY_FLAG_TRUSTED) {
823 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700824
Jeff Brown928e0542011-01-10 11:17:36 -0800825 // Note: inputWindowHandle may be null.
826 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800827 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
828 if (keyEventObj) {
829 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
830 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800831 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800832 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
833 android_view_KeyEvent_recycle(env, keyEventObj);
834 env->DeleteLocalRef(keyEventObj);
835 result = consumed && !error;
836 } else {
837 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800838 }
Jeff Brown928e0542011-01-10 11:17:36 -0800839 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700840 }
Jeff Brown1f245102010-11-18 20:53:46 -0800841 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700842}
843
Jeff Brown928e0542011-01-10 11:17:36 -0800844bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800845 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700846 // Policy:
847 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800848 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700849 if (policyFlags & POLICY_FLAG_TRUSTED) {
850 JNIEnv* env = jniEnv();
851
Jeff Brown928e0542011-01-10 11:17:36 -0800852 // Note: inputWindowHandle may be null.
853 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800854 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
855 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800856 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800857 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800858 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700859 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
860 fallbackKeyEventObj = NULL;
861 }
Jeff Brown1f245102010-11-18 20:53:46 -0800862 android_view_KeyEvent_recycle(env, keyEventObj);
863 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800864
865 if (fallbackKeyEventObj) {
866 // Note: outFallbackKeyEvent may be the same object as keyEvent.
867 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
868 outFallbackKeyEvent)) {
869 result = true;
870 }
871 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
872 env->DeleteLocalRef(fallbackKeyEventObj);
873 }
Jeff Brown1f245102010-11-18 20:53:46 -0800874 } else {
875 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800876 }
Jeff Brown928e0542011-01-10 11:17:36 -0800877 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700878 }
Jeff Brown1f245102010-11-18 20:53:46 -0800879 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700880}
881
Jeff Brown01ce2e92010-09-26 22:20:12 -0700882void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
883 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700884}
885
Jeff Brown349703e2010-06-22 01:27:15 -0700886
Jeff Brownb88102f2010-09-08 11:49:43 -0700887bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
888 int32_t injectorPid, int32_t injectorUid) {
889 JNIEnv* env = jniEnv();
890 jboolean result = env->CallBooleanMethod(mCallbacksObj,
891 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700892 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
893 result = false;
894 }
Jeff Brown349703e2010-06-22 01:27:15 -0700895 return result;
896}
897
Jeff Brown2352b972011-04-12 22:39:53 -0700898void NativeInputManager::loadPointerResources(PointerResources* outResources) {
899 JNIEnv* env = jniEnv();
900
901 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER,
902 &outResources->spotHover);
903 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH,
904 &outResources->spotTouch);
905 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR,
906 &outResources->spotAnchor);
907}
908
Jeff Brown83c09682010-12-23 17:50:18 -0800909
Jeff Brown9c3cda02010-06-15 01:31:58 -0700910// ----------------------------------------------------------------------------
911
912static sp<NativeInputManager> gNativeInputManager;
913
Jeff Brown46b9ac02010-04-22 18:58:52 -0700914static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700915 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700916 LOGE("Input manager not initialized.");
917 jniThrowRuntimeException(env, "Input manager not initialized.");
918 return true;
919 }
920 return false;
921}
922
923static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown2352b972011-04-12 22:39:53 -0700924 jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700925 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800926 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
Jeff Brown2352b972011-04-12 22:39:53 -0700927 gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700928 } else {
929 LOGE("Input manager already initialized.");
930 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700931 }
932}
933
934static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
935 if (checkInputManagerUnitialized(env)) {
936 return;
937 }
938
Jeff Brown9c3cda02010-06-15 01:31:58 -0700939 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700940 if (result) {
941 jniThrowRuntimeException(env, "Input manager could not be started.");
942 }
943}
944
945static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
946 jint displayId, jint width, jint height) {
947 if (checkInputManagerUnitialized(env)) {
948 return;
949 }
950
951 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
952 // to be passed in like this, not sure which is better but leaving it like this
953 // keeps the window manager in direct control of when display transitions propagate down
954 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700955 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700956}
957
958static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
959 jint displayId, jint orientation) {
960 if (checkInputManagerUnitialized(env)) {
961 return;
962 }
963
Jeff Brown9c3cda02010-06-15 01:31:58 -0700964 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700965}
966
967static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700968 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700969 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700970 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700971 }
972
Jeff Brownb88102f2010-09-08 11:49:43 -0700973 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700974 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700975}
976
977static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700978 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700979 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700980 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700981 }
982
Jeff Brownb88102f2010-09-08 11:49:43 -0700983 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700984 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700985}
986
987static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700988 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700989 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700990 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700991 }
992
Jeff Brownb88102f2010-09-08 11:49:43 -0700993 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700994 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700995}
996
997static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700998 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700999 if (checkInputManagerUnitialized(env)) {
1000 return JNI_FALSE;
1001 }
1002
1003 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1004 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1005 jsize numCodes = env->GetArrayLength(keyCodes);
1006 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001007 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001008 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001009 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001010 } else {
1011 result = JNI_FALSE;
1012 }
1013
1014 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1015 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1016 return result;
1017}
1018
1019static void throwInputChannelNotInitialized(JNIEnv* env) {
1020 jniThrowException(env, "java/lang/IllegalStateException",
1021 "inputChannel is not initialized");
1022}
1023
1024static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1025 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1026 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1027 "the input manager!", inputChannel->getName().string());
1028
Jeff Brown9c3cda02010-06-15 01:31:58 -07001029 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001030 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001031 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001032}
1033
1034static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001035 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001036 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
Jeff Brown928e0542011-01-10 11:17:36 -08001047 sp<InputWindowHandle> inputWindowHandle =
1048 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001049
1050 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001051 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001052 if (status) {
1053 jniThrowRuntimeException(env, "Failed to register input channel. "
1054 "Check logs for details.");
1055 return;
1056 }
1057
Jeff Browna41ca772010-08-11 14:46:32 -07001058 if (! monitor) {
1059 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1060 android_server_InputManager_handleInputChannelDisposed, NULL);
1061 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001062}
1063
1064static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1065 jobject inputChannelObj) {
1066 if (checkInputManagerUnitialized(env)) {
1067 return;
1068 }
1069
1070 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1071 inputChannelObj);
1072 if (inputChannel == NULL) {
1073 throwInputChannelNotInitialized(env);
1074 return;
1075 }
1076
1077 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1078
Jeff Brown7fbdc842010-06-17 20:52:56 -07001079 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001080 if (status) {
1081 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1082 "Check logs for details.");
1083 }
1084}
1085
Jeff Brown0029c662011-03-30 02:25:18 -07001086static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
1087 jboolean enabled) {
1088 if (checkInputManagerUnitialized(env)) {
1089 return;
1090 }
1091
1092 gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1093}
1094
Jeff Brown6ec402b2010-07-28 15:48:59 -07001095static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1096 jobject inputEventObj, jint injectorPid, jint injectorUid,
Jeff Brown0029c662011-03-30 02:25:18 -07001097 jint syncMode, jint timeoutMillis, jint policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001098 if (checkInputManagerUnitialized(env)) {
1099 return INPUT_EVENT_INJECTION_FAILED;
1100 }
1101
Jeff Brown6ec402b2010-07-28 15:48:59 -07001102 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1103 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001104 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1105 if (status) {
1106 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1107 return INPUT_EVENT_INJECTION_FAILED;
1108 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001109
Jeff Brownb88102f2010-09-08 11:49:43 -07001110 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001111 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1112 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001113 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001114 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1115 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001116 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1117 return INPUT_EVENT_INJECTION_FAILED;
1118 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001119
Jeff Brownb88102f2010-09-08 11:49:43 -07001120 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001121 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1122 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001123 } else {
1124 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001125 return INPUT_EVENT_INJECTION_FAILED;
1126 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001127}
1128
Jeff Brown349703e2010-06-22 01:27:15 -07001129static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1130 jobjectArray windowObjArray) {
1131 if (checkInputManagerUnitialized(env)) {
1132 return;
1133 }
1134
1135 gNativeInputManager->setInputWindows(env, windowObjArray);
1136}
1137
1138static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1139 jobject applicationObj) {
1140 if (checkInputManagerUnitialized(env)) {
1141 return;
1142 }
1143
1144 gNativeInputManager->setFocusedApplication(env, applicationObj);
1145}
1146
1147static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1148 jclass clazz, jboolean enabled, jboolean frozen) {
1149 if (checkInputManagerUnitialized(env)) {
1150 return;
1151 }
1152
1153 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1154}
1155
Jeff Brown05dc66a2011-03-02 14:41:58 -08001156static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1157 jclass clazz, jint visibility) {
1158 if (checkInputManagerUnitialized(env)) {
1159 return;
1160 }
1161
1162 gNativeInputManager->setSystemUiVisibility(visibility);
1163}
1164
Jeff Brown8d608662010-08-30 03:02:23 -07001165static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1166 jclass clazz, jint deviceId) {
1167 if (checkInputManagerUnitialized(env)) {
1168 return NULL;
1169 }
1170
1171 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001172 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001173 deviceId, & deviceInfo);
1174 if (status) {
1175 return NULL;
1176 }
1177
1178 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1179 if (! deviceObj) {
1180 return NULL;
1181 }
1182
1183 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1184 if (! deviceNameObj) {
1185 return NULL;
1186 }
1187
1188 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1189 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1190 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1191 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1192
Jeff Brownefd32662011-03-08 15:13:06 -08001193 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001194 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001195 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001196 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001197 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001198 if (env->ExceptionCheck()) {
1199 return NULL;
1200 }
1201 }
1202
1203 return deviceObj;
1204}
1205
1206static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1207 jclass clazz) {
1208 if (checkInputManagerUnitialized(env)) {
1209 return NULL;
1210 }
1211
1212 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001213 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001214
1215 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1216 if (! deviceIdsObj) {
1217 return NULL;
1218 }
1219
1220 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1221 return deviceIdsObj;
1222}
1223
Jeff Brown57c59372010-09-21 18:22:55 -07001224static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1225 jclass clazz, jobject configObj) {
1226 if (checkInputManagerUnitialized(env)) {
1227 return;
1228 }
1229
1230 InputConfiguration config;
1231 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1232
1233 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1234 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1235 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1236}
1237
Jeff Browne6504122010-09-27 14:52:15 -07001238static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1239 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1240 if (checkInputManagerUnitialized(env)) {
1241 return false;
1242 }
1243
1244 sp<InputChannel> fromChannel =
1245 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1246 sp<InputChannel> toChannel =
1247 android_view_InputChannel_getInputChannel(env, toChannelObj);
1248
1249 if (fromChannel == NULL || toChannel == NULL) {
1250 return false;
1251 }
1252
1253 return gNativeInputManager->getInputManager()->getDispatcher()->
1254 transferTouchFocus(fromChannel, toChannel);
1255}
1256
Jeff Browne33348b2010-07-15 23:54:05 -07001257static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1258 if (checkInputManagerUnitialized(env)) {
1259 return NULL;
1260 }
1261
Jeff Brownb88102f2010-09-08 11:49:43 -07001262 String8 dump;
1263 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001264 return env->NewStringUTF(dump.string());
1265}
1266
Jeff Brown9c3cda02010-06-15 01:31:58 -07001267// ----------------------------------------------------------------------------
1268
Jeff Brown46b9ac02010-04-22 18:58:52 -07001269static JNINativeMethod gInputManagerMethods[] = {
1270 /* name, signature, funcPtr */
Jeff Brown2352b972011-04-12 22:39:53 -07001271 { "nativeInit", "(Landroid/content/Context;"
1272 "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001273 (void*) android_server_InputManager_nativeInit },
1274 { "nativeStart", "()V",
1275 (void*) android_server_InputManager_nativeStart },
1276 { "nativeSetDisplaySize", "(III)V",
1277 (void*) android_server_InputManager_nativeSetDisplaySize },
1278 { "nativeSetDisplayOrientation", "(II)V",
1279 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1280 { "nativeGetScanCodeState", "(III)I",
1281 (void*) android_server_InputManager_nativeGetScanCodeState },
1282 { "nativeGetKeyCodeState", "(III)I",
1283 (void*) android_server_InputManager_nativeGetKeyCodeState },
1284 { "nativeGetSwitchState", "(III)I",
1285 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001286 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001287 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001288 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001289 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001290 (void*) android_server_InputManager_nativeRegisterInputChannel },
1291 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001292 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown0029c662011-03-30 02:25:18 -07001293 { "nativeSetInputFilterEnabled", "(Z)V",
1294 (void*) android_server_InputManager_nativeSetInputFilterEnabled },
1295 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
Jeff Brown6ec402b2010-07-28 15:48:59 -07001296 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001297 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001298 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001299 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001300 (void*) android_server_InputManager_nativeSetFocusedApplication },
1301 { "nativeSetInputDispatchMode", "(ZZ)V",
1302 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001303 { "nativeSetSystemUiVisibility", "(I)V",
1304 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001305 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1306 (void*) android_server_InputManager_nativeGetInputDevice },
1307 { "nativeGetInputDeviceIds", "()[I",
1308 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001309 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1310 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001311 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1312 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001313 { "nativeDump", "()Ljava/lang/String;",
1314 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001315};
1316
1317#define FIND_CLASS(var, className) \
1318 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001319 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001320
1321#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1322 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1323 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1324
1325#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1326 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1327 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1328
1329int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001330 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001331 gInputManagerMethods, NELEM(gInputManagerMethods));
1332 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1333
Jeff Brown9c3cda02010-06-15 01:31:58 -07001334 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001335
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001336 jclass clazz;
1337 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001338
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001339 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001340 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001341
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001342 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001343 "notifyLidSwitchChanged", "(JZ)V");
1344
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001345 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001346 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001347
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001348 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001349 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001350 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001351
Jeff Brown0029c662011-03-30 02:25:18 -07001352 GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
1353 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1354
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001355 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001356 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001357
Jeff Brown56194eb2011-03-02 19:23:13 -08001358 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001359 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001360 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1361
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001362 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001363 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001364 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001365
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001366 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001367 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001368 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001369
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001370 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001371 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001372
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001373 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001374 "filterTouchEvents", "()Z");
1375
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001376 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001377 "filterJumpyTouchEvents", "()Z");
1378
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001379 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001380 "getVirtualKeyQuietTimeMillis", "()I");
1381
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001382 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001383 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1384
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001385 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001386 "getKeyRepeatTimeout", "()I");
1387
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001388 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001389 "getKeyRepeatDelay", "()I");
1390
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001391 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001392 "getMaxEventsPerSecond", "()I");
1393
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001394 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001395 "getPointerLayer", "()I");
1396
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001397 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Jeff Brown2352b972011-04-12 22:39:53 -07001398 "getPointerIcon", "()Landroid/view/PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001399
Jeff Brown6ec402b2010-07-28 15:48:59 -07001400 // KeyEvent
1401
1402 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001403 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1404
Jeff Brown6ec402b2010-07-28 15:48:59 -07001405
Jeff Brown8d608662010-08-30 03:02:23 -07001406 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001407
1408 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001409 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001410
Jeff Brown8d608662010-08-30 03:02:23 -07001411 // InputDevice
1412
1413 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001414 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001415
1416 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1417 "<init>", "()V");
1418
1419 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001420 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001421
1422 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1423 "mId", "I");
1424
1425 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1426 "mName", "Ljava/lang/String;");
1427
1428 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1429 "mSources", "I");
1430
1431 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1432 "mKeyboardType", "I");
1433
Jeff Brown57c59372010-09-21 18:22:55 -07001434 // Configuration
1435
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001436 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001437
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001438 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001439 "touchscreen", "I");
1440
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001441 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001442 "keyboard", "I");
1443
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001444 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001445 "navigation", "I");
1446
Jeff Brown46b9ac02010-04-22 18:58:52 -07001447 return 0;
1448}
1449
Jeff Brown46b9ac02010-04-22 18:58:52 -07001450} /* namespace android */