blob: 110d4ef1fbad233fd3fa50ee3e170be921231e3c [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 Brown349703e2010-06-22 01:27:15 -070059 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080060 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070061 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070062 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070063 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070064 jmethodID filterTouchEvents;
65 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080066 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac02010-04-22 18:58:52 -070067 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080068 jmethodID getKeyRepeatTimeout;
69 jmethodID getKeyRepeatDelay;
Jeff Brownae9fc032010-08-18 15:51:08 -070070 jmethodID getMaxEventsPerSecond;
Jeff Brown83c09682010-12-23 17:50:18 -080071 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080072 jmethodID getPointerIcon;
Jeff Brown46b9ac02010-04-22 18:58:52 -070073} gCallbacksClassInfo;
74
75static struct {
76 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070077} gKeyEventClassInfo;
78
79static struct {
80 jclass clazz;
81} gMotionEventClassInfo;
82
Jeff Brown8d608662010-08-30 03:02:23 -070083static struct {
84 jclass clazz;
85
86 jmethodID ctor;
87 jmethodID addMotionRange;
88
89 jfieldID mId;
90 jfieldID mName;
91 jfieldID mSources;
92 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -070093} gInputDeviceClassInfo;
94
Jeff Brown57c59372010-09-21 18:22:55 -070095static struct {
Jeff Brown57c59372010-09-21 18:22:55 -070096 jfieldID touchscreen;
97 jfieldID keyboard;
98 jfieldID navigation;
99} gConfigurationClassInfo;
100
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800101static struct {
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800102 jfieldID bitmap;
103 jfieldID hotSpotX;
104 jfieldID hotSpotY;
105} gPointerIconClassInfo;
Jeff Brown83c09682010-12-23 17:50:18 -0800106
Jeff Brown928e0542011-01-10 11:17:36 -0800107
108// --- Global functions ---
109
110static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
111 const sp<InputApplicationHandle>& inputApplicationHandle) {
112 if (inputApplicationHandle == NULL) {
113 return NULL;
114 }
115 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
116 getInputApplicationHandleObjLocalRef(env);
117}
118
119static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
120 const sp<InputWindowHandle>& inputWindowHandle) {
121 if (inputWindowHandle == NULL) {
122 return NULL;
123 }
124 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
125 getInputWindowHandleObjLocalRef(env);
126}
127
128
129// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800130
Jeff Brown9c3cda02010-06-15 01:31:58 -0700131class NativeInputManager : public virtual RefBase,
132 public virtual InputReaderPolicyInterface,
133 public virtual InputDispatcherPolicyInterface {
134protected:
135 virtual ~NativeInputManager();
136
137public:
Jeff Brown05dc66a2011-03-02 14:41:58 -0800138 NativeInputManager(jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700139
140 inline sp<InputManager> getInputManager() const { return mInputManager; }
141
Jeff Brownb88102f2010-09-08 11:49:43 -0700142 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700143
Jeff Brown9c3cda02010-06-15 01:31:58 -0700144 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
145 void setDisplayOrientation(int32_t displayId, int32_t orientation);
146
Jeff Brown7fbdc842010-06-17 20:52:56 -0700147 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800148 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700149 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
150
Jeff Brown349703e2010-06-22 01:27:15 -0700151 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
152 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
153 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800154 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700155
Jeff Brown9c3cda02010-06-15 01:31:58 -0700156 /* --- InputReaderPolicyInterface implementation --- */
157
158 virtual bool getDisplayInfo(int32_t displayId,
159 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700160 virtual bool filterTouchEvents();
161 virtual bool filterJumpyTouchEvents();
Jeff Brownfe508922011-01-18 15:10:10 -0800162 virtual nsecs_t getVirtualKeyQuietTime();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700163 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800164 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700165
166 /* --- InputDispatcherPolicyInterface implementation --- */
167
Jeff Browne20c9e02010-10-11 14:20:19 -0700168 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
169 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700170 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700171 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800172 const sp<InputWindowHandle>& inputWindowHandle);
173 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700174 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700175 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700176 virtual int32_t getMaxEventsPerSecond();
Jeff Brown1f245102010-11-18 20:53:46 -0800177 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800178 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800179 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700180 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800181 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800182 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700183 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700184 virtual bool checkInjectEventsPermissionNonReentrant(
185 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700186
187private:
188 sp<InputManager> mInputManager;
189
190 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800191 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700192
193 // Cached filtering policies.
194 int32_t mFilterTouchEvents;
195 int32_t mFilterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -0800196 nsecs_t mVirtualKeyQuietTime;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197
Jeff Browna4547672011-03-02 21:38:11 -0800198 // Cached key repeat policy.
199 nsecs_t mKeyRepeatTimeout;
200 nsecs_t mKeyRepeatDelay;
201
Jeff Brownae9fc032010-08-18 15:51:08 -0700202 // Cached throttling policy.
203 int32_t mMaxEventsPerSecond;
204
Jeff Brown83c09682010-12-23 17:50:18 -0800205 Mutex mLock;
206 struct Locked {
207 // Display size information.
208 int32_t displayWidth, displayHeight; // -1 when initialized
209 int32_t displayOrientation;
210
Jeff Brown05dc66a2011-03-02 14:41:58 -0800211 // System UI visibility.
212 int32_t systemUiVisibility;
213
Jeff Brown83c09682010-12-23 17:50:18 -0800214 // Pointer controller singleton, created and destroyed as needed.
215 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800216 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700217
Jeff Brown05dc66a2011-03-02 14:41:58 -0800218 void updateInactivityFadeDelayLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800219 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800220
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700221 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700222 bool isScreenOn();
223 bool isScreenBright();
224
Jeff Brownb88102f2010-09-08 11:49:43 -0700225 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700226
Jeff Brown9c3cda02010-06-15 01:31:58 -0700227 static inline JNIEnv* jniEnv() {
228 return AndroidRuntime::getJNIEnv();
229 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700230};
231
Jeff Brown928e0542011-01-10 11:17:36 -0800232
Jeff Brown9c3cda02010-06-15 01:31:58 -0700233
Jeff Brown05dc66a2011-03-02 14:41:58 -0800234NativeInputManager::NativeInputManager(jobject callbacksObj, const sp<Looper>& looper) :
235 mLooper(looper),
236 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
Jeff Browna4547672011-03-02 21:38:11 -0800237 mKeyRepeatTimeout(-1), mKeyRepeatDelay(-1),
Jeff Brown05dc66a2011-03-02 14:41:58 -0800238 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700239 JNIEnv* env = jniEnv();
240
241 mCallbacksObj = env->NewGlobalRef(callbacksObj);
242
Jeff Brown83c09682010-12-23 17:50:18 -0800243 {
244 AutoMutex _l(mLock);
245 mLocked.displayWidth = -1;
246 mLocked.displayHeight = -1;
247 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800248
249 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800250 }
251
Jeff Brown9c3cda02010-06-15 01:31:58 -0700252 sp<EventHub> eventHub = new EventHub();
253 mInputManager = new InputManager(eventHub, this, this);
254}
255
256NativeInputManager::~NativeInputManager() {
257 JNIEnv* env = jniEnv();
258
259 env->DeleteGlobalRef(mCallbacksObj);
260}
261
Jeff Brownb88102f2010-09-08 11:49:43 -0700262void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700263 mInputManager->getReader()->dump(dump);
264 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700265
Jeff Brownb88102f2010-09-08 11:49:43 -0700266 mInputManager->getDispatcher()->dump(dump);
267 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700268}
269
Jeff Brown7fbdc842010-06-17 20:52:56 -0700270bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700271 if (env->ExceptionCheck()) {
272 LOGE("An exception was thrown by callback '%s'.", methodName);
273 LOGE_EX(env);
274 env->ExceptionClear();
275 return true;
276 }
277 return false;
278}
279
280void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
281 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800282 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700283
Jeff Brown83c09682010-12-23 17:50:18 -0800284 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
285 mLocked.displayWidth = width;
286 mLocked.displayHeight = height;
287
288 sp<PointerController> controller = mLocked.pointerController.promote();
289 if (controller != NULL) {
290 controller->setDisplaySize(width, height);
291 }
292 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700293 }
294}
295
296void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
297 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800298 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700299
Jeff Brown83c09682010-12-23 17:50:18 -0800300 if (mLocked.displayOrientation != orientation) {
301 mLocked.displayOrientation = orientation;
302
303 sp<PointerController> controller = mLocked.pointerController.promote();
304 if (controller != NULL) {
305 controller->setDisplayOrientation(orientation);
306 }
307 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700308 }
309}
310
Jeff Brown7fbdc842010-06-17 20:52:56 -0700311status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800312 const sp<InputChannel>& inputChannel,
313 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
314 return mInputManager->getDispatcher()->registerInputChannel(
315 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700316}
317
318status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
319 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700320 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700321}
322
Jeff Brown9c3cda02010-06-15 01:31:58 -0700323bool NativeInputManager::getDisplayInfo(int32_t displayId,
324 int32_t* width, int32_t* height, int32_t* orientation) {
325 bool result = false;
326 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800327 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700328
Jeff Brown83c09682010-12-23 17:50:18 -0800329 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700330 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800331 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700332 }
333 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800334 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700335 }
336 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800337 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700338 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700339 result = true;
340 }
341 }
342 return result;
343}
344
Jeff Brown9c3cda02010-06-15 01:31:58 -0700345bool NativeInputManager::filterTouchEvents() {
346 if (mFilterTouchEvents < 0) {
347 JNIEnv* env = jniEnv();
348
349 jboolean result = env->CallBooleanMethod(mCallbacksObj,
350 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700351 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700352 result = false;
353 }
354
355 mFilterTouchEvents = result ? 1 : 0;
356 }
357 return mFilterTouchEvents;
358}
359
360bool NativeInputManager::filterJumpyTouchEvents() {
361 if (mFilterJumpyTouchEvents < 0) {
362 JNIEnv* env = jniEnv();
363
364 jboolean result = env->CallBooleanMethod(mCallbacksObj,
365 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700366 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700367 result = false;
368 }
369
370 mFilterJumpyTouchEvents = result ? 1 : 0;
371 }
372 return mFilterJumpyTouchEvents;
373}
374
Jeff Brownfe508922011-01-18 15:10:10 -0800375nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
376 if (mVirtualKeyQuietTime < 0) {
377 JNIEnv* env = jniEnv();
378
379 jint result = env->CallIntMethod(mCallbacksObj,
380 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
381 if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
382 result = 0;
383 }
384 if (result < 0) {
385 result = 0;
386 }
387
388 mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
389 }
390 return mVirtualKeyQuietTime;
391}
392
Jeff Brown9c3cda02010-06-15 01:31:58 -0700393void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700394 outExcludedDeviceNames.clear();
395
Jeff Brown9c3cda02010-06-15 01:31:58 -0700396 JNIEnv* env = jniEnv();
397
398 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
399 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700400 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700401 jsize length = env->GetArrayLength(result);
402 for (jsize i = 0; i < length; i++) {
403 jstring item = jstring(env->GetObjectArrayElement(result, i));
404
405 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
406 outExcludedDeviceNames.add(String8(deviceNameChars));
407 env->ReleaseStringUTFChars(item, deviceNameChars);
408
409 env->DeleteLocalRef(item);
410 }
411 env->DeleteLocalRef(result);
412 }
413}
414
Jeff Brown83c09682010-12-23 17:50:18 -0800415sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
416 AutoMutex _l(mLock);
417
418 sp<PointerController> controller = mLocked.pointerController.promote();
419 if (controller == NULL) {
420 JNIEnv* env = jniEnv();
421 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800422 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
423 layer = -1;
424 }
Jeff Brown83c09682010-12-23 17:50:18 -0800425
Jeff Brown05dc66a2011-03-02 14:41:58 -0800426 controller = new PointerController(mLooper, layer);
Jeff Brown83c09682010-12-23 17:50:18 -0800427 mLocked.pointerController = controller;
428
429 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
430 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800431
432 jobject iconObj = env->CallObjectMethod(mCallbacksObj, gCallbacksClassInfo.getPointerIcon);
433 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon") && iconObj) {
434 jfloat iconHotSpotX = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotX);
435 jfloat iconHotSpotY = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotY);
436 jobject iconBitmapObj = env->GetObjectField(iconObj, gPointerIconClassInfo.bitmap);
437 if (iconBitmapObj) {
438 SkBitmap* iconBitmap = GraphicsJNI::getNativeBitmap(env, iconBitmapObj);
439 if (iconBitmap) {
440 controller->setPointerIcon(iconBitmap, iconHotSpotX, iconHotSpotY);
441 }
442 env->DeleteLocalRef(iconBitmapObj);
443 }
444 env->DeleteLocalRef(iconObj);
445 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800446
447 updateInactivityFadeDelayLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800448 }
449 return controller;
450}
451
Jeff Browne20c9e02010-10-11 14:20:19 -0700452void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
453 int32_t switchValue, uint32_t policyFlags) {
454#if DEBUG_INPUT_DISPATCHER_POLICY
455 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
456 when, switchCode, switchValue, policyFlags);
457#endif
458
459 JNIEnv* env = jniEnv();
460
461 switch (switchCode) {
462 case SW_LID:
463 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
464 when, switchValue == 0);
465 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
466 break;
467 }
468}
469
Jeff Brown9c3cda02010-06-15 01:31:58 -0700470void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
471#if DEBUG_INPUT_DISPATCHER_POLICY
472 LOGD("notifyConfigurationChanged - when=%lld", when);
473#endif
474
475 JNIEnv* env = jniEnv();
476
Jeff Brown57c59372010-09-21 18:22:55 -0700477 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700478 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700479}
480
Jeff Brown519e0242010-09-15 15:18:56 -0700481nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800482 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700483#if DEBUG_INPUT_DISPATCHER_POLICY
484 LOGD("notifyANR");
485#endif
486
487 JNIEnv* env = jniEnv();
488
Jeff Brown928e0542011-01-10 11:17:36 -0800489 jobject inputApplicationHandleObj =
490 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
491 jobject inputWindowHandleObj =
492 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700493
Jeff Brown519e0242010-09-15 15:18:56 -0700494 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800495 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700496 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
497 newTimeout = 0; // abort dispatch
498 } else {
499 assert(newTimeout >= 0);
500 }
501
Jeff Brown928e0542011-01-10 11:17:36 -0800502 env->DeleteLocalRef(inputWindowHandleObj);
503 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700504 return newTimeout;
505}
506
Jeff Brown928e0542011-01-10 11:17:36 -0800507void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700508#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800509 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700510#endif
511
Jeff Brown7fbdc842010-06-17 20:52:56 -0700512 JNIEnv* env = jniEnv();
513
Jeff Brown928e0542011-01-10 11:17:36 -0800514 jobject inputWindowHandleObj =
515 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
516 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700517 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800518 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700519 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
520
Jeff Brown928e0542011-01-10 11:17:36 -0800521 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700522 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700523}
524
Jeff Brown9c3cda02010-06-15 01:31:58 -0700525nsecs_t NativeInputManager::getKeyRepeatTimeout() {
526 if (! isScreenOn()) {
527 // Disable key repeat when the screen is off.
528 return -1;
529 } else {
Jeff Browna4547672011-03-02 21:38:11 -0800530 if (mKeyRepeatTimeout < 0) {
531 JNIEnv* env = jniEnv();
532
533 jint result = env->CallIntMethod(mCallbacksObj,
534 gCallbacksClassInfo.getKeyRepeatTimeout);
535 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
536 result = 500;
537 }
538
539 mKeyRepeatTimeout = milliseconds_to_nanoseconds(result);
540 }
541 return mKeyRepeatTimeout;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700542 }
543}
544
Jeff Brownb21fb102010-09-07 10:44:57 -0700545nsecs_t NativeInputManager::getKeyRepeatDelay() {
Jeff Browna4547672011-03-02 21:38:11 -0800546 if (mKeyRepeatDelay < 0) {
547 JNIEnv* env = jniEnv();
548
549 jint result = env->CallIntMethod(mCallbacksObj,
550 gCallbacksClassInfo.getKeyRepeatDelay);
551 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
552 result = 50;
553 }
554
555 mKeyRepeatDelay = milliseconds_to_nanoseconds(result);
556 }
557 return mKeyRepeatDelay;
Jeff Brownb21fb102010-09-07 10:44:57 -0700558}
559
Jeff Brownae9fc032010-08-18 15:51:08 -0700560int32_t NativeInputManager::getMaxEventsPerSecond() {
561 if (mMaxEventsPerSecond < 0) {
562 JNIEnv* env = jniEnv();
563
564 jint result = env->CallIntMethod(mCallbacksObj,
565 gCallbacksClassInfo.getMaxEventsPerSecond);
566 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700567 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700568 }
569
570 mMaxEventsPerSecond = result;
571 }
572 return mMaxEventsPerSecond;
573}
574
Jeff Brown349703e2010-06-22 01:27:15 -0700575void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700576 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700577
Jeff Brownb88102f2010-09-08 11:49:43 -0700578 jsize length = env->GetArrayLength(windowObjArray);
579 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800580 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
581 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700582 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700583 }
584
Jeff Brownb88102f2010-09-08 11:49:43 -0700585 windows.push();
586 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800587 android_server_InputWindow_toNative(env, windowObj, &window);
588 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700589 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700590 }
Jeff Brown928e0542011-01-10 11:17:36 -0800591 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700592 }
Jeff Brown349703e2010-06-22 01:27:15 -0700593
Jeff Brownb88102f2010-09-08 11:49:43 -0700594 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700595}
596
Jeff Brown349703e2010-06-22 01:27:15 -0700597void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700598 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700599 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800600 android_server_InputApplication_toNative(env, applicationObj, &application);
601 if (application.inputApplicationHandle != NULL) {
602 mInputManager->getDispatcher()->setFocusedApplication(&application);
603 }
Jeff Brown349703e2010-06-22 01:27:15 -0700604 }
Jeff Brown928e0542011-01-10 11:17:36 -0800605 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700606}
607
608void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700609 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700610}
611
Jeff Brown05dc66a2011-03-02 14:41:58 -0800612void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
613 AutoMutex _l(mLock);
614
615 if (mLocked.systemUiVisibility != visibility) {
616 mLocked.systemUiVisibility = visibility;
617
618 sp<PointerController> controller = mLocked.pointerController.promote();
619 if (controller != NULL) {
620 updateInactivityFadeDelayLocked(controller);
621 }
622 }
623}
624
625void NativeInputManager::updateInactivityFadeDelayLocked(const sp<PointerController>& controller) {
626 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
627 controller->setInactivityFadeDelay(lightsOut
628 ? PointerController::INACTIVITY_FADE_DELAY_SHORT
629 : PointerController::INACTIVITY_FADE_DELAY_NORMAL);
630}
631
Jeff Browne20c9e02010-10-11 14:20:19 -0700632bool NativeInputManager::isScreenOn() {
633 return android_server_PowerManagerService_isScreenOn();
634}
635
636bool NativeInputManager::isScreenBright() {
637 return android_server_PowerManagerService_isScreenBright();
638}
639
Jeff Brown1f245102010-11-18 20:53:46 -0800640void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
641 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700642 // Policy:
643 // - Ignore untrusted events and pass them along.
644 // - Ask the window manager what to do with normal events and trusted injected events.
645 // - For normal events wake and brighten the screen if currently off or dim.
646 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800647 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700648 bool isScreenOn = this->isScreenOn();
649 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700650
Jeff Brown3122e442010-10-11 23:32:49 -0700651 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800652 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
653 jint wmActions;
654 if (keyEventObj) {
655 wmActions = env->CallIntMethod(mCallbacksObj,
656 gCallbacksClassInfo.interceptKeyBeforeQueueing,
657 keyEventObj, policyFlags, isScreenOn);
658 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
659 wmActions = 0;
660 }
661 android_view_KeyEvent_recycle(env, keyEventObj);
662 env->DeleteLocalRef(keyEventObj);
663 } else {
664 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700665 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700666 }
667
Jeff Brown1f245102010-11-18 20:53:46 -0800668 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700669 if (!isScreenOn) {
670 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700671 }
672
673 if (!isScreenBright) {
674 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
675 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700676 }
677
Jeff Brown56194eb2011-03-02 19:23:13 -0800678 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700679 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700680 policyFlags |= POLICY_FLAG_PASS_TO_USER;
681 }
682}
683
Jeff Brown56194eb2011-03-02 19:23:13 -0800684void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700685 // Policy:
686 // - Ignore untrusted events and pass them along.
687 // - No special filtering for injected events required at this time.
688 // - Filter normal events based on screen state.
689 // - For normal events brighten (but do not wake) the screen if currently dim.
690 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
691 if (isScreenOn()) {
692 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700693
Jeff Brown3122e442010-10-11 23:32:49 -0700694 if (!isScreenBright()) {
695 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
696 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800697 } else {
698 JNIEnv* env = jniEnv();
699 jint wmActions = env->CallIntMethod(mCallbacksObj,
700 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
701 policyFlags);
702 if (checkAndClearExceptionFromCallback(env,
703 "interceptMotionBeforeQueueingWhenScreenOff")) {
704 wmActions = 0;
705 }
706
707 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
708 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700709 }
Jeff Brown3122e442010-10-11 23:32:49 -0700710 } else {
711 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700712 }
713}
714
Jeff Brown56194eb2011-03-02 19:23:13 -0800715void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
716 uint32_t& policyFlags) {
717 enum {
718 WM_ACTION_PASS_TO_USER = 1,
719 WM_ACTION_POKE_USER_ACTIVITY = 2,
720 WM_ACTION_GO_TO_SLEEP = 4,
721 };
722
723 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
724#ifdef DEBUG_INPUT_DISPATCHER_POLICY
725 LOGD("handleInterceptActions: Going to sleep.");
726#endif
727 android_server_PowerManagerService_goToSleep(when);
728 }
729
730 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
731#ifdef DEBUG_INPUT_DISPATCHER_POLICY
732 LOGD("handleInterceptActions: Poking user activity.");
733#endif
734 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
735 }
736
737 if (wmActions & WM_ACTION_PASS_TO_USER) {
738 policyFlags |= POLICY_FLAG_PASS_TO_USER;
739 } else {
740#ifdef DEBUG_INPUT_DISPATCHER_POLICY
741 LOGD("handleInterceptActions: Not passing key to user.");
742#endif
743 }
744}
745
Jeff Brown928e0542011-01-10 11:17:36 -0800746bool NativeInputManager::interceptKeyBeforeDispatching(
747 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700748 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700749 // Policy:
750 // - Ignore untrusted events and pass them along.
751 // - Filter normal events and trusted injected events through the window manager policy to
752 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800753 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700754 if (policyFlags & POLICY_FLAG_TRUSTED) {
755 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700756
Jeff Brown928e0542011-01-10 11:17:36 -0800757 // Note: inputWindowHandle may be null.
758 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800759 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
760 if (keyEventObj) {
761 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
762 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800763 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800764 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
765 android_view_KeyEvent_recycle(env, keyEventObj);
766 env->DeleteLocalRef(keyEventObj);
767 result = consumed && !error;
768 } else {
769 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800770 }
Jeff Brown928e0542011-01-10 11:17:36 -0800771 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700772 }
Jeff Brown1f245102010-11-18 20:53:46 -0800773 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700774}
775
Jeff Brown928e0542011-01-10 11:17:36 -0800776bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800777 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700778 // Policy:
779 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800780 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700781 if (policyFlags & POLICY_FLAG_TRUSTED) {
782 JNIEnv* env = jniEnv();
783
Jeff Brown928e0542011-01-10 11:17:36 -0800784 // Note: inputWindowHandle may be null.
785 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800786 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
787 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800788 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800789 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800790 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800791 checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey");
Jeff Brown1f245102010-11-18 20:53:46 -0800792 android_view_KeyEvent_recycle(env, keyEventObj);
793 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800794
795 if (fallbackKeyEventObj) {
796 // Note: outFallbackKeyEvent may be the same object as keyEvent.
797 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
798 outFallbackKeyEvent)) {
799 result = true;
800 }
801 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
802 env->DeleteLocalRef(fallbackKeyEventObj);
803 }
Jeff Brown1f245102010-11-18 20:53:46 -0800804 } else {
805 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800806 }
Jeff Brown928e0542011-01-10 11:17:36 -0800807 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700808 }
Jeff Brown1f245102010-11-18 20:53:46 -0800809 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700810}
811
Jeff Brown01ce2e92010-09-26 22:20:12 -0700812void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
813 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700814}
815
Jeff Brown349703e2010-06-22 01:27:15 -0700816
Jeff Brownb88102f2010-09-08 11:49:43 -0700817bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
818 int32_t injectorPid, int32_t injectorUid) {
819 JNIEnv* env = jniEnv();
820 jboolean result = env->CallBooleanMethod(mCallbacksObj,
821 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
822 checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission");
Jeff Brown349703e2010-06-22 01:27:15 -0700823 return result;
824}
825
Jeff Brown83c09682010-12-23 17:50:18 -0800826
Jeff Brown9c3cda02010-06-15 01:31:58 -0700827// ----------------------------------------------------------------------------
828
829static sp<NativeInputManager> gNativeInputManager;
830
Jeff Brown46b9ac02010-04-22 18:58:52 -0700831static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700832 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700833 LOGE("Input manager not initialized.");
834 jniThrowRuntimeException(env, "Input manager not initialized.");
835 return true;
836 }
837 return false;
838}
839
840static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown05dc66a2011-03-02 14:41:58 -0800841 jobject callbacks, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700842 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800843 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
844 gNativeInputManager = new NativeInputManager(callbacks, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700845 } else {
846 LOGE("Input manager already initialized.");
847 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700848 }
849}
850
851static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
852 if (checkInputManagerUnitialized(env)) {
853 return;
854 }
855
Jeff Brown9c3cda02010-06-15 01:31:58 -0700856 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700857 if (result) {
858 jniThrowRuntimeException(env, "Input manager could not be started.");
859 }
860}
861
862static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
863 jint displayId, jint width, jint height) {
864 if (checkInputManagerUnitialized(env)) {
865 return;
866 }
867
868 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
869 // to be passed in like this, not sure which is better but leaving it like this
870 // keeps the window manager in direct control of when display transitions propagate down
871 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700872 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700873}
874
875static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
876 jint displayId, jint orientation) {
877 if (checkInputManagerUnitialized(env)) {
878 return;
879 }
880
Jeff Brown9c3cda02010-06-15 01:31:58 -0700881 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700882}
883
884static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700885 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700886 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700887 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700888 }
889
Jeff Brownb88102f2010-09-08 11:49:43 -0700890 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700891 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700892}
893
894static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700895 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700896 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700897 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700898 }
899
Jeff Brownb88102f2010-09-08 11:49:43 -0700900 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700901 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700902}
903
904static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700905 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700906 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700907 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700908 }
909
Jeff Brownb88102f2010-09-08 11:49:43 -0700910 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700911 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700912}
913
914static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700915 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700916 if (checkInputManagerUnitialized(env)) {
917 return JNI_FALSE;
918 }
919
920 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
921 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
922 jsize numCodes = env->GetArrayLength(keyCodes);
923 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700924 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700925 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700926 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700927 } else {
928 result = JNI_FALSE;
929 }
930
931 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
932 env->ReleaseIntArrayElements(keyCodes, codes, 0);
933 return result;
934}
935
936static void throwInputChannelNotInitialized(JNIEnv* env) {
937 jniThrowException(env, "java/lang/IllegalStateException",
938 "inputChannel is not initialized");
939}
940
941static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
942 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
943 LOGW("Input channel object '%s' was disposed without first being unregistered with "
944 "the input manager!", inputChannel->getName().string());
945
Jeff Brown9c3cda02010-06-15 01:31:58 -0700946 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700947 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700948 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700949}
950
951static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -0800952 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700953 if (checkInputManagerUnitialized(env)) {
954 return;
955 }
956
957 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
958 inputChannelObj);
959 if (inputChannel == NULL) {
960 throwInputChannelNotInitialized(env);
961 return;
962 }
963
Jeff Brown928e0542011-01-10 11:17:36 -0800964 sp<InputWindowHandle> inputWindowHandle =
965 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700966
967 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -0800968 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700969 if (status) {
970 jniThrowRuntimeException(env, "Failed to register input channel. "
971 "Check logs for details.");
972 return;
973 }
974
Jeff Browna41ca772010-08-11 14:46:32 -0700975 if (! monitor) {
976 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
977 android_server_InputManager_handleInputChannelDisposed, NULL);
978 }
Jeff Brown46b9ac02010-04-22 18:58:52 -0700979}
980
981static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
982 jobject inputChannelObj) {
983 if (checkInputManagerUnitialized(env)) {
984 return;
985 }
986
987 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
988 inputChannelObj);
989 if (inputChannel == NULL) {
990 throwInputChannelNotInitialized(env);
991 return;
992 }
993
994 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
995
Jeff Brown7fbdc842010-06-17 20:52:56 -0700996 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700997 if (status) {
998 jniThrowRuntimeException(env, "Failed to unregister input channel. "
999 "Check logs for details.");
1000 }
1001}
1002
Jeff Brown6ec402b2010-07-28 15:48:59 -07001003static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1004 jobject inputEventObj, jint injectorPid, jint injectorUid,
1005 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001006 if (checkInputManagerUnitialized(env)) {
1007 return INPUT_EVENT_INJECTION_FAILED;
1008 }
1009
Jeff Brown6ec402b2010-07-28 15:48:59 -07001010 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1011 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001012 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1013 if (status) {
1014 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1015 return INPUT_EVENT_INJECTION_FAILED;
1016 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001017
Jeff Brownb88102f2010-09-08 11:49:43 -07001018 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1019 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001020 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
1021 MotionEvent motionEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001022 status_t status = android_view_MotionEvent_toNative(env, inputEventObj, & motionEvent);
1023 if (status) {
1024 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1025 return INPUT_EVENT_INJECTION_FAILED;
1026 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001027
Jeff Brownb88102f2010-09-08 11:49:43 -07001028 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1029 & motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001030 } else {
1031 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001032 return INPUT_EVENT_INJECTION_FAILED;
1033 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001034}
1035
Jeff Brown349703e2010-06-22 01:27:15 -07001036static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1037 jobjectArray windowObjArray) {
1038 if (checkInputManagerUnitialized(env)) {
1039 return;
1040 }
1041
1042 gNativeInputManager->setInputWindows(env, windowObjArray);
1043}
1044
1045static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1046 jobject applicationObj) {
1047 if (checkInputManagerUnitialized(env)) {
1048 return;
1049 }
1050
1051 gNativeInputManager->setFocusedApplication(env, applicationObj);
1052}
1053
1054static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1055 jclass clazz, jboolean enabled, jboolean frozen) {
1056 if (checkInputManagerUnitialized(env)) {
1057 return;
1058 }
1059
1060 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1061}
1062
Jeff Brown05dc66a2011-03-02 14:41:58 -08001063static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1064 jclass clazz, jint visibility) {
1065 if (checkInputManagerUnitialized(env)) {
1066 return;
1067 }
1068
1069 gNativeInputManager->setSystemUiVisibility(visibility);
1070}
1071
Jeff Brown8d608662010-08-30 03:02:23 -07001072static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1073 jclass clazz, jint deviceId) {
1074 if (checkInputManagerUnitialized(env)) {
1075 return NULL;
1076 }
1077
1078 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001079 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001080 deviceId, & deviceInfo);
1081 if (status) {
1082 return NULL;
1083 }
1084
1085 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1086 if (! deviceObj) {
1087 return NULL;
1088 }
1089
1090 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1091 if (! deviceNameObj) {
1092 return NULL;
1093 }
1094
1095 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1096 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1097 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1098 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1099
1100 const KeyedVector<int, InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
1101 for (size_t i = 0; i < ranges.size(); i++) {
1102 int rangeType = ranges.keyAt(i);
1103 const InputDeviceInfo::MotionRange& range = ranges.valueAt(i);
1104 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
1105 rangeType, range.min, range.max, range.flat, range.fuzz);
1106 if (env->ExceptionCheck()) {
1107 return NULL;
1108 }
1109 }
1110
1111 return deviceObj;
1112}
1113
1114static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1115 jclass clazz) {
1116 if (checkInputManagerUnitialized(env)) {
1117 return NULL;
1118 }
1119
1120 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001121 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001122
1123 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1124 if (! deviceIdsObj) {
1125 return NULL;
1126 }
1127
1128 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1129 return deviceIdsObj;
1130}
1131
Jeff Brown57c59372010-09-21 18:22:55 -07001132static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1133 jclass clazz, jobject configObj) {
1134 if (checkInputManagerUnitialized(env)) {
1135 return;
1136 }
1137
1138 InputConfiguration config;
1139 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1140
1141 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1142 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1143 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1144}
1145
Jeff Browne6504122010-09-27 14:52:15 -07001146static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1147 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1148 if (checkInputManagerUnitialized(env)) {
1149 return false;
1150 }
1151
1152 sp<InputChannel> fromChannel =
1153 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1154 sp<InputChannel> toChannel =
1155 android_view_InputChannel_getInputChannel(env, toChannelObj);
1156
1157 if (fromChannel == NULL || toChannel == NULL) {
1158 return false;
1159 }
1160
1161 return gNativeInputManager->getInputManager()->getDispatcher()->
1162 transferTouchFocus(fromChannel, toChannel);
1163}
1164
Jeff Browne33348b2010-07-15 23:54:05 -07001165static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1166 if (checkInputManagerUnitialized(env)) {
1167 return NULL;
1168 }
1169
Jeff Brownb88102f2010-09-08 11:49:43 -07001170 String8 dump;
1171 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001172 return env->NewStringUTF(dump.string());
1173}
1174
Jeff Brown9c3cda02010-06-15 01:31:58 -07001175// ----------------------------------------------------------------------------
1176
Jeff Brown46b9ac02010-04-22 18:58:52 -07001177static JNINativeMethod gInputManagerMethods[] = {
1178 /* name, signature, funcPtr */
Jeff Brown05dc66a2011-03-02 14:41:58 -08001179 { "nativeInit", "(Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001180 (void*) android_server_InputManager_nativeInit },
1181 { "nativeStart", "()V",
1182 (void*) android_server_InputManager_nativeStart },
1183 { "nativeSetDisplaySize", "(III)V",
1184 (void*) android_server_InputManager_nativeSetDisplaySize },
1185 { "nativeSetDisplayOrientation", "(II)V",
1186 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1187 { "nativeGetScanCodeState", "(III)I",
1188 (void*) android_server_InputManager_nativeGetScanCodeState },
1189 { "nativeGetKeyCodeState", "(III)I",
1190 (void*) android_server_InputManager_nativeGetKeyCodeState },
1191 { "nativeGetSwitchState", "(III)I",
1192 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001193 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001194 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001195 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001196 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001197 (void*) android_server_InputManager_nativeRegisterInputChannel },
1198 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001199 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001200 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1201 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001202 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001203 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001204 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001205 (void*) android_server_InputManager_nativeSetFocusedApplication },
1206 { "nativeSetInputDispatchMode", "(ZZ)V",
1207 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001208 { "nativeSetSystemUiVisibility", "(I)V",
1209 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001210 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1211 (void*) android_server_InputManager_nativeGetInputDevice },
1212 { "nativeGetInputDeviceIds", "()[I",
1213 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001214 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1215 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001216 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1217 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001218 { "nativeDump", "()Ljava/lang/String;",
1219 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001220};
1221
1222#define FIND_CLASS(var, className) \
1223 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001224 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001225
1226#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1227 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1228 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1229
1230#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1231 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1232 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1233
1234int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001235 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001236 gInputManagerMethods, NELEM(gInputManagerMethods));
1237 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1238
Jeff Brown9c3cda02010-06-15 01:31:58 -07001239 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001240
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001241 jclass clazz;
1242 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001243
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001244 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001245 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001246
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001247 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001248 "notifyLidSwitchChanged", "(JZ)V");
1249
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001250 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001251 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001252
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001253 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001254 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001255 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001256
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001257 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001258 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001259
Jeff Brown56194eb2011-03-02 19:23:13 -08001260 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001261 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001262 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1263
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001264 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001265 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001266 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001267
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001268 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001269 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001270 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001271
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001272 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001273 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001274
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001275 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001276 "filterTouchEvents", "()Z");
1277
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001278 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001279 "filterJumpyTouchEvents", "()Z");
1280
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001281 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001282 "getVirtualKeyQuietTimeMillis", "()I");
1283
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001284 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001285 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1286
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001287 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001288 "getKeyRepeatTimeout", "()I");
1289
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001290 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001291 "getKeyRepeatDelay", "()I");
1292
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001293 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001294 "getMaxEventsPerSecond", "()I");
1295
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001296 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001297 "getPointerLayer", "()I");
1298
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001299 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001300 "getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001301
Jeff Brown6ec402b2010-07-28 15:48:59 -07001302 // KeyEvent
1303
1304 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001305 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1306
Jeff Brown6ec402b2010-07-28 15:48:59 -07001307
Jeff Brown8d608662010-08-30 03:02:23 -07001308 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001309
1310 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001311 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001312
Jeff Brown8d608662010-08-30 03:02:23 -07001313 // InputDevice
1314
1315 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001316 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001317
1318 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1319 "<init>", "()V");
1320
1321 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
1322 "addMotionRange", "(IFFFF)V");
1323
1324 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1325 "mId", "I");
1326
1327 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1328 "mName", "Ljava/lang/String;");
1329
1330 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1331 "mSources", "I");
1332
1333 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1334 "mKeyboardType", "I");
1335
Jeff Brown57c59372010-09-21 18:22:55 -07001336 // Configuration
1337
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001338 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001339
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001340 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001341 "touchscreen", "I");
1342
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001343 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001344 "keyboard", "I");
1345
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001346 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001347 "navigation", "I");
1348
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001349 // PointerIcon
1350
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001351 FIND_CLASS(clazz, "com/android/server/wm/InputManager$PointerIcon");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001352
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001353 GET_FIELD_ID(gPointerIconClassInfo.bitmap, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001354 "bitmap", "Landroid/graphics/Bitmap;");
1355
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001356 GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001357 "hotSpotX", "F");
1358
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001359 GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, clazz,
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001360 "hotSpotY", "F");
1361
Jeff Brown46b9ac02010-04-22 18:58:52 -07001362 return 0;
1363}
1364
Jeff Brown46b9ac02010-04-22 18:58:52 -07001365} /* namespace android */