blob: 7985fab08d54116e6646591c92d9839b7504261e [file] [log] [blame]
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputManager-JNI"
18
Jeff Brown9c3cda02010-06-15 01:31:58 -070019//#define LOG_NDEBUG 0
20
21// Log debug messages about InputReaderPolicy
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INPUT_READER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070023
24// Log debug messages about InputDispatcherPolicy
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_INPUT_DISPATCHER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070026
Jeff Brown83c09682010-12-23 17:50:18 -080027
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070028#include "JNIHelp.h"
29#include "jni.h"
Jeff Brown349703e2010-06-22 01:27:15 -070030#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070031#include <android_runtime/AndroidRuntime.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080032
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070033#include <utils/Log.h>
Jeff Brown05dc66a2011-03-02 14:41:58 -080034#include <utils/Looper.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070035#include <utils/threads.h>
Jeff Brown83c09682010-12-23 17:50:18 -080036
Jeff Brownb4ff35d2011-01-02 16:37:43 -080037#include <input/InputManager.h>
38#include <input/PointerController.h>
Jeff Browna6dbfdd2011-04-11 11:54:25 -070039#include <input/SpotController.h>
40#include <input/SpriteController.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080041
Jeff Brown05dc66a2011-03-02 14:41:58 -080042#include <android_os_MessageQueue.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080043#include <android_view_KeyEvent.h>
44#include <android_view_MotionEvent.h>
45#include <android_view_InputChannel.h>
46#include <android/graphics/GraphicsJNI.h>
47
Jeff Brown00fa7bd2010-07-02 15:37:36 -070048#include "com_android_server_PowerManagerService.h"
Jeff Brown928e0542011-01-10 11:17:36 -080049#include "com_android_server_InputApplication.h"
50#include "com_android_server_InputApplicationHandle.h"
51#include "com_android_server_InputWindow.h"
52#include "com_android_server_InputWindowHandle.h"
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070053
54namespace android {
55
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070056static struct {
57 jclass clazz;
58
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070059 jmethodID notifyConfigurationChanged;
60 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070061 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070062 jmethodID notifyANR;
Jeff Brown349703e2010-06-22 01:27:15 -070063 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080064 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070065 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070066 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070067 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070068 jmethodID filterTouchEvents;
69 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080070 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070071 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080072 jmethodID getKeyRepeatTimeout;
73 jmethodID getKeyRepeatDelay;
Jeff Brownae9fc032010-08-18 15:51:08 -070074 jmethodID getMaxEventsPerSecond;
Jeff Brown83c09682010-12-23 17:50:18 -080075 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080076 jmethodID getPointerIcon;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070077} gCallbacksClassInfo;
78
79static struct {
80 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070081} gKeyEventClassInfo;
82
83static struct {
84 jclass clazz;
85} gMotionEventClassInfo;
86
Jeff Brown8d608662010-08-30 03:02:23 -070087static struct {
88 jclass clazz;
89
90 jmethodID ctor;
91 jmethodID addMotionRange;
92
93 jfieldID mId;
94 jfieldID mName;
95 jfieldID mSources;
96 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -070097} gInputDeviceClassInfo;
98
Jeff Brown57c59372010-09-21 18:22:55 -070099static struct {
100 jclass clazz;
101
102 jfieldID touchscreen;
103 jfieldID keyboard;
104 jfieldID navigation;
105} gConfigurationClassInfo;
106
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800107static struct {
108 jclass clazz;
Jeff Brown349703e2010-06-22 01:27:15 -0700109
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800110 jfieldID bitmap;
111 jfieldID hotSpotX;
112 jfieldID hotSpotY;
113} gPointerIconClassInfo;
Jeff Brown83c09682010-12-23 17:50:18 -0800114
Jeff Brown928e0542011-01-10 11:17:36 -0800115
116// --- Global functions ---
117
118static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
119 const sp<InputApplicationHandle>& inputApplicationHandle) {
120 if (inputApplicationHandle == NULL) {
121 return NULL;
122 }
123 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
124 getInputApplicationHandleObjLocalRef(env);
125}
126
127static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
128 const sp<InputWindowHandle>& inputWindowHandle) {
129 if (inputWindowHandle == NULL) {
130 return NULL;
131 }
132 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
133 getInputWindowHandleObjLocalRef(env);
134}
135
136
137// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800138
Jeff Brown9c3cda02010-06-15 01:31:58 -0700139class NativeInputManager : public virtual RefBase,
140 public virtual InputReaderPolicyInterface,
141 public virtual InputDispatcherPolicyInterface {
142protected:
143 virtual ~NativeInputManager();
144
145public:
Jeff Brown05dc66a2011-03-02 14:41:58 -0800146 NativeInputManager(jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700147
148 inline sp<InputManager> getInputManager() const { return mInputManager; }
149
Jeff Brownb88102f2010-09-08 11:49:43 -0700150 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700151
Jeff Brown9c3cda02010-06-15 01:31:58 -0700152 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
153 void setDisplayOrientation(int32_t displayId, int32_t orientation);
154
Jeff Brown7fbdc842010-06-17 20:52:56 -0700155 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800156 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700157 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
158
Jeff Brown349703e2010-06-22 01:27:15 -0700159 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
160 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
161 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800162 void setSystemUiVisibility(int32_t visibility);
Jeff Brown349703e2010-06-22 01:27:15 -0700163
Jeff Brown9c3cda02010-06-15 01:31:58 -0700164 /* --- InputReaderPolicyInterface implementation --- */
165
166 virtual bool getDisplayInfo(int32_t displayId,
167 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700168 virtual bool filterTouchEvents();
169 virtual bool filterJumpyTouchEvents();
Jeff Brownfe508922011-01-18 15:10:10 -0800170 virtual nsecs_t getVirtualKeyQuietTime();
Jeff Brown9c3cda02010-06-15 01:31:58 -0700171 virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
Jeff Brown83c09682010-12-23 17:50:18 -0800172 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700173 virtual sp<SpotControllerInterface> obtainSpotController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700174
175 /* --- InputDispatcherPolicyInterface implementation --- */
176
Jeff Browne20c9e02010-10-11 14:20:19 -0700177 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
178 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700179 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700180 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800181 const sp<InputWindowHandle>& inputWindowHandle);
182 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700183 virtual nsecs_t getKeyRepeatTimeout();
Jeff Brownb21fb102010-09-07 10:44:57 -0700184 virtual nsecs_t getKeyRepeatDelay();
Jeff Brownae9fc032010-08-18 15:51:08 -0700185 virtual int32_t getMaxEventsPerSecond();
Jeff Brown1f245102010-11-18 20:53:46 -0800186 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800187 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800188 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700189 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800190 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800191 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700192 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700193 virtual bool checkInjectEventsPermissionNonReentrant(
194 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700195
196private:
197 sp<InputManager> mInputManager;
198
199 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800200 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700201
202 // Cached filtering policies.
203 int32_t mFilterTouchEvents;
204 int32_t mFilterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -0800205 nsecs_t mVirtualKeyQuietTime;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700206
Jeff Browna4547672011-03-02 21:38:11 -0800207 // Cached key repeat policy.
208 nsecs_t mKeyRepeatTimeout;
209 nsecs_t mKeyRepeatDelay;
210
Jeff Brownae9fc032010-08-18 15:51:08 -0700211 // Cached throttling policy.
212 int32_t mMaxEventsPerSecond;
213
Jeff Brown83c09682010-12-23 17:50:18 -0800214 Mutex mLock;
215 struct Locked {
216 // Display size information.
217 int32_t displayWidth, displayHeight; // -1 when initialized
218 int32_t displayOrientation;
219
Jeff Brown05dc66a2011-03-02 14:41:58 -0800220 // System UI visibility.
221 int32_t systemUiVisibility;
222
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700223 // Sprite controller singleton, created on first use.
224 sp<SpriteController> spriteController;
225
Jeff Brown83c09682010-12-23 17:50:18 -0800226 // Pointer controller singleton, created and destroyed as needed.
227 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800228 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700229
Jeff Brown05dc66a2011-03-02 14:41:58 -0800230 void updateInactivityFadeDelayLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800231 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700232 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800233
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700234 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700235 bool isScreenOn();
236 bool isScreenBright();
237
Jeff Brownb88102f2010-09-08 11:49:43 -0700238 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700239
Jeff Brown9c3cda02010-06-15 01:31:58 -0700240 static inline JNIEnv* jniEnv() {
241 return AndroidRuntime::getJNIEnv();
242 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700243};
244
Jeff Brown928e0542011-01-10 11:17:36 -0800245
Jeff Brown9c3cda02010-06-15 01:31:58 -0700246
Jeff Brown05dc66a2011-03-02 14:41:58 -0800247NativeInputManager::NativeInputManager(jobject callbacksObj, const sp<Looper>& looper) :
248 mLooper(looper),
249 mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
Jeff Browna4547672011-03-02 21:38:11 -0800250 mKeyRepeatTimeout(-1), mKeyRepeatDelay(-1),
Jeff Brown05dc66a2011-03-02 14:41:58 -0800251 mMaxEventsPerSecond(-1) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700252 JNIEnv* env = jniEnv();
253
254 mCallbacksObj = env->NewGlobalRef(callbacksObj);
255
Jeff Brown83c09682010-12-23 17:50:18 -0800256 {
257 AutoMutex _l(mLock);
258 mLocked.displayWidth = -1;
259 mLocked.displayHeight = -1;
260 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800261
262 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown83c09682010-12-23 17:50:18 -0800263 }
264
Jeff Brown9c3cda02010-06-15 01:31:58 -0700265 sp<EventHub> eventHub = new EventHub();
266 mInputManager = new InputManager(eventHub, this, this);
267}
268
269NativeInputManager::~NativeInputManager() {
270 JNIEnv* env = jniEnv();
271
272 env->DeleteGlobalRef(mCallbacksObj);
273}
274
Jeff Brownb88102f2010-09-08 11:49:43 -0700275void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700276 mInputManager->getReader()->dump(dump);
277 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700278
Jeff Brownb88102f2010-09-08 11:49:43 -0700279 mInputManager->getDispatcher()->dump(dump);
280 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700281}
282
Jeff Brown7fbdc842010-06-17 20:52:56 -0700283bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700284 if (env->ExceptionCheck()) {
285 LOGE("An exception was thrown by callback '%s'.", methodName);
286 LOGE_EX(env);
287 env->ExceptionClear();
288 return true;
289 }
290 return false;
291}
292
293void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
294 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800295 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700296
Jeff Brown83c09682010-12-23 17:50:18 -0800297 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
298 mLocked.displayWidth = width;
299 mLocked.displayHeight = height;
300
301 sp<PointerController> controller = mLocked.pointerController.promote();
302 if (controller != NULL) {
303 controller->setDisplaySize(width, height);
304 }
305 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700306 }
307}
308
309void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
310 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800311 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700312
Jeff Brown83c09682010-12-23 17:50:18 -0800313 if (mLocked.displayOrientation != orientation) {
314 mLocked.displayOrientation = orientation;
315
316 sp<PointerController> controller = mLocked.pointerController.promote();
317 if (controller != NULL) {
318 controller->setDisplayOrientation(orientation);
319 }
320 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700321 }
322}
323
Jeff Brown7fbdc842010-06-17 20:52:56 -0700324status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800325 const sp<InputChannel>& inputChannel,
326 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
327 return mInputManager->getDispatcher()->registerInputChannel(
328 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700329}
330
331status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
332 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700333 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700334}
335
Jeff Brown9c3cda02010-06-15 01:31:58 -0700336bool NativeInputManager::getDisplayInfo(int32_t displayId,
337 int32_t* width, int32_t* height, int32_t* orientation) {
338 bool result = false;
339 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800340 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700341
Jeff Brown83c09682010-12-23 17:50:18 -0800342 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700343 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800344 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700345 }
346 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800347 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700348 }
349 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800350 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700351 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700352 result = true;
353 }
354 }
355 return result;
356}
357
Jeff Brown9c3cda02010-06-15 01:31:58 -0700358bool NativeInputManager::filterTouchEvents() {
359 if (mFilterTouchEvents < 0) {
360 JNIEnv* env = jniEnv();
361
362 jboolean result = env->CallBooleanMethod(mCallbacksObj,
363 gCallbacksClassInfo.filterTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700364 if (checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700365 result = false;
366 }
367
368 mFilterTouchEvents = result ? 1 : 0;
369 }
370 return mFilterTouchEvents;
371}
372
373bool NativeInputManager::filterJumpyTouchEvents() {
374 if (mFilterJumpyTouchEvents < 0) {
375 JNIEnv* env = jniEnv();
376
377 jboolean result = env->CallBooleanMethod(mCallbacksObj,
378 gCallbacksClassInfo.filterJumpyTouchEvents);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700379 if (checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700380 result = false;
381 }
382
383 mFilterJumpyTouchEvents = result ? 1 : 0;
384 }
385 return mFilterJumpyTouchEvents;
386}
387
Jeff Brownfe508922011-01-18 15:10:10 -0800388nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
389 if (mVirtualKeyQuietTime < 0) {
390 JNIEnv* env = jniEnv();
391
392 jint result = env->CallIntMethod(mCallbacksObj,
393 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
394 if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
395 result = 0;
396 }
397 if (result < 0) {
398 result = 0;
399 }
400
401 mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
402 }
403 return mVirtualKeyQuietTime;
404}
405
Jeff Brown9c3cda02010-06-15 01:31:58 -0700406void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
Jeff Brown8d608662010-08-30 03:02:23 -0700407 outExcludedDeviceNames.clear();
408
Jeff Brown9c3cda02010-06-15 01:31:58 -0700409 JNIEnv* env = jniEnv();
410
411 jobjectArray result = jobjectArray(env->CallObjectMethod(mCallbacksObj,
412 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown7fbdc842010-06-17 20:52:56 -0700413 if (! checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && result) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700414 jsize length = env->GetArrayLength(result);
415 for (jsize i = 0; i < length; i++) {
416 jstring item = jstring(env->GetObjectArrayElement(result, i));
417
418 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
419 outExcludedDeviceNames.add(String8(deviceNameChars));
420 env->ReleaseStringUTFChars(item, deviceNameChars);
421
422 env->DeleteLocalRef(item);
423 }
424 env->DeleteLocalRef(result);
425 }
426}
427
Jeff Brown83c09682010-12-23 17:50:18 -0800428sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
429 AutoMutex _l(mLock);
430
431 sp<PointerController> controller = mLocked.pointerController.promote();
432 if (controller == NULL) {
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700433 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800434
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700435 controller = new PointerController(mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800436 mLocked.pointerController = controller;
437
438 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
439 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800440
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700441 JNIEnv* env = jniEnv();
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800442 jobject iconObj = env->CallObjectMethod(mCallbacksObj, gCallbacksClassInfo.getPointerIcon);
443 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon") && iconObj) {
444 jfloat iconHotSpotX = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotX);
445 jfloat iconHotSpotY = env->GetFloatField(iconObj, gPointerIconClassInfo.hotSpotY);
446 jobject iconBitmapObj = env->GetObjectField(iconObj, gPointerIconClassInfo.bitmap);
447 if (iconBitmapObj) {
448 SkBitmap* iconBitmap = GraphicsJNI::getNativeBitmap(env, iconBitmapObj);
449 if (iconBitmap) {
450 controller->setPointerIcon(iconBitmap, iconHotSpotX, iconHotSpotY);
451 }
452 env->DeleteLocalRef(iconBitmapObj);
453 }
454 env->DeleteLocalRef(iconObj);
455 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800456
457 updateInactivityFadeDelayLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800458 }
459 return controller;
460}
461
Jeff Browna6dbfdd2011-04-11 11:54:25 -0700462sp<SpotControllerInterface> NativeInputManager::obtainSpotController(int32_t deviceId) {
463 AutoMutex _l(mLock);
464
465 ensureSpriteControllerLocked();
466 return new SpotController(mLooper, mLocked.spriteController);
467}
468
469void NativeInputManager::ensureSpriteControllerLocked() {
470 if (mLocked.spriteController == NULL) {
471 JNIEnv* env = jniEnv();
472 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
473 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
474 layer = -1;
475 }
476 mLocked.spriteController = new SpriteController(mLooper, layer);
477 }
478}
479
Jeff Browne20c9e02010-10-11 14:20:19 -0700480void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
481 int32_t switchValue, uint32_t policyFlags) {
482#if DEBUG_INPUT_DISPATCHER_POLICY
483 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
484 when, switchCode, switchValue, policyFlags);
485#endif
486
487 JNIEnv* env = jniEnv();
488
489 switch (switchCode) {
490 case SW_LID:
491 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
492 when, switchValue == 0);
493 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
494 break;
495 }
496}
497
Jeff Brown9c3cda02010-06-15 01:31:58 -0700498void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
499#if DEBUG_INPUT_DISPATCHER_POLICY
500 LOGD("notifyConfigurationChanged - when=%lld", when);
501#endif
502
503 JNIEnv* env = jniEnv();
504
Jeff Brown57c59372010-09-21 18:22:55 -0700505 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700506 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700507}
508
Jeff Brown519e0242010-09-15 15:18:56 -0700509nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800510 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700511#if DEBUG_INPUT_DISPATCHER_POLICY
512 LOGD("notifyANR");
513#endif
514
515 JNIEnv* env = jniEnv();
516
Jeff Brown928e0542011-01-10 11:17:36 -0800517 jobject inputApplicationHandleObj =
518 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
519 jobject inputWindowHandleObj =
520 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700521
Jeff Brown519e0242010-09-15 15:18:56 -0700522 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800523 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700524 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
525 newTimeout = 0; // abort dispatch
526 } else {
527 assert(newTimeout >= 0);
528 }
529
Jeff Brown928e0542011-01-10 11:17:36 -0800530 env->DeleteLocalRef(inputWindowHandleObj);
531 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700532 return newTimeout;
533}
534
Jeff Brown928e0542011-01-10 11:17:36 -0800535void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700536#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800537 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700538#endif
539
Jeff Brown7fbdc842010-06-17 20:52:56 -0700540 JNIEnv* env = jniEnv();
541
Jeff Brown928e0542011-01-10 11:17:36 -0800542 jobject inputWindowHandleObj =
543 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
544 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700545 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800546 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700547 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
548
Jeff Brown928e0542011-01-10 11:17:36 -0800549 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700550 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700551}
552
Jeff Brown9c3cda02010-06-15 01:31:58 -0700553nsecs_t NativeInputManager::getKeyRepeatTimeout() {
554 if (! isScreenOn()) {
555 // Disable key repeat when the screen is off.
556 return -1;
557 } else {
Jeff Browna4547672011-03-02 21:38:11 -0800558 if (mKeyRepeatTimeout < 0) {
559 JNIEnv* env = jniEnv();
560
561 jint result = env->CallIntMethod(mCallbacksObj,
562 gCallbacksClassInfo.getKeyRepeatTimeout);
563 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
564 result = 500;
565 }
566
567 mKeyRepeatTimeout = milliseconds_to_nanoseconds(result);
568 }
569 return mKeyRepeatTimeout;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700570 }
571}
572
Jeff Brownb21fb102010-09-07 10:44:57 -0700573nsecs_t NativeInputManager::getKeyRepeatDelay() {
Jeff Browna4547672011-03-02 21:38:11 -0800574 if (mKeyRepeatDelay < 0) {
575 JNIEnv* env = jniEnv();
576
577 jint result = env->CallIntMethod(mCallbacksObj,
578 gCallbacksClassInfo.getKeyRepeatDelay);
579 if (checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
580 result = 50;
581 }
582
583 mKeyRepeatDelay = milliseconds_to_nanoseconds(result);
584 }
585 return mKeyRepeatDelay;
Jeff Brownb21fb102010-09-07 10:44:57 -0700586}
587
Jeff Brownae9fc032010-08-18 15:51:08 -0700588int32_t NativeInputManager::getMaxEventsPerSecond() {
589 if (mMaxEventsPerSecond < 0) {
590 JNIEnv* env = jniEnv();
591
592 jint result = env->CallIntMethod(mCallbacksObj,
593 gCallbacksClassInfo.getMaxEventsPerSecond);
594 if (checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
Jeff Brown3d8c9bd2010-08-18 17:48:53 -0700595 result = 60;
Jeff Brownae9fc032010-08-18 15:51:08 -0700596 }
597
598 mMaxEventsPerSecond = result;
599 }
600 return mMaxEventsPerSecond;
601}
602
Jeff Brown349703e2010-06-22 01:27:15 -0700603void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700604 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700605
Jeff Brownb88102f2010-09-08 11:49:43 -0700606 jsize length = env->GetArrayLength(windowObjArray);
607 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800608 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
609 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700610 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700611 }
612
Jeff Brownb88102f2010-09-08 11:49:43 -0700613 windows.push();
614 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800615 android_server_InputWindow_toNative(env, windowObj, &window);
616 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700617 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700618 }
Jeff Brown928e0542011-01-10 11:17:36 -0800619 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700620 }
Jeff Brown349703e2010-06-22 01:27:15 -0700621
Jeff Brownb88102f2010-09-08 11:49:43 -0700622 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700623}
624
Jeff Brown349703e2010-06-22 01:27:15 -0700625void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700626 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700627 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800628 android_server_InputApplication_toNative(env, applicationObj, &application);
629 if (application.inputApplicationHandle != NULL) {
630 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Brown22d789d2011-03-25 11:58:46 -0700631 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800632 }
Jeff Brown349703e2010-06-22 01:27:15 -0700633 }
Jeff Brown928e0542011-01-10 11:17:36 -0800634 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700635}
636
637void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700638 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700639}
640
Jeff Brown05dc66a2011-03-02 14:41:58 -0800641void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
642 AutoMutex _l(mLock);
643
644 if (mLocked.systemUiVisibility != visibility) {
645 mLocked.systemUiVisibility = visibility;
646
647 sp<PointerController> controller = mLocked.pointerController.promote();
648 if (controller != NULL) {
649 updateInactivityFadeDelayLocked(controller);
650 }
651 }
652}
653
654void NativeInputManager::updateInactivityFadeDelayLocked(const sp<PointerController>& controller) {
655 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
656 controller->setInactivityFadeDelay(lightsOut
657 ? PointerController::INACTIVITY_FADE_DELAY_SHORT
658 : PointerController::INACTIVITY_FADE_DELAY_NORMAL);
659}
660
Jeff Browne20c9e02010-10-11 14:20:19 -0700661bool NativeInputManager::isScreenOn() {
662 return android_server_PowerManagerService_isScreenOn();
663}
664
665bool NativeInputManager::isScreenBright() {
666 return android_server_PowerManagerService_isScreenBright();
667}
668
Jeff Brown1f245102010-11-18 20:53:46 -0800669void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
670 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700671 // Policy:
672 // - Ignore untrusted events and pass them along.
673 // - Ask the window manager what to do with normal events and trusted injected events.
674 // - For normal events wake and brighten the screen if currently off or dim.
675 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800676 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700677 bool isScreenOn = this->isScreenOn();
678 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700679
Jeff Brown3122e442010-10-11 23:32:49 -0700680 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800681 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
682 jint wmActions;
683 if (keyEventObj) {
684 wmActions = env->CallIntMethod(mCallbacksObj,
685 gCallbacksClassInfo.interceptKeyBeforeQueueing,
686 keyEventObj, policyFlags, isScreenOn);
687 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
688 wmActions = 0;
689 }
690 android_view_KeyEvent_recycle(env, keyEventObj);
691 env->DeleteLocalRef(keyEventObj);
692 } else {
693 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700694 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700695 }
696
Jeff Brown1f245102010-11-18 20:53:46 -0800697 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700698 if (!isScreenOn) {
699 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700700 }
701
702 if (!isScreenBright) {
703 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
704 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700705 }
706
Jeff Brown56194eb2011-03-02 19:23:13 -0800707 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700708 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700709 policyFlags |= POLICY_FLAG_PASS_TO_USER;
710 }
711}
712
Jeff Brown56194eb2011-03-02 19:23:13 -0800713void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700714 // Policy:
715 // - Ignore untrusted events and pass them along.
716 // - No special filtering for injected events required at this time.
717 // - Filter normal events based on screen state.
718 // - For normal events brighten (but do not wake) the screen if currently dim.
719 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
720 if (isScreenOn()) {
721 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700722
Jeff Brown3122e442010-10-11 23:32:49 -0700723 if (!isScreenBright()) {
724 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
725 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800726 } else {
727 JNIEnv* env = jniEnv();
728 jint wmActions = env->CallIntMethod(mCallbacksObj,
729 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
730 policyFlags);
731 if (checkAndClearExceptionFromCallback(env,
732 "interceptMotionBeforeQueueingWhenScreenOff")) {
733 wmActions = 0;
734 }
735
736 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
737 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700738 }
Jeff Brown3122e442010-10-11 23:32:49 -0700739 } else {
740 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700741 }
742}
743
Jeff Brown56194eb2011-03-02 19:23:13 -0800744void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
745 uint32_t& policyFlags) {
746 enum {
747 WM_ACTION_PASS_TO_USER = 1,
748 WM_ACTION_POKE_USER_ACTIVITY = 2,
749 WM_ACTION_GO_TO_SLEEP = 4,
750 };
751
752 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800753#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800754 LOGD("handleInterceptActions: Going to sleep.");
755#endif
756 android_server_PowerManagerService_goToSleep(when);
757 }
758
759 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800760#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800761 LOGD("handleInterceptActions: Poking user activity.");
762#endif
763 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
764 }
765
766 if (wmActions & WM_ACTION_PASS_TO_USER) {
767 policyFlags |= POLICY_FLAG_PASS_TO_USER;
768 } else {
Jeff Brownb23bdf52011-03-07 20:11:22 -0800769#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800770 LOGD("handleInterceptActions: Not passing key to user.");
771#endif
772 }
773}
774
Jeff Brown928e0542011-01-10 11:17:36 -0800775bool NativeInputManager::interceptKeyBeforeDispatching(
776 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700777 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700778 // Policy:
779 // - Ignore untrusted events and pass them along.
780 // - Filter normal events and trusted injected events through the window manager policy to
781 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800782 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700783 if (policyFlags & POLICY_FLAG_TRUSTED) {
784 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700785
Jeff Brown928e0542011-01-10 11:17:36 -0800786 // Note: inputWindowHandle may be null.
787 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800788 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
789 if (keyEventObj) {
790 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
791 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800792 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800793 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
794 android_view_KeyEvent_recycle(env, keyEventObj);
795 env->DeleteLocalRef(keyEventObj);
796 result = consumed && !error;
797 } else {
798 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800799 }
Jeff Brown928e0542011-01-10 11:17:36 -0800800 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700801 }
Jeff Brown1f245102010-11-18 20:53:46 -0800802 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700803}
804
Jeff Brown928e0542011-01-10 11:17:36 -0800805bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800806 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700807 // Policy:
808 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800809 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700810 if (policyFlags & POLICY_FLAG_TRUSTED) {
811 JNIEnv* env = jniEnv();
812
Jeff Brown928e0542011-01-10 11:17:36 -0800813 // Note: inputWindowHandle may be null.
814 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800815 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
816 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800817 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800818 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800819 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown524ee642011-03-29 15:11:34 -0700820 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
821 fallbackKeyEventObj = NULL;
822 }
Jeff Brown1f245102010-11-18 20:53:46 -0800823 android_view_KeyEvent_recycle(env, keyEventObj);
824 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800825
826 if (fallbackKeyEventObj) {
827 // Note: outFallbackKeyEvent may be the same object as keyEvent.
828 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
829 outFallbackKeyEvent)) {
830 result = true;
831 }
832 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
833 env->DeleteLocalRef(fallbackKeyEventObj);
834 }
Jeff Brown1f245102010-11-18 20:53:46 -0800835 } else {
836 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800837 }
Jeff Brown928e0542011-01-10 11:17:36 -0800838 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700839 }
Jeff Brown1f245102010-11-18 20:53:46 -0800840 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700841}
842
Jeff Brown01ce2e92010-09-26 22:20:12 -0700843void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
844 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700845}
846
Jeff Brown349703e2010-06-22 01:27:15 -0700847
Jeff Brownb88102f2010-09-08 11:49:43 -0700848bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
849 int32_t injectorPid, int32_t injectorUid) {
850 JNIEnv* env = jniEnv();
851 jboolean result = env->CallBooleanMethod(mCallbacksObj,
852 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brown524ee642011-03-29 15:11:34 -0700853 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
854 result = false;
855 }
Jeff Brown349703e2010-06-22 01:27:15 -0700856 return result;
857}
858
Jeff Brown83c09682010-12-23 17:50:18 -0800859
Jeff Brown9c3cda02010-06-15 01:31:58 -0700860// ----------------------------------------------------------------------------
861
862static sp<NativeInputManager> gNativeInputManager;
863
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700864static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700865 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700866 LOGE("Input manager not initialized.");
867 jniThrowRuntimeException(env, "Input manager not initialized.");
868 return true;
869 }
870 return false;
871}
872
873static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown05dc66a2011-03-02 14:41:58 -0800874 jobject callbacks, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700875 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800876 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
877 gNativeInputManager = new NativeInputManager(callbacks, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700878 } else {
879 LOGE("Input manager already initialized.");
880 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700881 }
882}
883
884static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
885 if (checkInputManagerUnitialized(env)) {
886 return;
887 }
888
Jeff Brown9c3cda02010-06-15 01:31:58 -0700889 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700890 if (result) {
891 jniThrowRuntimeException(env, "Input manager could not be started.");
892 }
893}
894
895static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
896 jint displayId, jint width, jint height) {
897 if (checkInputManagerUnitialized(env)) {
898 return;
899 }
900
901 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
902 // to be passed in like this, not sure which is better but leaving it like this
903 // keeps the window manager in direct control of when display transitions propagate down
904 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700905 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700906}
907
908static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
909 jint displayId, jint orientation) {
910 if (checkInputManagerUnitialized(env)) {
911 return;
912 }
913
Jeff Brown9c3cda02010-06-15 01:31:58 -0700914 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700915}
916
917static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700918 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700919 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700920 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700921 }
922
Jeff Brownb88102f2010-09-08 11:49:43 -0700923 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700924 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700925}
926
927static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700928 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700929 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700930 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700931 }
932
Jeff Brownb88102f2010-09-08 11:49:43 -0700933 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700934 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700935}
936
937static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700938 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700939 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700940 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700941 }
942
Jeff Brownb88102f2010-09-08 11:49:43 -0700943 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700944 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700945}
946
947static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700948 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700949 if (checkInputManagerUnitialized(env)) {
950 return JNI_FALSE;
951 }
952
953 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
954 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
955 jsize numCodes = env->GetArrayLength(keyCodes);
956 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700957 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700958 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700959 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700960 } else {
961 result = JNI_FALSE;
962 }
963
964 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
965 env->ReleaseIntArrayElements(keyCodes, codes, 0);
966 return result;
967}
968
969static void throwInputChannelNotInitialized(JNIEnv* env) {
970 jniThrowException(env, "java/lang/IllegalStateException",
971 "inputChannel is not initialized");
972}
973
974static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
975 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
976 LOGW("Input channel object '%s' was disposed without first being unregistered with "
977 "the input manager!", inputChannel->getName().string());
978
Jeff Brown9c3cda02010-06-15 01:31:58 -0700979 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700980 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700981 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700982}
983
984static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -0800985 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700986 if (checkInputManagerUnitialized(env)) {
987 return;
988 }
989
990 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
991 inputChannelObj);
992 if (inputChannel == NULL) {
993 throwInputChannelNotInitialized(env);
994 return;
995 }
996
Jeff Brown928e0542011-01-10 11:17:36 -0800997 sp<InputWindowHandle> inputWindowHandle =
998 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700999
1000 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001001 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001002 if (status) {
1003 jniThrowRuntimeException(env, "Failed to register input channel. "
1004 "Check logs for details.");
1005 return;
1006 }
1007
Jeff Browna41ca772010-08-11 14:46:32 -07001008 if (! monitor) {
1009 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1010 android_server_InputManager_handleInputChannelDisposed, NULL);
1011 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001012}
1013
1014static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1015 jobject inputChannelObj) {
1016 if (checkInputManagerUnitialized(env)) {
1017 return;
1018 }
1019
1020 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1021 inputChannelObj);
1022 if (inputChannel == NULL) {
1023 throwInputChannelNotInitialized(env);
1024 return;
1025 }
1026
1027 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1028
Jeff Brown7fbdc842010-06-17 20:52:56 -07001029 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001030 if (status) {
1031 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1032 "Check logs for details.");
1033 }
1034}
1035
Jeff Brown6ec402b2010-07-28 15:48:59 -07001036static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1037 jobject inputEventObj, jint injectorPid, jint injectorUid,
1038 jint syncMode, jint timeoutMillis) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001039 if (checkInputManagerUnitialized(env)) {
1040 return INPUT_EVENT_INJECTION_FAILED;
1041 }
1042
Jeff Brown6ec402b2010-07-28 15:48:59 -07001043 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1044 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001045 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1046 if (status) {
1047 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1048 return INPUT_EVENT_INJECTION_FAILED;
1049 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001050
Jeff Brownb88102f2010-09-08 11:49:43 -07001051 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
1052 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001053 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown5b2b4d92011-03-14 19:39:54 -07001054 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1055 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001056 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1057 return INPUT_EVENT_INJECTION_FAILED;
1058 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001059
Jeff Brownb88102f2010-09-08 11:49:43 -07001060 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown5b2b4d92011-03-14 19:39:54 -07001061 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis);
Jeff Brown6ec402b2010-07-28 15:48:59 -07001062 } else {
1063 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001064 return INPUT_EVENT_INJECTION_FAILED;
1065 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001066}
1067
Jeff Brown349703e2010-06-22 01:27:15 -07001068static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1069 jobjectArray windowObjArray) {
1070 if (checkInputManagerUnitialized(env)) {
1071 return;
1072 }
1073
1074 gNativeInputManager->setInputWindows(env, windowObjArray);
1075}
1076
1077static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1078 jobject applicationObj) {
1079 if (checkInputManagerUnitialized(env)) {
1080 return;
1081 }
1082
1083 gNativeInputManager->setFocusedApplication(env, applicationObj);
1084}
1085
1086static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1087 jclass clazz, jboolean enabled, jboolean frozen) {
1088 if (checkInputManagerUnitialized(env)) {
1089 return;
1090 }
1091
1092 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1093}
1094
Jeff Brown05dc66a2011-03-02 14:41:58 -08001095static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1096 jclass clazz, jint visibility) {
1097 if (checkInputManagerUnitialized(env)) {
1098 return;
1099 }
1100
1101 gNativeInputManager->setSystemUiVisibility(visibility);
1102}
1103
Jeff Brown8d608662010-08-30 03:02:23 -07001104static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1105 jclass clazz, jint deviceId) {
1106 if (checkInputManagerUnitialized(env)) {
1107 return NULL;
1108 }
1109
1110 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001111 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001112 deviceId, & deviceInfo);
1113 if (status) {
1114 return NULL;
1115 }
1116
1117 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1118 if (! deviceObj) {
1119 return NULL;
1120 }
1121
1122 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1123 if (! deviceNameObj) {
1124 return NULL;
1125 }
1126
1127 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1128 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1129 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1130 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1131
Jeff Brownefd32662011-03-08 15:13:06 -08001132 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001133 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001134 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001135 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001136 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001137 if (env->ExceptionCheck()) {
1138 return NULL;
1139 }
1140 }
1141
1142 return deviceObj;
1143}
1144
1145static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1146 jclass clazz) {
1147 if (checkInputManagerUnitialized(env)) {
1148 return NULL;
1149 }
1150
1151 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001152 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001153
1154 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1155 if (! deviceIdsObj) {
1156 return NULL;
1157 }
1158
1159 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1160 return deviceIdsObj;
1161}
1162
Jeff Brown57c59372010-09-21 18:22:55 -07001163static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1164 jclass clazz, jobject configObj) {
1165 if (checkInputManagerUnitialized(env)) {
1166 return;
1167 }
1168
1169 InputConfiguration config;
1170 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1171
1172 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1173 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1174 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1175}
1176
Jeff Browne6504122010-09-27 14:52:15 -07001177static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1178 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1179 if (checkInputManagerUnitialized(env)) {
1180 return false;
1181 }
1182
1183 sp<InputChannel> fromChannel =
1184 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1185 sp<InputChannel> toChannel =
1186 android_view_InputChannel_getInputChannel(env, toChannelObj);
1187
1188 if (fromChannel == NULL || toChannel == NULL) {
1189 return false;
1190 }
1191
1192 return gNativeInputManager->getInputManager()->getDispatcher()->
1193 transferTouchFocus(fromChannel, toChannel);
1194}
1195
Jeff Browne33348b2010-07-15 23:54:05 -07001196static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1197 if (checkInputManagerUnitialized(env)) {
1198 return NULL;
1199 }
1200
Jeff Brownb88102f2010-09-08 11:49:43 -07001201 String8 dump;
1202 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001203 return env->NewStringUTF(dump.string());
1204}
1205
Jeff Brown9c3cda02010-06-15 01:31:58 -07001206// ----------------------------------------------------------------------------
1207
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001208static JNINativeMethod gInputManagerMethods[] = {
1209 /* name, signature, funcPtr */
Jeff Brown05dc66a2011-03-02 14:41:58 -08001210 { "nativeInit", "(Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001211 (void*) android_server_InputManager_nativeInit },
1212 { "nativeStart", "()V",
1213 (void*) android_server_InputManager_nativeStart },
1214 { "nativeSetDisplaySize", "(III)V",
1215 (void*) android_server_InputManager_nativeSetDisplaySize },
1216 { "nativeSetDisplayOrientation", "(II)V",
1217 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1218 { "nativeGetScanCodeState", "(III)I",
1219 (void*) android_server_InputManager_nativeGetScanCodeState },
1220 { "nativeGetKeyCodeState", "(III)I",
1221 (void*) android_server_InputManager_nativeGetKeyCodeState },
1222 { "nativeGetSwitchState", "(III)I",
1223 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001224 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001225 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001226 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001227 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001228 (void*) android_server_InputManager_nativeRegisterInputChannel },
1229 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001230 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown6ec402b2010-07-28 15:48:59 -07001231 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIII)I",
1232 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001233 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001234 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001235 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001236 (void*) android_server_InputManager_nativeSetFocusedApplication },
1237 { "nativeSetInputDispatchMode", "(ZZ)V",
1238 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001239 { "nativeSetSystemUiVisibility", "(I)V",
1240 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001241 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1242 (void*) android_server_InputManager_nativeGetInputDevice },
1243 { "nativeGetInputDeviceIds", "()[I",
1244 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001245 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1246 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001247 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1248 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Browne33348b2010-07-15 23:54:05 -07001249 { "nativeDump", "()Ljava/lang/String;",
1250 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001251};
1252
1253#define FIND_CLASS(var, className) \
1254 var = env->FindClass(className); \
1255 LOG_FATAL_IF(! var, "Unable to find class " className); \
1256 var = jclass(env->NewGlobalRef(var));
1257
1258#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1259 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1260 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1261
1262#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1263 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1264 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1265
1266int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001267 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001268 gInputManagerMethods, NELEM(gInputManagerMethods));
1269 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1270
Jeff Brown9c3cda02010-06-15 01:31:58 -07001271 // Callbacks
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001272
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001273 FIND_CLASS(gCallbacksClassInfo.clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001274
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001275 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, gCallbacksClassInfo.clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001276 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001277
1278 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, gCallbacksClassInfo.clazz,
1279 "notifyLidSwitchChanged", "(JZ)V");
1280
Jeff Brown7fbdc842010-06-17 20:52:56 -07001281 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, gCallbacksClassInfo.clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001282 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001283
Jeff Brown349703e2010-06-22 01:27:15 -07001284 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, gCallbacksClassInfo.clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001285 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001286 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001287
Jeff Brown349703e2010-06-22 01:27:15 -07001288 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001289 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001290
Jeff Brown56194eb2011-03-02 19:23:13 -08001291 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
1292 gCallbacksClassInfo.clazz,
1293 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1294
Jeff Brown349703e2010-06-22 01:27:15 -07001295 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, gCallbacksClassInfo.clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001296 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001297 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001298
Jeff Brown3915bb82010-11-05 15:02:16 -07001299 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, gCallbacksClassInfo.clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001300 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001301 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001302
Jeff Brown349703e2010-06-22 01:27:15 -07001303 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, gCallbacksClassInfo.clazz,
1304 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001305
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001306 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, gCallbacksClassInfo.clazz,
1307 "filterTouchEvents", "()Z");
1308
1309 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
1310 "filterJumpyTouchEvents", "()Z");
1311
Jeff Brownfe508922011-01-18 15:10:10 -08001312 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
1313 "getVirtualKeyQuietTimeMillis", "()I");
1314
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001315 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
1316 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1317
Jeff Browna4547672011-03-02 21:38:11 -08001318 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, gCallbacksClassInfo.clazz,
1319 "getKeyRepeatTimeout", "()I");
1320
1321 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, gCallbacksClassInfo.clazz,
1322 "getKeyRepeatDelay", "()I");
1323
Jeff Brownae9fc032010-08-18 15:51:08 -07001324 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, gCallbacksClassInfo.clazz,
1325 "getMaxEventsPerSecond", "()I");
1326
Jeff Brown83c09682010-12-23 17:50:18 -08001327 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, gCallbacksClassInfo.clazz,
1328 "getPointerLayer", "()I");
1329
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001330 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, gCallbacksClassInfo.clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001331 "getPointerIcon", "()Lcom/android/server/wm/InputManager$PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001332
Jeff Brown6ec402b2010-07-28 15:48:59 -07001333 // KeyEvent
1334
1335 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
1336
Jeff Brown8d608662010-08-30 03:02:23 -07001337 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001338
1339 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
1340
Jeff Brown8d608662010-08-30 03:02:23 -07001341 // InputDevice
1342
1343 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
1344
1345 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1346 "<init>", "()V");
1347
1348 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001349 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001350
1351 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1352 "mId", "I");
1353
1354 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1355 "mName", "Ljava/lang/String;");
1356
1357 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1358 "mSources", "I");
1359
1360 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1361 "mKeyboardType", "I");
1362
Jeff Brown57c59372010-09-21 18:22:55 -07001363 // Configuration
1364
1365 FIND_CLASS(gConfigurationClassInfo.clazz, "android/content/res/Configuration");
1366
1367 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, gConfigurationClassInfo.clazz,
1368 "touchscreen", "I");
1369
1370 GET_FIELD_ID(gConfigurationClassInfo.keyboard, gConfigurationClassInfo.clazz,
1371 "keyboard", "I");
1372
1373 GET_FIELD_ID(gConfigurationClassInfo.navigation, gConfigurationClassInfo.clazz,
1374 "navigation", "I");
1375
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001376 // PointerIcon
1377
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001378 FIND_CLASS(gPointerIconClassInfo.clazz, "com/android/server/wm/InputManager$PointerIcon");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001379
1380 GET_FIELD_ID(gPointerIconClassInfo.bitmap, gPointerIconClassInfo.clazz,
1381 "bitmap", "Landroid/graphics/Bitmap;");
1382
1383 GET_FIELD_ID(gPointerIconClassInfo.hotSpotX, gPointerIconClassInfo.clazz,
1384 "hotSpotX", "F");
1385
1386 GET_FIELD_ID(gPointerIconClassInfo.hotSpotY, gPointerIconClassInfo.clazz,
1387 "hotSpotY", "F");
1388
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001389 return 0;
1390}
1391
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001392} /* namespace android */