blob: aaa305e91dc2dd30f3b6cfa66dbae0afe29b625f [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/SpotController.h>
40#include <input/SpriteController.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080041
Jeff Brown05dc66a2011-03-02 14:41:58 -080042#include <android_os_MessageQueue.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080043#include <android_view_KeyEvent.h>
44#include <android_view_MotionEvent.h>
45#include <android_view_InputChannel.h>
46#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 Brownb4ff35d2011-01-02 16:37:43 -0800104static struct {
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800105 jfieldID bitmap;
106 jfieldID hotSpotX;
107 jfieldID hotSpotY;
108} gPointerIconClassInfo;
Jeff Brown83c09682010-12-23 17:50:18 -0800109
Jeff Brown928e0542011-01-10 11:17:36 -0800110
111// --- Global functions ---
112
113static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
114 const sp<InputApplicationHandle>& inputApplicationHandle) {
115 if (inputApplicationHandle == NULL) {
116 return NULL;
117 }
118 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
119 getInputApplicationHandleObjLocalRef(env);
120}
121
122static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
123 const sp<InputWindowHandle>& inputWindowHandle) {
124 if (inputWindowHandle == NULL) {
125 return NULL;
126 }
127 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
128 getInputWindowHandleObjLocalRef(env);
129}
130
131
132// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800133
Jeff Brown9c3cda02010-06-15 01:31:58 -0700134class NativeInputManager : public virtual RefBase,
135 public virtual InputReaderPolicyInterface,
136 public virtual InputDispatcherPolicyInterface {
137protected:
138 virtual ~NativeInputManager();
139
140public:
Jeff Brown05dc66a2011-03-02 14:41:58 -0800141 NativeInputManager(jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700142
143 inline sp<InputManager> getInputManager() const { return mInputManager; }
144
Jeff Brownb88102f2010-09-08 11:49:43 -0700145 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700146
Jeff Brown9c3cda02010-06-15 01:31:58 -0700147 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
148 void setDisplayOrientation(int32_t displayId, int32_t orientation);
149
Jeff Brown7fbdc842010-06-17 20:52:56 -0700150 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800151 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700152 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
153
Jeff Brown349703e2010-06-22 01:27:15 -0700154 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
155 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
156 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800157 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700158
Jeff Brown9c3cda02010-06-15 01:31:58 -0700159 /* --- InputReaderPolicyInterface implementation --- */
160
161 virtual bool getDisplayInfo(int32_t displayId,
162 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700163 virtual bool filterTouchEvents();
164 virtual bool filterJumpyTouchEvents();
Jeff Brownfe508922011-01-18 15:10:10 -0800165 virtual nsecs_t getVirtualKeyQuietTime();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700166 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800167 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown5541de92011-04-11 11:54:25 -0700168 virtual sp<SpotControllerInterface> obtainSpotController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700169
170 /* --- InputDispatcherPolicyInterface implementation --- */
171
Jeff Browne20c9e02010-10-11 14:20:19 -0700172 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
173 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700174 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700175 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800176 const sp<InputWindowHandle>& inputWindowHandle);
177 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700178 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700179 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700180 virtual int32_t getMaxEventsPerSecond();
Jeff Brown0029c662011-03-30 02:25:18 -0700181 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800182 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800183 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800184 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700185 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800186 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800187 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700188 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700189 virtual bool checkInjectEventsPermissionNonReentrant(
190 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700191
192private:
193 sp<InputManager> mInputManager;
194
195 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800196 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197
198 // Cached filtering policies.
199 int32_t mFilterTouchEvents;
200 int32_t mFilterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -0800201 nsecs_t mVirtualKeyQuietTime;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700202
Jeff Browna4547672011-03-02 21:38:11 -0800203 // Cached key repeat policy.
204 nsecs_t mKeyRepeatTimeout;
205 nsecs_t mKeyRepeatDelay;
206
Jeff Brownae9fc032010-08-18 15:51:08 -0700207 // Cached throttling policy.
208 int32_t mMaxEventsPerSecond;
209
Jeff Brown83c09682010-12-23 17:50:18 -0800210 Mutex mLock;
211 struct Locked {
212 // Display size information.
213 int32_t displayWidth, displayHeight; // -1 when initialized
214 int32_t displayOrientation;
215
Jeff Brown05dc66a2011-03-02 14:41:58 -0800216 // System UI visibility.
217 int32_t systemUiVisibility;
218
Jeff Brown5541de92011-04-11 11:54:25 -0700219 // Sprite controller singleton, created on first use.
220 sp<SpriteController> spriteController;
221
Jeff Brown83c09682010-12-23 17:50:18 -0800222 // Pointer controller singleton, created and destroyed as needed.
223 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800224 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700225
Jeff Brown05dc66a2011-03-02 14:41:58 -0800226 void updateInactivityFadeDelayLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800227 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown5541de92011-04-11 11:54:25 -0700228 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800229
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700230 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700231 bool isScreenOn();
232 bool isScreenBright();
233
Jeff Brownb88102f2010-09-08 11:49:43 -0700234 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700235
Jeff Brown9c3cda02010-06-15 01:31:58 -0700236 static inline JNIEnv* jniEnv() {
237 return AndroidRuntime::getJNIEnv();
238 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700239};
240
Jeff Brown928e0542011-01-10 11:17:36 -0800241
Jeff Brown9c3cda02010-06-15 01:31:58 -0700242
Jeff Brown05dc66a2011-03-02 14:41:58 -0800243NativeInputManager::NativeInputManager(jobject callbacksObj, const sp<Looper>& looper) :
244 mLooper(looper),
245 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
Jeff Browna4547672011-03-02 21:38:11 -0800246 mKeyRepeatTimeout(-1), mKeyRepeatDelay(-1),
Jeff Brown05dc66a2011-03-02 14:41:58 -0800247 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700248 JNIEnv* env = jniEnv();
249
250 mCallbacksObj = env->NewGlobalRef(callbacksObj);
251
Jeff Brown83c09682010-12-23 17:50:18 -0800252 {
253 AutoMutex _l(mLock);
254 mLocked.displayWidth = -1;
255 mLocked.displayHeight = -1;
256 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800257
258 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800259 }
260
Jeff Brown9c3cda02010-06-15 01:31:58 -0700261 sp<EventHub> eventHub = new EventHub();
262 mInputManager = new InputManager(eventHub, this, this);
263}
264
265NativeInputManager::~NativeInputManager() {
266 JNIEnv* env = jniEnv();
267
268 env->DeleteGlobalRef(mCallbacksObj);
269}
270
Jeff Brownb88102f2010-09-08 11:49:43 -0700271void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700272 mInputManager->getReader()->dump(dump);
273 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700274
Jeff Brownb88102f2010-09-08 11:49:43 -0700275 mInputManager->getDispatcher()->dump(dump);
276 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700277}
278
Jeff Brown7fbdc842010-06-17 20:52:56 -0700279bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700280 if (env->ExceptionCheck()) {
281 LOGE("An exception was thrown by callback '%s'.", methodName);
282 LOGE_EX(env);
283 env->ExceptionClear();
284 return true;
285 }
286 return false;
287}
288
289void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
290 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800291 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700292
Jeff Brown83c09682010-12-23 17:50:18 -0800293 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
294 mLocked.displayWidth = width;
295 mLocked.displayHeight = height;
296
297 sp<PointerController> controller = mLocked.pointerController.promote();
298 if (controller != NULL) {
299 controller->setDisplaySize(width, height);
300 }
301 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700302 }
303}
304
305void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
306 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800307 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700308
Jeff Brown83c09682010-12-23 17:50:18 -0800309 if (mLocked.displayOrientation != orientation) {
310 mLocked.displayOrientation = orientation;
311
312 sp<PointerController> controller = mLocked.pointerController.promote();
313 if (controller != NULL) {
314 controller->setDisplayOrientation(orientation);
315 }
316 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700317 }
318}
319
Jeff Brown7fbdc842010-06-17 20:52:56 -0700320status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800321 const sp<InputChannel>& inputChannel,
322 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
323 return mInputManager->getDispatcher()->registerInputChannel(
324 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700325}
326
327status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
328 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700329 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700330}
331
Jeff Brown9c3cda02010-06-15 01:31:58 -0700332bool NativeInputManager::getDisplayInfo(int32_t displayId,
333 int32_t* width, int32_t* height, int32_t* orientation) {
334 bool result = false;
335 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800336 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700337
Jeff Brown83c09682010-12-23 17:50:18 -0800338 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700339 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800340 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700341 }
342 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800343 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700344 }
345 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800346 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700347 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700348 result = true;
349 }
350 }
351 return result;
352}
353
Jeff Brown9c3cda02010-06-15 01:31:58 -0700354bool NativeInputManager::filterTouchEvents() {
355 if (mFilterTouchEvents < 0) {
356 JNIEnv* env = jniEnv();
357
358 jboolean result = env->CallBooleanMethod(mCallbacksObj,
359 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700360 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700361 result = false;
362 }
363
364 mFilterTouchEvents = result ? 1 : 0;
365 }
366 return mFilterTouchEvents;
367}
368
369bool NativeInputManager::filterJumpyTouchEvents() {
370 if (mFilterJumpyTouchEvents < 0) {
371 JNIEnv* env = jniEnv();
372
373 jboolean result = env->CallBooleanMethod(mCallbacksObj,
374 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700375 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700376 result = false;
377 }
378
379 mFilterJumpyTouchEvents = result ? 1 : 0;
380 }
381 return mFilterJumpyTouchEvents;
382}
383
Jeff Brownfe508922011-01-18 15:10:10 -0800384nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
385 if (mVirtualKeyQuietTime < 0) {
386 JNIEnv* env = jniEnv();
387
388 jint result = env->CallIntMethod(mCallbacksObj,
389 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
390 if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
391 result = 0;
392 }
393 if (result < 0) {
394 result = 0;
395 }
396
397 mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
398 }
399 return mVirtualKeyQuietTime;
400}
401
Jeff Brown9c3cda02010-06-15 01:31:58 -0700402void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700403 outExcludedDeviceNames.clear();
404
Jeff Brown9c3cda02010-06-15 01:31:58 -0700405 JNIEnv* env = jniEnv();
406
407 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
408 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700409 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700410 jsize length = env->GetArrayLength(result);
411 for (jsize i = 0; i < length; i++) {
412 jstring item = jstring(env->GetObjectArrayElement(result, i));
413
414 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
415 outExcludedDeviceNames.add(String8(deviceNameChars));
416 env->ReleaseStringUTFChars(item, deviceNameChars);
417
418 env->DeleteLocalRef(item);
419 }
420 env->DeleteLocalRef(result);
421 }
422}
423
Jeff Brown83c09682010-12-23 17:50:18 -0800424sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
425 AutoMutex _l(mLock);
426
427 sp<PointerController> controller = mLocked.pointerController.promote();
428 if (controller == NULL) {
Jeff Brown5541de92011-04-11 11:54:25 -0700429 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800430
Jeff Brown5541de92011-04-11 11:54:25 -0700431 controller = new PointerController(mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800432 mLocked.pointerController = controller;
433
434 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
435 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800436
Jeff Brown5541de92011-04-11 11:54:25 -0700437 JNIEnv* env = jniEnv();
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800438 jobject iconObj = env->CallObjectMethod(mCallbacksObj, gCallbacksClassInfo.getPointerIcon);
439 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon") && iconObj) {
440 jfloat iconHotSpotX = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotX);
441 jfloat iconHotSpotY = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotY);
442 jobject iconBitmapObj = env->GetObjectField(iconObj, gPointerIconClassInfo.bitmap);
443 if (iconBitmapObj) {
444 SkBitmap* iconBitmap = GraphicsJNI::getNativeBitmap(env, iconBitmapObj);
445 if (iconBitmap) {
446 controller->setPointerIcon(iconBitmap, iconHotSpotX, iconHotSpotY);
447 }
448 env->DeleteLocalRef(iconBitmapObj);
449 }
450 env->DeleteLocalRef(iconObj);
451 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800452
453 updateInactivityFadeDelayLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800454 }
455 return controller;
456}
457
Jeff Brown5541de92011-04-11 11:54:25 -0700458sp<SpotControllerInterface> NativeInputManager::obtainSpotController(int32_t deviceId) {
459 AutoMutex _l(mLock);
460
461 ensureSpriteControllerLocked();
462 return new SpotController(mLooper, mLocked.spriteController);
463}
464
465void NativeInputManager::ensureSpriteControllerLocked() {
466 if (mLocked.spriteController == NULL) {
467 JNIEnv* env = jniEnv();
468 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
469 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
470 layer = -1;
471 }
472 mLocked.spriteController = new SpriteController(mLooper, layer);
473 }
474}
475
Jeff Browne20c9e02010-10-11 14:20:19 -0700476void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
477 int32_t switchValue, uint32_t policyFlags) {
478#if DEBUG_INPUT_DISPATCHER_POLICY
479 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
480 when, switchCode, switchValue, policyFlags);
481#endif
482
483 JNIEnv* env = jniEnv();
484
485 switch (switchCode) {
486 case SW_LID:
487 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
488 when, switchValue == 0);
489 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
490 break;
491 }
492}
493
Jeff Brown9c3cda02010-06-15 01:31:58 -0700494void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
495#if DEBUG_INPUT_DISPATCHER_POLICY
496 LOGD("notifyConfigurationChanged - when=%lld", when);
497#endif
498
499 JNIEnv* env = jniEnv();
500
Jeff Brown57c59372010-09-21 18:22:55 -0700501 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700502 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700503}
504
Jeff Brown519e0242010-09-15 15:18:56 -0700505nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800506 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700507#if DEBUG_INPUT_DISPATCHER_POLICY
508 LOGD("notifyANR");
509#endif
510
511 JNIEnv* env = jniEnv();
512
Jeff Brown928e0542011-01-10 11:17:36 -0800513 jobject inputApplicationHandleObj =
514 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
515 jobject inputWindowHandleObj =
516 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700517
Jeff Brown519e0242010-09-15 15:18:56 -0700518 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800519 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700520 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
521 newTimeout = 0; // abort dispatch
522 } else {
523 assert(newTimeout >= 0);
524 }
525
Jeff Brown928e0542011-01-10 11:17:36 -0800526 env->DeleteLocalRef(inputWindowHandleObj);
527 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700528 return newTimeout;
529}
530
Jeff Brown928e0542011-01-10 11:17:36 -0800531void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700532#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800533 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700534#endif
535
Jeff Brown7fbdc842010-06-17 20:52:56 -0700536 JNIEnv* env = jniEnv();
537
Jeff Brown928e0542011-01-10 11:17:36 -0800538 jobject inputWindowHandleObj =
539 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
540 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700541 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800542 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700543 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
544
Jeff Brown928e0542011-01-10 11:17:36 -0800545 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700546 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700547}
548
Jeff Brown9c3cda02010-06-15 01:31:58 -0700549nsecs_t NativeInputManager::getKeyRepeatTimeout() {
550 if (! isScreenOn()) {
551 // Disable key repeat when the screen is off.
552 return -1;
553 } else {
Jeff Browna4547672011-03-02 21:38:11 -0800554 if (mKeyRepeatTimeout < 0) {
555 JNIEnv* env = jniEnv();
556
557 jint result = env->CallIntMethod(mCallbacksObj,
558 gCallbacksClassInfo.getKeyRepeatTimeout);
559 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
560 result = 500;
561 }
562
563 mKeyRepeatTimeout = milliseconds_to_nanoseconds(result);
564 }
565 return mKeyRepeatTimeout;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700566 }
567}
568
Jeff Brownb21fb102010-09-07 10:44:57 -0700569nsecs_t NativeInputManager::getKeyRepeatDelay() {
Jeff Browna4547672011-03-02 21:38:11 -0800570 if (mKeyRepeatDelay < 0) {
571 JNIEnv* env = jniEnv();
572
573 jint result = env->CallIntMethod(mCallbacksObj,
574 gCallbacksClassInfo.getKeyRepeatDelay);
575 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
576 result = 50;
577 }
578
579 mKeyRepeatDelay = milliseconds_to_nanoseconds(result);
580 }
581 return mKeyRepeatDelay;
Jeff Brownb21fb102010-09-07 10:44:57 -0700582}
583
Jeff Brownae9fc032010-08-18 15:51:08 -0700584int32_t NativeInputManager::getMaxEventsPerSecond() {
585 if (mMaxEventsPerSecond < 0) {
586 JNIEnv* env = jniEnv();
587
588 jint result = env->CallIntMethod(mCallbacksObj,
589 gCallbacksClassInfo.getMaxEventsPerSecond);
590 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700591 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700592 }
593
594 mMaxEventsPerSecond = result;
595 }
596 return mMaxEventsPerSecond;
597}
598
Jeff Brown349703e2010-06-22 01:27:15 -0700599void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700600 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700601
Jeff Brownb88102f2010-09-08 11:49:43 -0700602 jsize length = env->GetArrayLength(windowObjArray);
603 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800604 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
605 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700606 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700607 }
608
Jeff Brownb88102f2010-09-08 11:49:43 -0700609 windows.push();
610 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800611 android_server_InputWindow_toNative(env, windowObj, &window);
612 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700613 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700614 }
Jeff Brown928e0542011-01-10 11:17:36 -0800615 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700616 }
Jeff Brown349703e2010-06-22 01:27:15 -0700617
Jeff Brownb88102f2010-09-08 11:49:43 -0700618 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700619}
620
Jeff Brown349703e2010-06-22 01:27:15 -0700621void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700622 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700623 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800624 android_server_InputApplication_toNative(env, applicationObj, &application);
625 if (application.inputApplicationHandle != NULL) {
626 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Browna2cc28d2011-03-25 11:58:46 -0700627 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800628 }
Jeff Brown349703e2010-06-22 01:27:15 -0700629 }
Jeff Brown928e0542011-01-10 11:17:36 -0800630 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700631}
632
633void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700634 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700635}
636
Jeff Brown05dc66a2011-03-02 14:41:58 -0800637void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
638 AutoMutex _l(mLock);
639
640 if (mLocked.systemUiVisibility != visibility) {
641 mLocked.systemUiVisibility = visibility;
642
643 sp<PointerController> controller = mLocked.pointerController.promote();
644 if (controller != NULL) {
645 updateInactivityFadeDelayLocked(controller);
646 }
647 }
648}
649
650void NativeInputManager::updateInactivityFadeDelayLocked(const sp<PointerController>& controller) {
651 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
652 controller->setInactivityFadeDelay(lightsOut
653 ? PointerController::INACTIVITY_FADE_DELAY_SHORT
654 : PointerController::INACTIVITY_FADE_DELAY_NORMAL);
655}
656
Jeff Browne20c9e02010-10-11 14:20:19 -0700657bool NativeInputManager::isScreenOn() {
658 return android_server_PowerManagerService_isScreenOn();
659}
660
661bool NativeInputManager::isScreenBright() {
662 return android_server_PowerManagerService_isScreenBright();
663}
664
Jeff Brown0029c662011-03-30 02:25:18 -0700665bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
666 jobject inputEventObj;
667
668 JNIEnv* env = jniEnv();
669 switch (inputEvent->getType()) {
670 case AINPUT_EVENT_TYPE_KEY:
671 inputEventObj = android_view_KeyEvent_fromNative(env,
672 static_cast<const KeyEvent*>(inputEvent));
673 break;
674 case AINPUT_EVENT_TYPE_MOTION:
675 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
676 static_cast<const MotionEvent*>(inputEvent));
677 break;
678 default:
679 return true; // dispatch the event normally
680 }
681
682 if (!inputEventObj) {
683 LOGE("Failed to obtain input event object for filterInputEvent.");
684 return true; // dispatch the event normally
685 }
686
687 // The callee is responsible for recycling the event.
688 jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
689 inputEventObj, policyFlags);
690 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
691 pass = true;
692 }
693 env->DeleteLocalRef(inputEventObj);
694 return pass;
695}
696
Jeff Brown1f245102010-11-18 20:53:46 -0800697void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
698 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700699 // Policy:
700 // - Ignore untrusted events and pass them along.
701 // - Ask the window manager what to do with normal events and trusted injected events.
702 // - For normal events wake and brighten the screen if currently off or dim.
703 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800704 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700705 bool isScreenOn = this->isScreenOn();
706 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700707
Jeff Brown3122e442010-10-11 23:32:49 -0700708 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800709 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
710 jint wmActions;
711 if (keyEventObj) {
712 wmActions = env->CallIntMethod(mCallbacksObj,
713 gCallbacksClassInfo.interceptKeyBeforeQueueing,
714 keyEventObj, policyFlags, isScreenOn);
715 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
716 wmActions = 0;
717 }
718 android_view_KeyEvent_recycle(env, keyEventObj);
719 env->DeleteLocalRef(keyEventObj);
720 } else {
721 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700722 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700723 }
724
Jeff Brown1f245102010-11-18 20:53:46 -0800725 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700726 if (!isScreenOn) {
727 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700728 }
729
730 if (!isScreenBright) {
731 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
732 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700733 }
734
Jeff Brown56194eb2011-03-02 19:23:13 -0800735 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700736 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700737 policyFlags |= POLICY_FLAG_PASS_TO_USER;
738 }
739}
740
Jeff Brown56194eb2011-03-02 19:23:13 -0800741void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700742 // Policy:
743 // - Ignore untrusted events and pass them along.
744 // - No special filtering for injected events required at this time.
745 // - Filter normal events based on screen state.
746 // - For normal events brighten (but do not wake) the screen if currently dim.
747 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
748 if (isScreenOn()) {
749 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700750
Jeff Brown3122e442010-10-11 23:32:49 -0700751 if (!isScreenBright()) {
752 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
753 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800754 } else {
755 JNIEnv* env = jniEnv();
756 jint wmActions = env->CallIntMethod(mCallbacksObj,
757 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
758 policyFlags);
759 if (checkAndClearExceptionFromCallback(env,
760 "interceptMotionBeforeQueueingWhenScreenOff")) {
761 wmActions = 0;
762 }
763
764 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
765 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700766 }
Jeff Brown3122e442010-10-11 23:32:49 -0700767 } else {
768 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700769 }
770}
771
Jeff Brown56194eb2011-03-02 19:23:13 -0800772void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
773 uint32_t& policyFlags) {
774 enum {
775 WM_ACTION_PASS_TO_USER = 1,
776 WM_ACTION_POKE_USER_ACTIVITY = 2,
777 WM_ACTION_GO_TO_SLEEP = 4,
778 };
779
780 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800781#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800782 LOGD("handleInterceptActions: Going to sleep.");
783#endif
784 android_server_PowerManagerService_goToSleep(when);
785 }
786
787 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800788#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800789 LOGD("handleInterceptActions: Poking user activity.");
790#endif
791 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
792 }
793
794 if (wmActions & WM_ACTION_PASS_TO_USER) {
795 policyFlags |= POLICY_FLAG_PASS_TO_USER;
796 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800797#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800798 LOGD("handleInterceptActions: Not passing key to user.");
799#endif
800 }
801}
802
Jeff Brown928e0542011-01-10 11:17:36 -0800803bool NativeInputManager::interceptKeyBeforeDispatching(
804 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700805 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700806 // Policy:
807 // - Ignore untrusted events and pass them along.
808 // - Filter normal events and trusted injected events through the window manager policy to
809 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800810 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700811 if (policyFlags & POLICY_FLAG_TRUSTED) {
812 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700813
Jeff Brown928e0542011-01-10 11:17:36 -0800814 // Note: inputWindowHandle may be null.
815 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800816 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
817 if (keyEventObj) {
818 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
819 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800820 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800821 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
822 android_view_KeyEvent_recycle(env, keyEventObj);
823 env->DeleteLocalRef(keyEventObj);
824 result = consumed && !error;
825 } else {
826 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800827 }
Jeff Brown928e0542011-01-10 11:17:36 -0800828 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700829 }
Jeff Brown1f245102010-11-18 20:53:46 -0800830 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700831}
832
Jeff Brown928e0542011-01-10 11:17:36 -0800833bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800834 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700835 // Policy:
836 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800837 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700838 if (policyFlags & POLICY_FLAG_TRUSTED) {
839 JNIEnv* env = jniEnv();
840
Jeff Brown928e0542011-01-10 11:17:36 -0800841 // Note: inputWindowHandle may be null.
842 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800843 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
844 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800845 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800846 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800847 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700848 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
849 fallbackKeyEventObj = NULL;
850 }
Jeff Brown1f245102010-11-18 20:53:46 -0800851 android_view_KeyEvent_recycle(env, keyEventObj);
852 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800853
854 if (fallbackKeyEventObj) {
855 // Note: outFallbackKeyEvent may be the same object as keyEvent.
856 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
857 outFallbackKeyEvent)) {
858 result = true;
859 }
860 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
861 env->DeleteLocalRef(fallbackKeyEventObj);
862 }
Jeff Brown1f245102010-11-18 20:53:46 -0800863 } else {
864 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800865 }
Jeff Brown928e0542011-01-10 11:17:36 -0800866 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700867 }
Jeff Brown1f245102010-11-18 20:53:46 -0800868 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700869}
870
Jeff Brown01ce2e92010-09-26 22:20:12 -0700871void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
872 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700873}
874
Jeff Brown349703e2010-06-22 01:27:15 -0700875
Jeff Brownb88102f2010-09-08 11:49:43 -0700876bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
877 int32_t injectorPid, int32_t injectorUid) {
878 JNIEnv* env = jniEnv();
879 jboolean result = env->CallBooleanMethod(mCallbacksObj,
880 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700881 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
882 result = false;
883 }
Jeff Brown349703e2010-06-22 01:27:15 -0700884 return result;
885}
886
Jeff Brown83c09682010-12-23 17:50:18 -0800887
Jeff Brown9c3cda02010-06-15 01:31:58 -0700888// ----------------------------------------------------------------------------
889
890static sp<NativeInputManager> gNativeInputManager;
891
Jeff Brown46b9ac02010-04-22 18:58:52 -0700892static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700893 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700894 LOGE("Input manager not initialized.");
895 jniThrowRuntimeException(env, "Input manager not initialized.");
896 return true;
897 }
898 return false;
899}
900
901static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown05dc66a2011-03-02 14:41:58 -0800902 jobject callbacks, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700903 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800904 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
905 gNativeInputManager = new NativeInputManager(callbacks, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700906 } else {
907 LOGE("Input manager already initialized.");
908 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700909 }
910}
911
912static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
913 if (checkInputManagerUnitialized(env)) {
914 return;
915 }
916
Jeff Brown9c3cda02010-06-15 01:31:58 -0700917 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700918 if (result) {
919 jniThrowRuntimeException(env, "Input manager could not be started.");
920 }
921}
922
923static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
924 jint displayId, jint width, jint height) {
925 if (checkInputManagerUnitialized(env)) {
926 return;
927 }
928
929 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
930 // to be passed in like this, not sure which is better but leaving it like this
931 // keeps the window manager in direct control of when display transitions propagate down
932 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700933 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700934}
935
936static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
937 jint displayId, jint orientation) {
938 if (checkInputManagerUnitialized(env)) {
939 return;
940 }
941
Jeff Brown9c3cda02010-06-15 01:31:58 -0700942 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700943}
944
945static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700946 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700947 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700948 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700949 }
950
Jeff Brownb88102f2010-09-08 11:49:43 -0700951 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700952 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700953}
954
955static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700956 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700957 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700958 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700959 }
960
Jeff Brownb88102f2010-09-08 11:49:43 -0700961 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700962 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700963}
964
965static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700966 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700967 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700968 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700969 }
970
Jeff Brownb88102f2010-09-08 11:49:43 -0700971 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700972 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700973}
974
975static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700976 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700977 if (checkInputManagerUnitialized(env)) {
978 return JNI_FALSE;
979 }
980
981 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
982 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
983 jsize numCodes = env->GetArrayLength(keyCodes);
984 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700985 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700986 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700987 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700988 } else {
989 result = JNI_FALSE;
990 }
991
992 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
993 env->ReleaseIntArrayElements(keyCodes, codes, 0);
994 return result;
995}
996
997static void throwInputChannelNotInitialized(JNIEnv* env) {
998 jniThrowException(env, "java/lang/IllegalStateException",
999 "inputChannel is not initialized");
1000}
1001
1002static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1003 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1004 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1005 "the input manager!", inputChannel->getName().string());
1006
Jeff Brown9c3cda02010-06-15 01:31:58 -07001007 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001008 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001009 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001010}
1011
1012static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001013 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001014 if (checkInputManagerUnitialized(env)) {
1015 return;
1016 }
1017
1018 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1019 inputChannelObj);
1020 if (inputChannel == NULL) {
1021 throwInputChannelNotInitialized(env);
1022 return;
1023 }
1024
Jeff Brown928e0542011-01-10 11:17:36 -08001025 sp<InputWindowHandle> inputWindowHandle =
1026 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001027
1028 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001029 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001030 if (status) {
1031 jniThrowRuntimeException(env, "Failed to register input channel. "
1032 "Check logs for details.");
1033 return;
1034 }
1035
Jeff Browna41ca772010-08-11 14:46:32 -07001036 if (! monitor) {
1037 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1038 android_server_InputManager_handleInputChannelDisposed, NULL);
1039 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001040}
1041
1042static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1043 jobject inputChannelObj) {
1044 if (checkInputManagerUnitialized(env)) {
1045 return;
1046 }
1047
1048 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1049 inputChannelObj);
1050 if (inputChannel == NULL) {
1051 throwInputChannelNotInitialized(env);
1052 return;
1053 }
1054
1055 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1056
Jeff Brown7fbdc842010-06-17 20:52:56 -07001057 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001058 if (status) {
1059 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1060 "Check logs for details.");
1061 }
1062}
1063
Jeff Brown0029c662011-03-30 02:25:18 -07001064static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
1065 jboolean enabled) {
1066 if (checkInputManagerUnitialized(env)) {
1067 return;
1068 }
1069
1070 gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1071}
1072
Jeff Brown6ec402b2010-07-28 15:48:59 -07001073static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1074 jobject inputEventObj, jint injectorPid, jint injectorUid,
Jeff Brown0029c662011-03-30 02:25:18 -07001075 jint syncMode, jint timeoutMillis, jint policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001076 if (checkInputManagerUnitialized(env)) {
1077 return INPUT_EVENT_INJECTION_FAILED;
1078 }
1079
Jeff Brown6ec402b2010-07-28 15:48:59 -07001080 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1081 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001082 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1083 if (status) {
1084 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1085 return INPUT_EVENT_INJECTION_FAILED;
1086 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001087
Jeff Brownb88102f2010-09-08 11:49:43 -07001088 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001089 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1090 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001091 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001092 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1093 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001094 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1095 return INPUT_EVENT_INJECTION_FAILED;
1096 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001097
Jeff Brownb88102f2010-09-08 11:49:43 -07001098 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001099 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1100 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001101 } else {
1102 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001103 return INPUT_EVENT_INJECTION_FAILED;
1104 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001105}
1106
Jeff Brown349703e2010-06-22 01:27:15 -07001107static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1108 jobjectArray windowObjArray) {
1109 if (checkInputManagerUnitialized(env)) {
1110 return;
1111 }
1112
1113 gNativeInputManager->setInputWindows(env, windowObjArray);
1114}
1115
1116static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1117 jobject applicationObj) {
1118 if (checkInputManagerUnitialized(env)) {
1119 return;
1120 }
1121
1122 gNativeInputManager->setFocusedApplication(env, applicationObj);
1123}
1124
1125static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1126 jclass clazz, jboolean enabled, jboolean frozen) {
1127 if (checkInputManagerUnitialized(env)) {
1128 return;
1129 }
1130
1131 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1132}
1133
Jeff Brown05dc66a2011-03-02 14:41:58 -08001134static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1135 jclass clazz, jint visibility) {
1136 if (checkInputManagerUnitialized(env)) {
1137 return;
1138 }
1139
1140 gNativeInputManager->setSystemUiVisibility(visibility);
1141}
1142
Jeff Brown8d608662010-08-30 03:02:23 -07001143static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1144 jclass clazz, jint deviceId) {
1145 if (checkInputManagerUnitialized(env)) {
1146 return NULL;
1147 }
1148
1149 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001150 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001151 deviceId, & deviceInfo);
1152 if (status) {
1153 return NULL;
1154 }
1155
1156 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1157 if (! deviceObj) {
1158 return NULL;
1159 }
1160
1161 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1162 if (! deviceNameObj) {
1163 return NULL;
1164 }
1165
1166 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1167 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1168 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1169 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1170
Jeff Brownefd32662011-03-08 15:13:06 -08001171 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001172 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001173 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001174 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001175 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001176 if (env->ExceptionCheck()) {
1177 return NULL;
1178 }
1179 }
1180
1181 return deviceObj;
1182}
1183
1184static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1185 jclass clazz) {
1186 if (checkInputManagerUnitialized(env)) {
1187 return NULL;
1188 }
1189
1190 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001191 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001192
1193 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1194 if (! deviceIdsObj) {
1195 return NULL;
1196 }
1197
1198 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1199 return deviceIdsObj;
1200}
1201
Jeff Brown57c59372010-09-21 18:22:55 -07001202static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1203 jclass clazz, jobject configObj) {
1204 if (checkInputManagerUnitialized(env)) {
1205 return;
1206 }
1207
1208 InputConfiguration config;
1209 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1210
1211 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1212 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1213 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1214}
1215
Jeff Browne6504122010-09-27 14:52:15 -07001216static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1217 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1218 if (checkInputManagerUnitialized(env)) {
1219 return false;
1220 }
1221
1222 sp<InputChannel> fromChannel =
1223 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1224 sp<InputChannel> toChannel =
1225 android_view_InputChannel_getInputChannel(env, toChannelObj);
1226
1227 if (fromChannel == NULL || toChannel == NULL) {
1228 return false;
1229 }
1230
1231 return gNativeInputManager->getInputManager()->getDispatcher()->
1232 transferTouchFocus(fromChannel, toChannel);
1233}
1234
Jeff Browne33348b2010-07-15 23:54:05 -07001235static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1236 if (checkInputManagerUnitialized(env)) {
1237 return NULL;
1238 }
1239
Jeff Brownb88102f2010-09-08 11:49:43 -07001240 String8 dump;
1241 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001242 return env->NewStringUTF(dump.string());
1243}
1244
Jeff Brown9c3cda02010-06-15 01:31:58 -07001245// ----------------------------------------------------------------------------
1246
Jeff Brown46b9ac02010-04-22 18:58:52 -07001247static JNINativeMethod gInputManagerMethods[] = {
1248 /* name, signature, funcPtr */
Jeff Brown05dc66a2011-03-02 14:41:58 -08001249 { "nativeInit", "(Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001250 (void*) android_server_InputManager_nativeInit },
1251 { "nativeStart", "()V",
1252 (void*) android_server_InputManager_nativeStart },
1253 { "nativeSetDisplaySize", "(III)V",
1254 (void*) android_server_InputManager_nativeSetDisplaySize },
1255 { "nativeSetDisplayOrientation", "(II)V",
1256 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1257 { "nativeGetScanCodeState", "(III)I",
1258 (void*) android_server_InputManager_nativeGetScanCodeState },
1259 { "nativeGetKeyCodeState", "(III)I",
1260 (void*) android_server_InputManager_nativeGetKeyCodeState },
1261 { "nativeGetSwitchState", "(III)I",
1262 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001263 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001264 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001265 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001266 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001267 (void*) android_server_InputManager_nativeRegisterInputChannel },
1268 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001269 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown0029c662011-03-30 02:25:18 -07001270 { "nativeSetInputFilterEnabled", "(Z)V",
1271 (void*) android_server_InputManager_nativeSetInputFilterEnabled },
1272 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
Jeff Brown6ec402b2010-07-28 15:48:59 -07001273 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001274 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001275 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001276 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001277 (void*) android_server_InputManager_nativeSetFocusedApplication },
1278 { "nativeSetInputDispatchMode", "(ZZ)V",
1279 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001280 { "nativeSetSystemUiVisibility", "(I)V",
1281 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001282 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1283 (void*) android_server_InputManager_nativeGetInputDevice },
1284 { "nativeGetInputDeviceIds", "()[I",
1285 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001286 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1287 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001288 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1289 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001290 { "nativeDump", "()Ljava/lang/String;",
1291 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001292};
1293
1294#define FIND_CLASS(var, className) \
1295 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001296 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001297
1298#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1299 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1300 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1301
1302#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1303 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1304 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1305
1306int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001307 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001308 gInputManagerMethods, NELEM(gInputManagerMethods));
1309 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1310
Jeff Brown9c3cda02010-06-15 01:31:58 -07001311 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001312
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001313 jclass clazz;
1314 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001315
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001316 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001317 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001318
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001319 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001320 "notifyLidSwitchChanged", "(JZ)V");
1321
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001322 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001323 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001324
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001325 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001326 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001327 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001328
Jeff Brown0029c662011-03-30 02:25:18 -07001329 GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
1330 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1331
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001332 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001333 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001334
Jeff Brown56194eb2011-03-02 19:23:13 -08001335 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001336 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001337 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1338
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001339 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001340 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001341 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001342
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001343 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001344 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001345 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001346
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001347 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001348 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001349
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001350 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001351 "filterTouchEvents", "()Z");
1352
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001353 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001354 "filterJumpyTouchEvents", "()Z");
1355
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001356 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001357 "getVirtualKeyQuietTimeMillis", "()I");
1358
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001359 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001360 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1361
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001362 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001363 "getKeyRepeatTimeout", "()I");
1364
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001365 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001366 "getKeyRepeatDelay", "()I");
1367
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001368 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001369 "getMaxEventsPerSecond", "()I");
1370
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001371 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001372 "getPointerLayer", "()I");
1373
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001374 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001375 "getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001376
Jeff Brown6ec402b2010-07-28 15:48:59 -07001377 // KeyEvent
1378
1379 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001380 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1381
Jeff Brown6ec402b2010-07-28 15:48:59 -07001382
Jeff Brown8d608662010-08-30 03:02:23 -07001383 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001384
1385 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001386 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001387
Jeff Brown8d608662010-08-30 03:02:23 -07001388 // InputDevice
1389
1390 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001391 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001392
1393 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1394 "<init>", "()V");
1395
1396 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001397 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001398
1399 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1400 "mId", "I");
1401
1402 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1403 "mName", "Ljava/lang/String;");
1404
1405 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1406 "mSources", "I");
1407
1408 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1409 "mKeyboardType", "I");
1410
Jeff Brown57c59372010-09-21 18:22:55 -07001411 // Configuration
1412
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001413 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001414
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001415 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001416 "touchscreen", "I");
1417
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001418 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001419 "keyboard", "I");
1420
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001421 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001422 "navigation", "I");
1423
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001424 // PointerIcon
1425
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001426 FIND_CLASS(clazz, "com/android/server/wm/InputManager$PointerIcon");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001427
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001428 GET_FIELD_ID(gPointerIconClassInfo.bitmap, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001429 "bitmap", "Landroid/graphics/Bitmap;");
1430
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001431 GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001432 "hotSpotX", "F");
1433
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001434 GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001435 "hotSpotY", "F");
1436
Jeff Brown46b9ac02010-04-22 18:58:52 -07001437 return 0;
1438}
1439
Jeff Brown46b9ac02010-04-22 18:58:52 -07001440} /* namespace android */