blob: ab2c125667ca911157370a1029a84a0c3efbdae0 [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>
39
Jeff Brown05dc66a2011-03-02 14:41:58 -080040#include <android_os_MessageQueue.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080041#include <android_view_KeyEvent.h>
42#include <android_view_MotionEvent.h>
43#include <android_view_InputChannel.h>
44#include <android/graphics/GraphicsJNI.h>
45
Jeff Brown00fa7bd2010-07-02 15:37:36 -070046#include "com_android_server_PowerManagerService.h"
Jeff Brown928e0542011-01-10 11:17:36 -080047#include "com_android_server_InputApplication.h"
48#include "com_android_server_InputApplicationHandle.h"
49#include "com_android_server_InputWindow.h"
50#include "com_android_server_InputWindowHandle.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070051
52namespace android {
53
Jeff Brown46b9ac02010-04-22 18:58:52 -070054static struct {
Jeff Brown46b9ac02010-04-22 18:58:52 -070055 jmethodID notifyConfigurationChanged;
56 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070057 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070058 jmethodID notifyANR;
Jeff Brown0029c662011-03-30 02:25:18 -070059 jmethodID filterInputEvent;
Jeff Brown349703e2010-06-22 01:27:15 -070060 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080061 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070062 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070063 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070064 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070065 jmethodID filterTouchEvents;
66 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080067 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac02010-04-22 18:58:52 -070068 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080069 jmethodID getKeyRepeatTimeout;
70 jmethodID getKeyRepeatDelay;
Jeff Brownae9fc032010-08-18 15:51:08 -070071 jmethodID getMaxEventsPerSecond;
Jeff Brown83c09682010-12-23 17:50:18 -080072 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080073 jmethodID getPointerIcon;
Jeff Brown46b9ac02010-04-22 18:58:52 -070074} gCallbacksClassInfo;
75
76static struct {
77 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070078} gKeyEventClassInfo;
79
80static struct {
81 jclass clazz;
82} gMotionEventClassInfo;
83
Jeff Brown8d608662010-08-30 03:02:23 -070084static struct {
85 jclass clazz;
86
87 jmethodID ctor;
88 jmethodID addMotionRange;
89
90 jfieldID mId;
91 jfieldID mName;
92 jfieldID mSources;
93 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -070094} gInputDeviceClassInfo;
95
Jeff Brown57c59372010-09-21 18:22:55 -070096static struct {
Jeff Brown57c59372010-09-21 18:22:55 -070097 jfieldID touchscreen;
98 jfieldID keyboard;
99 jfieldID navigation;
100} gConfigurationClassInfo;
101
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800102static struct {
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800103 jfieldID bitmap;
104 jfieldID hotSpotX;
105 jfieldID hotSpotY;
106} gPointerIconClassInfo;
Jeff Brown83c09682010-12-23 17:50:18 -0800107
Jeff Brown928e0542011-01-10 11:17:36 -0800108
109// --- Global functions ---
110
111static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
112 const sp<InputApplicationHandle>& inputApplicationHandle) {
113 if (inputApplicationHandle == NULL) {
114 return NULL;
115 }
116 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
117 getInputApplicationHandleObjLocalRef(env);
118}
119
120static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
121 const sp<InputWindowHandle>& inputWindowHandle) {
122 if (inputWindowHandle == NULL) {
123 return NULL;
124 }
125 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
126 getInputWindowHandleObjLocalRef(env);
127}
128
129
130// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800131
Jeff Brown9c3cda02010-06-15 01:31:58 -0700132class NativeInputManager : public virtual RefBase,
133 public virtual InputReaderPolicyInterface,
134 public virtual InputDispatcherPolicyInterface {
135protected:
136 virtual ~NativeInputManager();
137
138public:
Jeff Brown05dc66a2011-03-02 14:41:58 -0800139 NativeInputManager(jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700140
141 inline sp<InputManager> getInputManager() const { return mInputManager; }
142
Jeff Brownb88102f2010-09-08 11:49:43 -0700143 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700144
Jeff Brown9c3cda02010-06-15 01:31:58 -0700145 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
146 void setDisplayOrientation(int32_t displayId, int32_t orientation);
147
Jeff Brown7fbdc842010-06-17 20:52:56 -0700148 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800149 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700150 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
151
Jeff Brown349703e2010-06-22 01:27:15 -0700152 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
153 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
154 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800155 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700156
Jeff Brown9c3cda02010-06-15 01:31:58 -0700157 /* --- InputReaderPolicyInterface implementation --- */
158
159 virtual bool getDisplayInfo(int32_t displayId,
160 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700161 virtual bool filterTouchEvents();
162 virtual bool filterJumpyTouchEvents();
Jeff Brownfe508922011-01-18 15:10:10 -0800163 virtual nsecs_t getVirtualKeyQuietTime();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700164 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800165 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700166
167 /* --- InputDispatcherPolicyInterface implementation --- */
168
Jeff Browne20c9e02010-10-11 14:20:19 -0700169 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
170 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700171 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700172 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800173 const sp<InputWindowHandle>& inputWindowHandle);
174 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700175 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700176 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700177 virtual int32_t getMaxEventsPerSecond();
Jeff Brown0029c662011-03-30 02:25:18 -0700178 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800179 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800180 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800181 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700182 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800183 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800184 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700185 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700186 virtual bool checkInjectEventsPermissionNonReentrant(
187 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700188
189private:
190 sp<InputManager> mInputManager;
191
192 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800193 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700194
195 // Cached filtering policies.
196 int32_t mFilterTouchEvents;
197 int32_t mFilterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -0800198 nsecs_t mVirtualKeyQuietTime;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700199
Jeff Browna4547672011-03-02 21:38:11 -0800200 // Cached key repeat policy.
201 nsecs_t mKeyRepeatTimeout;
202 nsecs_t mKeyRepeatDelay;
203
Jeff Brownae9fc032010-08-18 15:51:08 -0700204 // Cached throttling policy.
205 int32_t mMaxEventsPerSecond;
206
Jeff Brown83c09682010-12-23 17:50:18 -0800207 Mutex mLock;
208 struct Locked {
209 // Display size information.
210 int32_t displayWidth, displayHeight; // -1 when initialized
211 int32_t displayOrientation;
212
Jeff Brown05dc66a2011-03-02 14:41:58 -0800213 // System UI visibility.
214 int32_t systemUiVisibility;
215
Jeff Brown83c09682010-12-23 17:50:18 -0800216 // Pointer controller singleton, created and destroyed as needed.
217 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800218 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700219
Jeff Brown05dc66a2011-03-02 14:41:58 -0800220 void updateInactivityFadeDelayLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800221 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800222
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700223 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700224 bool isScreenOn();
225 bool isScreenBright();
226
Jeff Brownb88102f2010-09-08 11:49:43 -0700227 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700228
Jeff Brown9c3cda02010-06-15 01:31:58 -0700229 static inline JNIEnv* jniEnv() {
230 return AndroidRuntime::getJNIEnv();
231 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700232};
233
Jeff Brown928e0542011-01-10 11:17:36 -0800234
Jeff Brown9c3cda02010-06-15 01:31:58 -0700235
Jeff Brown05dc66a2011-03-02 14:41:58 -0800236NativeInputManager::NativeInputManager(jobject callbacksObj, const sp<Looper>& looper) :
237 mLooper(looper),
238 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
Jeff Browna4547672011-03-02 21:38:11 -0800239 mKeyRepeatTimeout(-1), mKeyRepeatDelay(-1),
Jeff Brown05dc66a2011-03-02 14:41:58 -0800240 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700241 JNIEnv* env = jniEnv();
242
243 mCallbacksObj = env->NewGlobalRef(callbacksObj);
244
Jeff Brown83c09682010-12-23 17:50:18 -0800245 {
246 AutoMutex _l(mLock);
247 mLocked.displayWidth = -1;
248 mLocked.displayHeight = -1;
249 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800250
251 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800252 }
253
Jeff Brown9c3cda02010-06-15 01:31:58 -0700254 sp<EventHub> eventHub = new EventHub();
255 mInputManager = new InputManager(eventHub, this, this);
256}
257
258NativeInputManager::~NativeInputManager() {
259 JNIEnv* env = jniEnv();
260
261 env->DeleteGlobalRef(mCallbacksObj);
262}
263
Jeff Brownb88102f2010-09-08 11:49:43 -0700264void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700265 mInputManager->getReader()->dump(dump);
266 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700267
Jeff Brownb88102f2010-09-08 11:49:43 -0700268 mInputManager->getDispatcher()->dump(dump);
269 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700270}
271
Jeff Brown7fbdc842010-06-17 20:52:56 -0700272bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700273 if (env->ExceptionCheck()) {
274 LOGE("An exception was thrown by callback '%s'.", methodName);
275 LOGE_EX(env);
276 env->ExceptionClear();
277 return true;
278 }
279 return false;
280}
281
282void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
283 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800284 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700285
Jeff Brown83c09682010-12-23 17:50:18 -0800286 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
287 mLocked.displayWidth = width;
288 mLocked.displayHeight = height;
289
290 sp<PointerController> controller = mLocked.pointerController.promote();
291 if (controller != NULL) {
292 controller->setDisplaySize(width, height);
293 }
294 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700295 }
296}
297
298void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
299 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800300 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700301
Jeff Brown83c09682010-12-23 17:50:18 -0800302 if (mLocked.displayOrientation != orientation) {
303 mLocked.displayOrientation = orientation;
304
305 sp<PointerController> controller = mLocked.pointerController.promote();
306 if (controller != NULL) {
307 controller->setDisplayOrientation(orientation);
308 }
309 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700310 }
311}
312
Jeff Brown7fbdc842010-06-17 20:52:56 -0700313status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800314 const sp<InputChannel>& inputChannel,
315 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
316 return mInputManager->getDispatcher()->registerInputChannel(
317 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700318}
319
320status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
321 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700322 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700323}
324
Jeff Brown9c3cda02010-06-15 01:31:58 -0700325bool NativeInputManager::getDisplayInfo(int32_t displayId,
326 int32_t* width, int32_t* height, int32_t* orientation) {
327 bool result = false;
328 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800329 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700330
Jeff Brown83c09682010-12-23 17:50:18 -0800331 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700332 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800333 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700334 }
335 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800336 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700337 }
338 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800339 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700340 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700341 result = true;
342 }
343 }
344 return result;
345}
346
Jeff Brown9c3cda02010-06-15 01:31:58 -0700347bool NativeInputManager::filterTouchEvents() {
348 if (mFilterTouchEvents < 0) {
349 JNIEnv* env = jniEnv();
350
351 jboolean result = env->CallBooleanMethod(mCallbacksObj,
352 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700353 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700354 result = false;
355 }
356
357 mFilterTouchEvents = result ? 1 : 0;
358 }
359 return mFilterTouchEvents;
360}
361
362bool NativeInputManager::filterJumpyTouchEvents() {
363 if (mFilterJumpyTouchEvents < 0) {
364 JNIEnv* env = jniEnv();
365
366 jboolean result = env->CallBooleanMethod(mCallbacksObj,
367 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700368 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700369 result = false;
370 }
371
372 mFilterJumpyTouchEvents = result ? 1 : 0;
373 }
374 return mFilterJumpyTouchEvents;
375}
376
Jeff Brownfe508922011-01-18 15:10:10 -0800377nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
378 if (mVirtualKeyQuietTime < 0) {
379 JNIEnv* env = jniEnv();
380
381 jint result = env->CallIntMethod(mCallbacksObj,
382 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
383 if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
384 result = 0;
385 }
386 if (result < 0) {
387 result = 0;
388 }
389
390 mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
391 }
392 return mVirtualKeyQuietTime;
393}
394
Jeff Brown9c3cda02010-06-15 01:31:58 -0700395void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700396 outExcludedDeviceNames.clear();
397
Jeff Brown9c3cda02010-06-15 01:31:58 -0700398 JNIEnv* env = jniEnv();
399
400 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
401 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700402 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700403 jsize length = env->GetArrayLength(result);
404 for (jsize i = 0; i < length; i++) {
405 jstring item = jstring(env->GetObjectArrayElement(result, i));
406
407 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
408 outExcludedDeviceNames.add(String8(deviceNameChars));
409 env->ReleaseStringUTFChars(item, deviceNameChars);
410
411 env->DeleteLocalRef(item);
412 }
413 env->DeleteLocalRef(result);
414 }
415}
416
Jeff Brown83c09682010-12-23 17:50:18 -0800417sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
418 AutoMutex _l(mLock);
419
420 sp<PointerController> controller = mLocked.pointerController.promote();
421 if (controller == NULL) {
422 JNIEnv* env = jniEnv();
423 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800424 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
425 layer = -1;
426 }
Jeff Brown83c09682010-12-23 17:50:18 -0800427
Jeff Brown05dc66a2011-03-02 14:41:58 -0800428 controller = new PointerController(mLooper, layer);
Jeff Brown83c09682010-12-23 17:50:18 -0800429 mLocked.pointerController = controller;
430
431 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
432 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800433
434 jobject iconObj = env->CallObjectMethod(mCallbacksObj, gCallbacksClassInfo.getPointerIcon);
435 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon") && iconObj) {
436 jfloat iconHotSpotX = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotX);
437 jfloat iconHotSpotY = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotY);
438 jobject iconBitmapObj = env->GetObjectField(iconObj, gPointerIconClassInfo.bitmap);
439 if (iconBitmapObj) {
440 SkBitmap* iconBitmap = GraphicsJNI::getNativeBitmap(env, iconBitmapObj);
441 if (iconBitmap) {
442 controller->setPointerIcon(iconBitmap, iconHotSpotX, iconHotSpotY);
443 }
444 env->DeleteLocalRef(iconBitmapObj);
445 }
446 env->DeleteLocalRef(iconObj);
447 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800448
449 updateInactivityFadeDelayLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800450 }
451 return controller;
452}
453
Jeff Browne20c9e02010-10-11 14:20:19 -0700454void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
455 int32_t switchValue, uint32_t policyFlags) {
456#if DEBUG_INPUT_DISPATCHER_POLICY
457 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
458 when, switchCode, switchValue, policyFlags);
459#endif
460
461 JNIEnv* env = jniEnv();
462
463 switch (switchCode) {
464 case SW_LID:
465 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
466 when, switchValue == 0);
467 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
468 break;
469 }
470}
471
Jeff Brown9c3cda02010-06-15 01:31:58 -0700472void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
473#if DEBUG_INPUT_DISPATCHER_POLICY
474 LOGD("notifyConfigurationChanged - when=%lld", when);
475#endif
476
477 JNIEnv* env = jniEnv();
478
Jeff Brown57c59372010-09-21 18:22:55 -0700479 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700480 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700481}
482
Jeff Brown519e0242010-09-15 15:18:56 -0700483nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800484 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700485#if DEBUG_INPUT_DISPATCHER_POLICY
486 LOGD("notifyANR");
487#endif
488
489 JNIEnv* env = jniEnv();
490
Jeff Brown928e0542011-01-10 11:17:36 -0800491 jobject inputApplicationHandleObj =
492 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
493 jobject inputWindowHandleObj =
494 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700495
Jeff Brown519e0242010-09-15 15:18:56 -0700496 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800497 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700498 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
499 newTimeout = 0; // abort dispatch
500 } else {
501 assert(newTimeout >= 0);
502 }
503
Jeff Brown928e0542011-01-10 11:17:36 -0800504 env->DeleteLocalRef(inputWindowHandleObj);
505 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700506 return newTimeout;
507}
508
Jeff Brown928e0542011-01-10 11:17:36 -0800509void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700510#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800511 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700512#endif
513
Jeff Brown7fbdc842010-06-17 20:52:56 -0700514 JNIEnv* env = jniEnv();
515
Jeff Brown928e0542011-01-10 11:17:36 -0800516 jobject inputWindowHandleObj =
517 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
518 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700519 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800520 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700521 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
522
Jeff Brown928e0542011-01-10 11:17:36 -0800523 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700524 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700525}
526
Jeff Brown9c3cda02010-06-15 01:31:58 -0700527nsecs_t NativeInputManager::getKeyRepeatTimeout() {
528 if (! isScreenOn()) {
529 // Disable key repeat when the screen is off.
530 return -1;
531 } else {
Jeff Browna4547672011-03-02 21:38:11 -0800532 if (mKeyRepeatTimeout < 0) {
533 JNIEnv* env = jniEnv();
534
535 jint result = env->CallIntMethod(mCallbacksObj,
536 gCallbacksClassInfo.getKeyRepeatTimeout);
537 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
538 result = 500;
539 }
540
541 mKeyRepeatTimeout = milliseconds_to_nanoseconds(result);
542 }
543 return mKeyRepeatTimeout;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700544 }
545}
546
Jeff Brownb21fb102010-09-07 10:44:57 -0700547nsecs_t NativeInputManager::getKeyRepeatDelay() {
Jeff Browna4547672011-03-02 21:38:11 -0800548 if (mKeyRepeatDelay < 0) {
549 JNIEnv* env = jniEnv();
550
551 jint result = env->CallIntMethod(mCallbacksObj,
552 gCallbacksClassInfo.getKeyRepeatDelay);
553 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
554 result = 50;
555 }
556
557 mKeyRepeatDelay = milliseconds_to_nanoseconds(result);
558 }
559 return mKeyRepeatDelay;
Jeff Brownb21fb102010-09-07 10:44:57 -0700560}
561
Jeff Brownae9fc032010-08-18 15:51:08 -0700562int32_t NativeInputManager::getMaxEventsPerSecond() {
563 if (mMaxEventsPerSecond < 0) {
564 JNIEnv* env = jniEnv();
565
566 jint result = env->CallIntMethod(mCallbacksObj,
567 gCallbacksClassInfo.getMaxEventsPerSecond);
568 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700569 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700570 }
571
572 mMaxEventsPerSecond = result;
573 }
574 return mMaxEventsPerSecond;
575}
576
Jeff Brown349703e2010-06-22 01:27:15 -0700577void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700578 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700579
Jeff Brownb88102f2010-09-08 11:49:43 -0700580 jsize length = env->GetArrayLength(windowObjArray);
581 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800582 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
583 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700584 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700585 }
586
Jeff Brownb88102f2010-09-08 11:49:43 -0700587 windows.push();
588 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800589 android_server_InputWindow_toNative(env, windowObj, &window);
590 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700591 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700592 }
Jeff Brown928e0542011-01-10 11:17:36 -0800593 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700594 }
Jeff Brown349703e2010-06-22 01:27:15 -0700595
Jeff Brownb88102f2010-09-08 11:49:43 -0700596 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700597}
598
Jeff Brown349703e2010-06-22 01:27:15 -0700599void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700600 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700601 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800602 android_server_InputApplication_toNative(env, applicationObj, &application);
603 if (application.inputApplicationHandle != NULL) {
604 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Browna2cc28d2011-03-25 11:58:46 -0700605 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800606 }
Jeff Brown349703e2010-06-22 01:27:15 -0700607 }
Jeff Brown928e0542011-01-10 11:17:36 -0800608 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700609}
610
611void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700612 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700613}
614
Jeff Brown05dc66a2011-03-02 14:41:58 -0800615void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
616 AutoMutex _l(mLock);
617
618 if (mLocked.systemUiVisibility != visibility) {
619 mLocked.systemUiVisibility = visibility;
620
621 sp<PointerController> controller = mLocked.pointerController.promote();
622 if (controller != NULL) {
623 updateInactivityFadeDelayLocked(controller);
624 }
625 }
626}
627
628void NativeInputManager::updateInactivityFadeDelayLocked(const sp<PointerController>& controller) {
629 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
630 controller->setInactivityFadeDelay(lightsOut
631 ? PointerController::INACTIVITY_FADE_DELAY_SHORT
632 : PointerController::INACTIVITY_FADE_DELAY_NORMAL);
633}
634
Jeff Browne20c9e02010-10-11 14:20:19 -0700635bool NativeInputManager::isScreenOn() {
636 return android_server_PowerManagerService_isScreenOn();
637}
638
639bool NativeInputManager::isScreenBright() {
640 return android_server_PowerManagerService_isScreenBright();
641}
642
Jeff Brown0029c662011-03-30 02:25:18 -0700643bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
644 jobject inputEventObj;
645
646 JNIEnv* env = jniEnv();
647 switch (inputEvent->getType()) {
648 case AINPUT_EVENT_TYPE_KEY:
649 inputEventObj = android_view_KeyEvent_fromNative(env,
650 static_cast<const KeyEvent*>(inputEvent));
651 break;
652 case AINPUT_EVENT_TYPE_MOTION:
653 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
654 static_cast<const MotionEvent*>(inputEvent));
655 break;
656 default:
657 return true; // dispatch the event normally
658 }
659
660 if (!inputEventObj) {
661 LOGE("Failed to obtain input event object for filterInputEvent.");
662 return true; // dispatch the event normally
663 }
664
665 // The callee is responsible for recycling the event.
666 jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
667 inputEventObj, policyFlags);
668 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
669 pass = true;
670 }
671 env->DeleteLocalRef(inputEventObj);
672 return pass;
673}
674
Jeff Brown1f245102010-11-18 20:53:46 -0800675void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
676 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700677 // Policy:
678 // - Ignore untrusted events and pass them along.
679 // - Ask the window manager what to do with normal events and trusted injected events.
680 // - For normal events wake and brighten the screen if currently off or dim.
681 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800682 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700683 bool isScreenOn = this->isScreenOn();
684 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700685
Jeff Brown3122e442010-10-11 23:32:49 -0700686 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800687 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
688 jint wmActions;
689 if (keyEventObj) {
690 wmActions = env->CallIntMethod(mCallbacksObj,
691 gCallbacksClassInfo.interceptKeyBeforeQueueing,
692 keyEventObj, policyFlags, isScreenOn);
693 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
694 wmActions = 0;
695 }
696 android_view_KeyEvent_recycle(env, keyEventObj);
697 env->DeleteLocalRef(keyEventObj);
698 } else {
699 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700700 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700701 }
702
Jeff Brown1f245102010-11-18 20:53:46 -0800703 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700704 if (!isScreenOn) {
705 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700706 }
707
708 if (!isScreenBright) {
709 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
710 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700711 }
712
Jeff Brown56194eb2011-03-02 19:23:13 -0800713 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700714 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700715 policyFlags |= POLICY_FLAG_PASS_TO_USER;
716 }
717}
718
Jeff Brown56194eb2011-03-02 19:23:13 -0800719void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700720 // Policy:
721 // - Ignore untrusted events and pass them along.
722 // - No special filtering for injected events required at this time.
723 // - Filter normal events based on screen state.
724 // - For normal events brighten (but do not wake) the screen if currently dim.
725 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
726 if (isScreenOn()) {
727 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700728
Jeff Brown3122e442010-10-11 23:32:49 -0700729 if (!isScreenBright()) {
730 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
731 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800732 } else {
733 JNIEnv* env = jniEnv();
734 jint wmActions = env->CallIntMethod(mCallbacksObj,
735 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
736 policyFlags);
737 if (checkAndClearExceptionFromCallback(env,
738 "interceptMotionBeforeQueueingWhenScreenOff")) {
739 wmActions = 0;
740 }
741
742 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
743 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700744 }
Jeff Brown3122e442010-10-11 23:32:49 -0700745 } else {
746 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700747 }
748}
749
Jeff Brown56194eb2011-03-02 19:23:13 -0800750void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
751 uint32_t& policyFlags) {
752 enum {
753 WM_ACTION_PASS_TO_USER = 1,
754 WM_ACTION_POKE_USER_ACTIVITY = 2,
755 WM_ACTION_GO_TO_SLEEP = 4,
756 };
757
758 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800759#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800760 LOGD("handleInterceptActions: Going to sleep.");
761#endif
762 android_server_PowerManagerService_goToSleep(when);
763 }
764
765 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800766#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800767 LOGD("handleInterceptActions: Poking user activity.");
768#endif
769 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
770 }
771
772 if (wmActions & WM_ACTION_PASS_TO_USER) {
773 policyFlags |= POLICY_FLAG_PASS_TO_USER;
774 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800775#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800776 LOGD("handleInterceptActions: Not passing key to user.");
777#endif
778 }
779}
780
Jeff Brown928e0542011-01-10 11:17:36 -0800781bool NativeInputManager::interceptKeyBeforeDispatching(
782 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700783 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700784 // Policy:
785 // - Ignore untrusted events and pass them along.
786 // - Filter normal events and trusted injected events through the window manager policy to
787 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800788 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700789 if (policyFlags & POLICY_FLAG_TRUSTED) {
790 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700791
Jeff Brown928e0542011-01-10 11:17:36 -0800792 // Note: inputWindowHandle may be null.
793 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800794 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
795 if (keyEventObj) {
796 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
797 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800798 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800799 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
800 android_view_KeyEvent_recycle(env, keyEventObj);
801 env->DeleteLocalRef(keyEventObj);
802 result = consumed && !error;
803 } else {
804 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800805 }
Jeff Brown928e0542011-01-10 11:17:36 -0800806 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700807 }
Jeff Brown1f245102010-11-18 20:53:46 -0800808 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700809}
810
Jeff Brown928e0542011-01-10 11:17:36 -0800811bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800812 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700813 // Policy:
814 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800815 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700816 if (policyFlags & POLICY_FLAG_TRUSTED) {
817 JNIEnv* env = jniEnv();
818
Jeff Brown928e0542011-01-10 11:17:36 -0800819 // Note: inputWindowHandle may be null.
820 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800821 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
822 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800823 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800824 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800825 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700826 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
827 fallbackKeyEventObj = NULL;
828 }
Jeff Brown1f245102010-11-18 20:53:46 -0800829 android_view_KeyEvent_recycle(env, keyEventObj);
830 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800831
832 if (fallbackKeyEventObj) {
833 // Note: outFallbackKeyEvent may be the same object as keyEvent.
834 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
835 outFallbackKeyEvent)) {
836 result = true;
837 }
838 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
839 env->DeleteLocalRef(fallbackKeyEventObj);
840 }
Jeff Brown1f245102010-11-18 20:53:46 -0800841 } else {
842 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800843 }
Jeff Brown928e0542011-01-10 11:17:36 -0800844 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700845 }
Jeff Brown1f245102010-11-18 20:53:46 -0800846 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700847}
848
Jeff Brown01ce2e92010-09-26 22:20:12 -0700849void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
850 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700851}
852
Jeff Brown349703e2010-06-22 01:27:15 -0700853
Jeff Brownb88102f2010-09-08 11:49:43 -0700854bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
855 int32_t injectorPid, int32_t injectorUid) {
856 JNIEnv* env = jniEnv();
857 jboolean result = env->CallBooleanMethod(mCallbacksObj,
858 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700859 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
860 result = false;
861 }
Jeff Brown349703e2010-06-22 01:27:15 -0700862 return result;
863}
864
Jeff Brown83c09682010-12-23 17:50:18 -0800865
Jeff Brown9c3cda02010-06-15 01:31:58 -0700866// ----------------------------------------------------------------------------
867
868static sp<NativeInputManager> gNativeInputManager;
869
Jeff Brown46b9ac02010-04-22 18:58:52 -0700870static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700871 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700872 LOGE("Input manager not initialized.");
873 jniThrowRuntimeException(env, "Input manager not initialized.");
874 return true;
875 }
876 return false;
877}
878
879static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown05dc66a2011-03-02 14:41:58 -0800880 jobject callbacks, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700881 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800882 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
883 gNativeInputManager = new NativeInputManager(callbacks, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700884 } else {
885 LOGE("Input manager already initialized.");
886 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700887 }
888}
889
890static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
891 if (checkInputManagerUnitialized(env)) {
892 return;
893 }
894
Jeff Brown9c3cda02010-06-15 01:31:58 -0700895 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700896 if (result) {
897 jniThrowRuntimeException(env, "Input manager could not be started.");
898 }
899}
900
901static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
902 jint displayId, jint width, jint height) {
903 if (checkInputManagerUnitialized(env)) {
904 return;
905 }
906
907 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
908 // to be passed in like this, not sure which is better but leaving it like this
909 // keeps the window manager in direct control of when display transitions propagate down
910 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700911 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700912}
913
914static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
915 jint displayId, jint orientation) {
916 if (checkInputManagerUnitialized(env)) {
917 return;
918 }
919
Jeff Brown9c3cda02010-06-15 01:31:58 -0700920 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700921}
922
923static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700924 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700925 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700926 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700927 }
928
Jeff Brownb88102f2010-09-08 11:49:43 -0700929 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700930 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700931}
932
933static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700934 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700935 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700936 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700937 }
938
Jeff Brownb88102f2010-09-08 11:49:43 -0700939 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700940 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700941}
942
943static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700944 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700945 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700946 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700947 }
948
Jeff Brownb88102f2010-09-08 11:49:43 -0700949 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700950 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700951}
952
953static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700954 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700955 if (checkInputManagerUnitialized(env)) {
956 return JNI_FALSE;
957 }
958
959 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
960 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
961 jsize numCodes = env->GetArrayLength(keyCodes);
962 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700963 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700964 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700965 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700966 } else {
967 result = JNI_FALSE;
968 }
969
970 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
971 env->ReleaseIntArrayElements(keyCodes, codes, 0);
972 return result;
973}
974
975static void throwInputChannelNotInitialized(JNIEnv* env) {
976 jniThrowException(env, "java/lang/IllegalStateException",
977 "inputChannel is not initialized");
978}
979
980static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
981 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
982 LOGW("Input channel object '%s' was disposed without first being unregistered with "
983 "the input manager!", inputChannel->getName().string());
984
Jeff Brown9c3cda02010-06-15 01:31:58 -0700985 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700986 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700987 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700988}
989
990static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -0800991 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700992 if (checkInputManagerUnitialized(env)) {
993 return;
994 }
995
996 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
997 inputChannelObj);
998 if (inputChannel == NULL) {
999 throwInputChannelNotInitialized(env);
1000 return;
1001 }
1002
Jeff Brown928e0542011-01-10 11:17:36 -08001003 sp<InputWindowHandle> inputWindowHandle =
1004 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001005
1006 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001007 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001008 if (status) {
1009 jniThrowRuntimeException(env, "Failed to register input channel. "
1010 "Check logs for details.");
1011 return;
1012 }
1013
Jeff Browna41ca772010-08-11 14:46:32 -07001014 if (! monitor) {
1015 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1016 android_server_InputManager_handleInputChannelDisposed, NULL);
1017 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001018}
1019
1020static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1021 jobject inputChannelObj) {
1022 if (checkInputManagerUnitialized(env)) {
1023 return;
1024 }
1025
1026 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1027 inputChannelObj);
1028 if (inputChannel == NULL) {
1029 throwInputChannelNotInitialized(env);
1030 return;
1031 }
1032
1033 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1034
Jeff Brown7fbdc842010-06-17 20:52:56 -07001035 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001036 if (status) {
1037 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1038 "Check logs for details.");
1039 }
1040}
1041
Jeff Brown0029c662011-03-30 02:25:18 -07001042static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
1043 jboolean enabled) {
1044 if (checkInputManagerUnitialized(env)) {
1045 return;
1046 }
1047
1048 gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1049}
1050
Jeff Brown6ec402b2010-07-28 15:48:59 -07001051static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1052 jobject inputEventObj, jint injectorPid, jint injectorUid,
Jeff Brown0029c662011-03-30 02:25:18 -07001053 jint syncMode, jint timeoutMillis, jint policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001054 if (checkInputManagerUnitialized(env)) {
1055 return INPUT_EVENT_INJECTION_FAILED;
1056 }
1057
Jeff Brown6ec402b2010-07-28 15:48:59 -07001058 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1059 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001060 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1061 if (status) {
1062 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1063 return INPUT_EVENT_INJECTION_FAILED;
1064 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001065
Jeff Brownb88102f2010-09-08 11:49:43 -07001066 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001067 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1068 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001069 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001070 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1071 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001072 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1073 return INPUT_EVENT_INJECTION_FAILED;
1074 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001075
Jeff Brownb88102f2010-09-08 11:49:43 -07001076 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001077 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1078 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001079 } else {
1080 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001081 return INPUT_EVENT_INJECTION_FAILED;
1082 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001083}
1084
Jeff Brown349703e2010-06-22 01:27:15 -07001085static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1086 jobjectArray windowObjArray) {
1087 if (checkInputManagerUnitialized(env)) {
1088 return;
1089 }
1090
1091 gNativeInputManager->setInputWindows(env, windowObjArray);
1092}
1093
1094static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1095 jobject applicationObj) {
1096 if (checkInputManagerUnitialized(env)) {
1097 return;
1098 }
1099
1100 gNativeInputManager->setFocusedApplication(env, applicationObj);
1101}
1102
1103static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1104 jclass clazz, jboolean enabled, jboolean frozen) {
1105 if (checkInputManagerUnitialized(env)) {
1106 return;
1107 }
1108
1109 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1110}
1111
Jeff Brown05dc66a2011-03-02 14:41:58 -08001112static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1113 jclass clazz, jint visibility) {
1114 if (checkInputManagerUnitialized(env)) {
1115 return;
1116 }
1117
1118 gNativeInputManager->setSystemUiVisibility(visibility);
1119}
1120
Jeff Brown8d608662010-08-30 03:02:23 -07001121static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1122 jclass clazz, jint deviceId) {
1123 if (checkInputManagerUnitialized(env)) {
1124 return NULL;
1125 }
1126
1127 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001128 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001129 deviceId, & deviceInfo);
1130 if (status) {
1131 return NULL;
1132 }
1133
1134 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1135 if (! deviceObj) {
1136 return NULL;
1137 }
1138
1139 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1140 if (! deviceNameObj) {
1141 return NULL;
1142 }
1143
1144 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1145 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1146 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1147 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1148
Jeff Brownefd32662011-03-08 15:13:06 -08001149 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001150 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001151 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001152 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001153 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001154 if (env->ExceptionCheck()) {
1155 return NULL;
1156 }
1157 }
1158
1159 return deviceObj;
1160}
1161
1162static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1163 jclass clazz) {
1164 if (checkInputManagerUnitialized(env)) {
1165 return NULL;
1166 }
1167
1168 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001169 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001170
1171 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1172 if (! deviceIdsObj) {
1173 return NULL;
1174 }
1175
1176 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1177 return deviceIdsObj;
1178}
1179
Jeff Brown57c59372010-09-21 18:22:55 -07001180static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1181 jclass clazz, jobject configObj) {
1182 if (checkInputManagerUnitialized(env)) {
1183 return;
1184 }
1185
1186 InputConfiguration config;
1187 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1188
1189 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1190 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1191 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1192}
1193
Jeff Browne6504122010-09-27 14:52:15 -07001194static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1195 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1196 if (checkInputManagerUnitialized(env)) {
1197 return false;
1198 }
1199
1200 sp<InputChannel> fromChannel =
1201 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1202 sp<InputChannel> toChannel =
1203 android_view_InputChannel_getInputChannel(env, toChannelObj);
1204
1205 if (fromChannel == NULL || toChannel == NULL) {
1206 return false;
1207 }
1208
1209 return gNativeInputManager->getInputManager()->getDispatcher()->
1210 transferTouchFocus(fromChannel, toChannel);
1211}
1212
Jeff Browne33348b2010-07-15 23:54:05 -07001213static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1214 if (checkInputManagerUnitialized(env)) {
1215 return NULL;
1216 }
1217
Jeff Brownb88102f2010-09-08 11:49:43 -07001218 String8 dump;
1219 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001220 return env->NewStringUTF(dump.string());
1221}
1222
Jeff Brown9c3cda02010-06-15 01:31:58 -07001223// ----------------------------------------------------------------------------
1224
Jeff Brown46b9ac02010-04-22 18:58:52 -07001225static JNINativeMethod gInputManagerMethods[] = {
1226 /* name, signature, funcPtr */
Jeff Brown05dc66a2011-03-02 14:41:58 -08001227 { "nativeInit", "(Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001228 (void*) android_server_InputManager_nativeInit },
1229 { "nativeStart", "()V",
1230 (void*) android_server_InputManager_nativeStart },
1231 { "nativeSetDisplaySize", "(III)V",
1232 (void*) android_server_InputManager_nativeSetDisplaySize },
1233 { "nativeSetDisplayOrientation", "(II)V",
1234 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1235 { "nativeGetScanCodeState", "(III)I",
1236 (void*) android_server_InputManager_nativeGetScanCodeState },
1237 { "nativeGetKeyCodeState", "(III)I",
1238 (void*) android_server_InputManager_nativeGetKeyCodeState },
1239 { "nativeGetSwitchState", "(III)I",
1240 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001241 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001242 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001243 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001244 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001245 (void*) android_server_InputManager_nativeRegisterInputChannel },
1246 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001247 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown0029c662011-03-30 02:25:18 -07001248 { "nativeSetInputFilterEnabled", "(Z)V",
1249 (void*) android_server_InputManager_nativeSetInputFilterEnabled },
1250 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
Jeff Brown6ec402b2010-07-28 15:48:59 -07001251 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001252 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001253 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001254 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001255 (void*) android_server_InputManager_nativeSetFocusedApplication },
1256 { "nativeSetInputDispatchMode", "(ZZ)V",
1257 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001258 { "nativeSetSystemUiVisibility", "(I)V",
1259 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001260 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1261 (void*) android_server_InputManager_nativeGetInputDevice },
1262 { "nativeGetInputDeviceIds", "()[I",
1263 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001264 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1265 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001266 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1267 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001268 { "nativeDump", "()Ljava/lang/String;",
1269 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001270};
1271
1272#define FIND_CLASS(var, className) \
1273 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001274 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001275
1276#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1277 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1278 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1279
1280#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1281 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1282 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1283
1284int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001285 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001286 gInputManagerMethods, NELEM(gInputManagerMethods));
1287 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1288
Jeff Brown9c3cda02010-06-15 01:31:58 -07001289 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001290
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001291 jclass clazz;
1292 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001293
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001294 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001295 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001296
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001297 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001298 "notifyLidSwitchChanged", "(JZ)V");
1299
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001300 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001301 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001302
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001303 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001304 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001305 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001306
Jeff Brown0029c662011-03-30 02:25:18 -07001307 GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
1308 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1309
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001310 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001311 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001312
Jeff Brown56194eb2011-03-02 19:23:13 -08001313 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001314 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001315 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1316
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001317 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001318 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001319 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001320
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001321 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001322 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001323 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001324
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001325 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001326 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001327
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001328 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001329 "filterTouchEvents", "()Z");
1330
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001331 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001332 "filterJumpyTouchEvents", "()Z");
1333
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001334 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001335 "getVirtualKeyQuietTimeMillis", "()I");
1336
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001337 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001338 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1339
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001340 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001341 "getKeyRepeatTimeout", "()I");
1342
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001343 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001344 "getKeyRepeatDelay", "()I");
1345
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001346 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001347 "getMaxEventsPerSecond", "()I");
1348
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001349 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001350 "getPointerLayer", "()I");
1351
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001352 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001353 "getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001354
Jeff Brown6ec402b2010-07-28 15:48:59 -07001355 // KeyEvent
1356
1357 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001358 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1359
Jeff Brown6ec402b2010-07-28 15:48:59 -07001360
Jeff Brown8d608662010-08-30 03:02:23 -07001361 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001362
1363 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001364 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001365
Jeff Brown8d608662010-08-30 03:02:23 -07001366 // InputDevice
1367
1368 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001369 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001370
1371 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1372 "<init>", "()V");
1373
1374 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001375 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001376
1377 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1378 "mId", "I");
1379
1380 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1381 "mName", "Ljava/lang/String;");
1382
1383 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1384 "mSources", "I");
1385
1386 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1387 "mKeyboardType", "I");
1388
Jeff Brown57c59372010-09-21 18:22:55 -07001389 // Configuration
1390
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001391 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001392
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001393 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001394 "touchscreen", "I");
1395
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001396 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001397 "keyboard", "I");
1398
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001399 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001400 "navigation", "I");
1401
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001402 // PointerIcon
1403
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001404 FIND_CLASS(clazz, "com/android/server/wm/InputManager$PointerIcon");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001405
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001406 GET_FIELD_ID(gPointerIconClassInfo.bitmap, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001407 "bitmap", "Landroid/graphics/Bitmap;");
1408
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001409 GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001410 "hotSpotX", "F");
1411
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001412 GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001413 "hotSpotY", "F");
1414
Jeff Brown46b9ac02010-04-22 18:58:52 -07001415 return 0;
1416}
1417
Jeff Brown46b9ac02010-04-22 18:58:52 -07001418} /* namespace android */