blob: 8a46ab0fee055a4319b04c816dc0ab93f8aa13f7 [file] [log] [blame]
Jeff Brown46b9ac02010-04-22 18:58:52 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputManager-JNI"
18
Jeff Brown9c3cda02010-06-15 01:31:58 -070019//#define LOG_NDEBUG 0
20
21// Log debug messages about InputReaderPolicy
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INPUT_READER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070023
24// Log debug messages about InputDispatcherPolicy
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_INPUT_DISPATCHER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070026
Jeff Brown83c09682010-12-23 17:50:18 -080027
Jeff Brown46b9ac02010-04-22 18:58:52 -070028#include "JNIHelp.h"
29#include "jni.h"
Jeff Brown349703e2010-06-22 01:27:15 -070030#include <limits.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070031#include <android_runtime/AndroidRuntime.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080032
Jeff Brown46b9ac02010-04-22 18:58:52 -070033#include <utils/Log.h>
Jeff Brown05dc66a2011-03-02 14:41:58 -080034#include <utils/Looper.h>
Jeff Brown46b9ac02010-04-22 18:58:52 -070035#include <utils/threads.h>
Jeff Brown83c09682010-12-23 17:50:18 -080036
Jeff Brownb4ff35d2011-01-02 16:37:43 -080037#include <input/InputManager.h>
38#include <input/PointerController.h>
Jeff Brown5541de92011-04-11 11:54:25 -070039#include <input/SpriteController.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080040
Jeff Brown05dc66a2011-03-02 14:41:58 -080041#include <android_os_MessageQueue.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080042#include <android_view_KeyEvent.h>
43#include <android_view_MotionEvent.h>
44#include <android_view_InputChannel.h>
Jeff Brown2352b972011-04-12 22:39:53 -070045#include <android_view_PointerIcon.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080046#include <android/graphics/GraphicsJNI.h>
47
Jeff Brown00fa7bd2010-07-02 15:37:36 -070048#include "com_android_server_PowerManagerService.h"
Jeff Brown928e0542011-01-10 11:17:36 -080049#include "com_android_server_InputApplication.h"
50#include "com_android_server_InputApplicationHandle.h"
51#include "com_android_server_InputWindow.h"
52#include "com_android_server_InputWindowHandle.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070053
54namespace android {
55
Jeff Brown1a84fd12011-06-02 01:26:32 -070056// The exponent used to calculate the pointer speed scaling factor.
57// The scaling factor is calculated as 2 ^ (speed * exponent),
58// where the speed ranges from -7 to + 7 and is supplied by the user.
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -070059static const float POINTER_SPEED_EXPONENT = 1.0f / 4;
Jeff Brown1a84fd12011-06-02 01:26:32 -070060
Jeff Brown46b9ac02010-04-22 18:58:52 -070061static struct {
Jeff Brown46b9ac02010-04-22 18:58:52 -070062 jmethodID notifyConfigurationChanged;
63 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070064 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070065 jmethodID notifyANR;
Jeff Brown0029c662011-03-30 02:25:18 -070066 jmethodID filterInputEvent;
Jeff Brown349703e2010-06-22 01:27:15 -070067 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080068 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070069 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070070 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070071 jmethodID checkInjectEventsPermission;
Jeff Brown46b9ac02010-04-22 18:58:52 -070072 jmethodID filterTouchEvents;
73 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080074 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac02010-04-22 18:58:52 -070075 jmethodID getExcludedDeviceNames;
Jeff Browna4547672011-03-02 21:38:11 -080076 jmethodID getKeyRepeatTimeout;
77 jmethodID getKeyRepeatDelay;
Jeff Brownae9fc032010-08-18 15:51:08 -070078 jmethodID getMaxEventsPerSecond;
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -070079 jmethodID getHoverTapTimeout;
80 jmethodID getHoverTapSlop;
Jeff Brown214eaf42011-05-26 19:17:02 -070081 jmethodID getDoubleTapTimeout;
82 jmethodID getLongPressTimeout;
Jeff Brown83c09682010-12-23 17:50:18 -080083 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080084 jmethodID getPointerIcon;
Jeff Brown46b9ac02010-04-22 18:58:52 -070085} gCallbacksClassInfo;
86
87static struct {
88 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070089} gKeyEventClassInfo;
90
91static struct {
92 jclass clazz;
93} gMotionEventClassInfo;
94
Jeff Brown8d608662010-08-30 03:02:23 -070095static struct {
96 jclass clazz;
97
98 jmethodID ctor;
99 jmethodID addMotionRange;
100
101 jfieldID mId;
102 jfieldID mName;
103 jfieldID mSources;
104 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -0700105} gInputDeviceClassInfo;
106
Jeff Brown57c59372010-09-21 18:22:55 -0700107static struct {
Jeff Brown57c59372010-09-21 18:22:55 -0700108 jfieldID touchscreen;
109 jfieldID keyboard;
110 jfieldID navigation;
111} gConfigurationClassInfo;
112
Jeff Brown928e0542011-01-10 11:17:36 -0800113
114// --- Global functions ---
115
Jeff Brown214eaf42011-05-26 19:17:02 -0700116template<typename T>
117inline static T min(const T& a, const T& b) {
118 return a < b ? a : b;
119}
120
121template<typename T>
122inline static T max(const T& a, const T& b) {
123 return a > b ? a : b;
124}
125
Jeff Brown928e0542011-01-10 11:17:36 -0800126static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
127 const sp<InputApplicationHandle>& inputApplicationHandle) {
128 if (inputApplicationHandle == NULL) {
129 return NULL;
130 }
131 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
132 getInputApplicationHandleObjLocalRef(env);
133}
134
135static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
136 const sp<InputWindowHandle>& inputWindowHandle) {
137 if (inputWindowHandle == NULL) {
138 return NULL;
139 }
140 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
141 getInputWindowHandleObjLocalRef(env);
142}
143
Jeff Brown2352b972011-04-12 22:39:53 -0700144static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
145 SpriteIcon* outSpriteIcon) {
146 PointerIcon pointerIcon;
147 status_t status = android_view_PointerIcon_loadSystemIcon(env,
148 contextObj, style, &pointerIcon);
149 if (!status) {
150 pointerIcon.bitmap.copyTo(&outSpriteIcon->bitmap, SkBitmap::kARGB_8888_Config);
151 outSpriteIcon->hotSpotX = pointerIcon.hotSpotX;
152 outSpriteIcon->hotSpotY = pointerIcon.hotSpotY;
153 }
154}
155
Jeff Brown928e0542011-01-10 11:17:36 -0800156
157// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800158
Jeff Brown9c3cda02010-06-15 01:31:58 -0700159class NativeInputManager : public virtual RefBase,
160 public virtual InputReaderPolicyInterface,
Jeff Brown2352b972011-04-12 22:39:53 -0700161 public virtual InputDispatcherPolicyInterface,
162 public virtual PointerControllerPolicyInterface {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700163protected:
164 virtual ~NativeInputManager();
165
166public:
Jeff Brown2352b972011-04-12 22:39:53 -0700167 NativeInputManager(jobject contextObj, jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700168
169 inline sp<InputManager> getInputManager() const { return mInputManager; }
170
Jeff Brownb88102f2010-09-08 11:49:43 -0700171 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700172
Jeff Brown9c3cda02010-06-15 01:31:58 -0700173 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
174 void setDisplayOrientation(int32_t displayId, int32_t orientation);
175
Jeff Brown7fbdc842010-06-17 20:52:56 -0700176 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800177 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700178 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
179
Jeff Brown349703e2010-06-22 01:27:15 -0700180 void setInputWindows(JNIEnv* env, jobjectArray windowObjArray);
181 void setFocusedApplication(JNIEnv* env, jobject applicationObj);
182 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800183 void setSystemUiVisibility(int32_t visibility);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700184 void setPointerSpeed(int32_t speed);
Jeff Brown349703e2010-06-22 01:27:15 -0700185
Jeff Brown9c3cda02010-06-15 01:31:58 -0700186 /* --- InputReaderPolicyInterface implementation --- */
187
188 virtual bool getDisplayInfo(int32_t displayId,
189 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown214eaf42011-05-26 19:17:02 -0700190 virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);
Jeff Brown83c09682010-12-23 17:50:18 -0800191 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700192
193 /* --- InputDispatcherPolicyInterface implementation --- */
194
Jeff Browne20c9e02010-10-11 14:20:19 -0700195 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
196 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700197 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700198 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800199 const sp<InputWindowHandle>& inputWindowHandle);
200 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown0029c662011-03-30 02:25:18 -0700201 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
Jeff Brown214eaf42011-05-26 19:17:02 -0700202 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
203 virtual bool isKeyRepeatEnabled();
Jeff Brown1f245102010-11-18 20:53:46 -0800204 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800205 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800206 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700207 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800208 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800209 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700210 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700211 virtual bool checkInjectEventsPermissionNonReentrant(
212 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700213
Jeff Brown2352b972011-04-12 22:39:53 -0700214 /* --- PointerControllerPolicyInterface implementation --- */
215
216 virtual void loadPointerResources(PointerResources* outResources);
217
Jeff Brown9c3cda02010-06-15 01:31:58 -0700218private:
219 sp<InputManager> mInputManager;
220
Jeff Brown2352b972011-04-12 22:39:53 -0700221 jobject mContextObj;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700222 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800223 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700224
Jeff Brown83c09682010-12-23 17:50:18 -0800225 Mutex mLock;
226 struct Locked {
227 // Display size information.
228 int32_t displayWidth, displayHeight; // -1 when initialized
229 int32_t displayOrientation;
230
Jeff Brown05dc66a2011-03-02 14:41:58 -0800231 // System UI visibility.
232 int32_t systemUiVisibility;
233
Jeff Brown1a84fd12011-06-02 01:26:32 -0700234 // Pointer speed.
235 int32_t pointerSpeed;
236
Jeff Brown474dcb52011-06-14 20:22:50 -0700237 // True if pointer gestures are enabled.
238 bool pointerGesturesEnabled;
239
Jeff Brown5541de92011-04-11 11:54:25 -0700240 // Sprite controller singleton, created on first use.
241 sp<SpriteController> spriteController;
242
Jeff Brown83c09682010-12-23 17:50:18 -0800243 // Pointer controller singleton, created and destroyed as needed.
244 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800245 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700246
Jeff Brown2352b972011-04-12 22:39:53 -0700247 void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800248 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown5541de92011-04-11 11:54:25 -0700249 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800250
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700251 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700252 bool isScreenOn();
253 bool isScreenBright();
254
Jeff Brownb88102f2010-09-08 11:49:43 -0700255 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700256
Jeff Brown9c3cda02010-06-15 01:31:58 -0700257 static inline JNIEnv* jniEnv() {
258 return AndroidRuntime::getJNIEnv();
259 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700260};
261
Jeff Brown928e0542011-01-10 11:17:36 -0800262
Jeff Brown9c3cda02010-06-15 01:31:58 -0700263
Jeff Brown2352b972011-04-12 22:39:53 -0700264NativeInputManager::NativeInputManager(jobject contextObj,
265 jobject callbacksObj, const sp<Looper>& looper) :
Jeff Brown214eaf42011-05-26 19:17:02 -0700266 mLooper(looper) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700267 JNIEnv* env = jniEnv();
268
Jeff Brown2352b972011-04-12 22:39:53 -0700269 mContextObj = env->NewGlobalRef(contextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700270 mCallbacksObj = env->NewGlobalRef(callbacksObj);
271
Jeff Brown83c09682010-12-23 17:50:18 -0800272 {
273 AutoMutex _l(mLock);
274 mLocked.displayWidth = -1;
275 mLocked.displayHeight = -1;
276 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800277
278 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700279 mLocked.pointerSpeed = 0;
Jeff Brown474dcb52011-06-14 20:22:50 -0700280 mLocked.pointerGesturesEnabled = true;
Jeff Brown83c09682010-12-23 17:50:18 -0800281 }
282
Jeff Brown9c3cda02010-06-15 01:31:58 -0700283 sp<EventHub> eventHub = new EventHub();
284 mInputManager = new InputManager(eventHub, this, this);
285}
286
287NativeInputManager::~NativeInputManager() {
288 JNIEnv* env = jniEnv();
289
Jeff Brown2352b972011-04-12 22:39:53 -0700290 env->DeleteGlobalRef(mContextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700291 env->DeleteGlobalRef(mCallbacksObj);
292}
293
Jeff Brownb88102f2010-09-08 11:49:43 -0700294void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700295 mInputManager->getReader()->dump(dump);
296 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700297
Jeff Brownb88102f2010-09-08 11:49:43 -0700298 mInputManager->getDispatcher()->dump(dump);
299 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700300}
301
Jeff Brown7fbdc842010-06-17 20:52:56 -0700302bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700303 if (env->ExceptionCheck()) {
304 LOGE("An exception was thrown by callback '%s'.", methodName);
305 LOGE_EX(env);
306 env->ExceptionClear();
307 return true;
308 }
309 return false;
310}
311
312void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
313 if (displayId == 0) {
Jeff Brown2352b972011-04-12 22:39:53 -0700314 { // acquire lock
315 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700316
Jeff Brown2352b972011-04-12 22:39:53 -0700317 if (mLocked.displayWidth == width && mLocked.displayHeight == height) {
318 return;
319 }
320
Jeff Brown83c09682010-12-23 17:50:18 -0800321 mLocked.displayWidth = width;
322 mLocked.displayHeight = height;
323
324 sp<PointerController> controller = mLocked.pointerController.promote();
325 if (controller != NULL) {
326 controller->setDisplaySize(width, height);
327 }
Jeff Brown2352b972011-04-12 22:39:53 -0700328 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700329 }
330}
331
332void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
333 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800334 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700335
Jeff Brown83c09682010-12-23 17:50:18 -0800336 if (mLocked.displayOrientation != orientation) {
337 mLocked.displayOrientation = orientation;
338
339 sp<PointerController> controller = mLocked.pointerController.promote();
340 if (controller != NULL) {
341 controller->setDisplayOrientation(orientation);
342 }
343 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700344 }
345}
346
Jeff Brown7fbdc842010-06-17 20:52:56 -0700347status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800348 const sp<InputChannel>& inputChannel,
349 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
350 return mInputManager->getDispatcher()->registerInputChannel(
351 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700352}
353
354status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
355 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700356 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700357}
358
Jeff Brown9c3cda02010-06-15 01:31:58 -0700359bool NativeInputManager::getDisplayInfo(int32_t displayId,
360 int32_t* width, int32_t* height, int32_t* orientation) {
361 bool result = false;
362 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800363 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700364
Jeff Brown83c09682010-12-23 17:50:18 -0800365 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700366 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800367 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700368 }
369 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800370 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700371 }
372 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800373 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700374 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700375 result = true;
376 }
377 }
378 return result;
379}
380
Jeff Brown214eaf42011-05-26 19:17:02 -0700381void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700382 JNIEnv* env = jniEnv();
383
Jeff Brown214eaf42011-05-26 19:17:02 -0700384 jboolean filterTouchEvents = env->CallBooleanMethod(mCallbacksObj,
385 gCallbacksClassInfo.filterTouchEvents);
386 if (!checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
387 outConfig->filterTouchEvents = filterTouchEvents;
388 }
389
390 jboolean filterJumpyTouchEvents = env->CallBooleanMethod(mCallbacksObj,
391 gCallbacksClassInfo.filterJumpyTouchEvents);
392 if (!checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
393 outConfig->filterJumpyTouchEvents = filterJumpyTouchEvents;
394 }
395
396 jint virtualKeyQuietTime = env->CallIntMethod(mCallbacksObj,
397 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
398 if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
399 outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
400 }
401
402 outConfig->excludedDeviceNames.clear();
403 jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mCallbacksObj,
Jeff Brown9c3cda02010-06-15 01:31:58 -0700404 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown214eaf42011-05-26 19:17:02 -0700405 if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
406 jsize length = env->GetArrayLength(excludedDeviceNames);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700407 for (jsize i = 0; i < length; i++) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700408 jstring item = jstring(env->GetObjectArrayElement(excludedDeviceNames, i));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700409 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
Jeff Brown214eaf42011-05-26 19:17:02 -0700410 outConfig->excludedDeviceNames.add(String8(deviceNameChars));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700411 env->ReleaseStringUTFChars(item, deviceNameChars);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700412 env->DeleteLocalRef(item);
413 }
Jeff Brown214eaf42011-05-26 19:17:02 -0700414 env->DeleteLocalRef(excludedDeviceNames);
415 }
416
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700417 jint hoverTapTimeout = env->CallIntMethod(mCallbacksObj,
418 gCallbacksClassInfo.getHoverTapTimeout);
419 if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700420 jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
421 gCallbacksClassInfo.getDoubleTapTimeout);
422 if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
423 jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
424 gCallbacksClassInfo.getLongPressTimeout);
425 if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700426 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700427
428 // We must ensure that the tap-drag interval is significantly shorter than
429 // the long-press timeout because the tap is held down for the entire duration
430 // of the double-tap timeout.
431 jint tapDragInterval = max(min(longPressTimeout - 100,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700432 doubleTapTimeout), hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700433 outConfig->pointerGestureTapDragInterval =
434 milliseconds_to_nanoseconds(tapDragInterval);
435 }
436 }
437 }
438
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700439 jint hoverTapSlop = env->CallIntMethod(mCallbacksObj,
440 gCallbacksClassInfo.getHoverTapSlop);
441 if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
442 outConfig->pointerGestureTapSlop = hoverTapSlop;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700443 }
Jeff Brown1a84fd12011-06-02 01:26:32 -0700444
445 { // acquire lock
446 AutoMutex _l(mLock);
447
448 outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
449 * POINTER_SPEED_EXPONENT);
Jeff Brown474dcb52011-06-14 20:22:50 -0700450 outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700451 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700452}
453
Jeff Brown83c09682010-12-23 17:50:18 -0800454sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
455 AutoMutex _l(mLock);
456
457 sp<PointerController> controller = mLocked.pointerController.promote();
458 if (controller == NULL) {
Jeff Brown5541de92011-04-11 11:54:25 -0700459 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800460
Jeff Brown2352b972011-04-12 22:39:53 -0700461 controller = new PointerController(this, mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800462 mLocked.pointerController = controller;
463
464 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
465 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800466
Jeff Brown5541de92011-04-11 11:54:25 -0700467 JNIEnv* env = jniEnv();
Jeff Brown2352b972011-04-12 22:39:53 -0700468 jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
469 gCallbacksClassInfo.getPointerIcon);
470 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
471 PointerIcon pointerIcon;
472 status_t status = android_view_PointerIcon_load(env, pointerIconObj,
473 mContextObj, &pointerIcon);
474 if (!status && !pointerIcon.isNullIcon()) {
475 controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
476 pointerIcon.hotSpotX, pointerIcon.hotSpotY));
477 } else {
478 controller->setPointerIcon(SpriteIcon());
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800479 }
Jeff Brown2352b972011-04-12 22:39:53 -0700480 env->DeleteLocalRef(pointerIconObj);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800481 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800482
Jeff Brown2352b972011-04-12 22:39:53 -0700483 updateInactivityTimeoutLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800484 }
485 return controller;
486}
487
Jeff Brown5541de92011-04-11 11:54:25 -0700488void NativeInputManager::ensureSpriteControllerLocked() {
489 if (mLocked.spriteController == NULL) {
490 JNIEnv* env = jniEnv();
491 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
492 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
493 layer = -1;
494 }
495 mLocked.spriteController = new SpriteController(mLooper, layer);
496 }
497}
498
Jeff Browne20c9e02010-10-11 14:20:19 -0700499void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
500 int32_t switchValue, uint32_t policyFlags) {
501#if DEBUG_INPUT_DISPATCHER_POLICY
502 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
503 when, switchCode, switchValue, policyFlags);
504#endif
505
506 JNIEnv* env = jniEnv();
507
508 switch (switchCode) {
509 case SW_LID:
510 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
511 when, switchValue == 0);
512 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
513 break;
514 }
515}
516
Jeff Brown9c3cda02010-06-15 01:31:58 -0700517void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
518#if DEBUG_INPUT_DISPATCHER_POLICY
519 LOGD("notifyConfigurationChanged - when=%lld", when);
520#endif
521
522 JNIEnv* env = jniEnv();
523
Jeff Brown57c59372010-09-21 18:22:55 -0700524 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700525 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700526}
527
Jeff Brown519e0242010-09-15 15:18:56 -0700528nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800529 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700530#if DEBUG_INPUT_DISPATCHER_POLICY
531 LOGD("notifyANR");
532#endif
533
534 JNIEnv* env = jniEnv();
535
Jeff Brown928e0542011-01-10 11:17:36 -0800536 jobject inputApplicationHandleObj =
537 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
538 jobject inputWindowHandleObj =
539 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700540
Jeff Brown519e0242010-09-15 15:18:56 -0700541 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800542 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700543 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
544 newTimeout = 0; // abort dispatch
545 } else {
546 assert(newTimeout >= 0);
547 }
548
Jeff Brown928e0542011-01-10 11:17:36 -0800549 env->DeleteLocalRef(inputWindowHandleObj);
550 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700551 return newTimeout;
552}
553
Jeff Brown928e0542011-01-10 11:17:36 -0800554void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700555#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800556 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700557#endif
558
Jeff Brown7fbdc842010-06-17 20:52:56 -0700559 JNIEnv* env = jniEnv();
560
Jeff Brown928e0542011-01-10 11:17:36 -0800561 jobject inputWindowHandleObj =
562 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
563 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700564 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800565 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700566 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
567
Jeff Brown928e0542011-01-10 11:17:36 -0800568 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700569 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700570}
571
Jeff Brown214eaf42011-05-26 19:17:02 -0700572void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
573 JNIEnv* env = jniEnv();
Jeff Browna4547672011-03-02 21:38:11 -0800574
Jeff Brown214eaf42011-05-26 19:17:02 -0700575 jint keyRepeatTimeout = env->CallIntMethod(mCallbacksObj,
576 gCallbacksClassInfo.getKeyRepeatTimeout);
577 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
578 outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
579 }
Jeff Browna4547672011-03-02 21:38:11 -0800580
Jeff Brown214eaf42011-05-26 19:17:02 -0700581 jint keyRepeatDelay = env->CallIntMethod(mCallbacksObj,
582 gCallbacksClassInfo.getKeyRepeatDelay);
583 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
584 outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
585 }
586
587 jint maxEventsPerSecond = env->CallIntMethod(mCallbacksObj,
588 gCallbacksClassInfo.getMaxEventsPerSecond);
589 if (!checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
590 outConfig->maxEventsPerSecond = maxEventsPerSecond;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700591 }
592}
593
Jeff Brown214eaf42011-05-26 19:17:02 -0700594bool NativeInputManager::isKeyRepeatEnabled() {
595 // Only enable automatic key repeating when the screen is on.
596 return isScreenOn();
Jeff Brownae9fc032010-08-18 15:51:08 -0700597}
598
Jeff Brown349703e2010-06-22 01:27:15 -0700599void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700600 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700601
Jeff Brown474dcb52011-06-14 20:22:50 -0700602 bool newPointerGesturesEnabled = true;
Jeff Brownb88102f2010-09-08 11:49:43 -0700603 jsize length = env->GetArrayLength(windowObjArray);
604 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800605 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
606 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700607 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700608 }
609
Jeff Brownb88102f2010-09-08 11:49:43 -0700610 windows.push();
611 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800612 android_server_InputWindow_toNative(env, windowObj, &window);
613 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700614 windows.pop();
Jeff Brown474dcb52011-06-14 20:22:50 -0700615 } else if (window.hasFocus) {
616 if (window.inputFeatures & InputWindow::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES) {
617 newPointerGesturesEnabled = false;
618 }
Jeff Brown349703e2010-06-22 01:27:15 -0700619 }
Jeff Brown928e0542011-01-10 11:17:36 -0800620 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700621 }
Jeff Brown349703e2010-06-22 01:27:15 -0700622
Jeff Brownb88102f2010-09-08 11:49:43 -0700623 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown474dcb52011-06-14 20:22:50 -0700624
625 uint32_t changes = 0;
626 { // acquire lock
627 AutoMutex _l(mLock);
628
629 if (mLocked.pointerGesturesEnabled != newPointerGesturesEnabled) {
630 mLocked.pointerGesturesEnabled = newPointerGesturesEnabled;
631 changes |= InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT;
632 }
633 } // release lock
634
635 if (changes) {
636 mInputManager->getReader()->requestRefreshConfiguration(changes);
637 }
Jeff Brown349703e2010-06-22 01:27:15 -0700638}
639
Jeff Brown349703e2010-06-22 01:27:15 -0700640void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700641 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700642 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800643 android_server_InputApplication_toNative(env, applicationObj, &application);
644 if (application.inputApplicationHandle != NULL) {
645 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Browna2cc28d2011-03-25 11:58:46 -0700646 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800647 }
Jeff Brown349703e2010-06-22 01:27:15 -0700648 }
Jeff Brown928e0542011-01-10 11:17:36 -0800649 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700650}
651
652void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700653 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700654}
655
Jeff Brown05dc66a2011-03-02 14:41:58 -0800656void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
657 AutoMutex _l(mLock);
658
659 if (mLocked.systemUiVisibility != visibility) {
660 mLocked.systemUiVisibility = visibility;
661
662 sp<PointerController> controller = mLocked.pointerController.promote();
663 if (controller != NULL) {
Jeff Brown2352b972011-04-12 22:39:53 -0700664 updateInactivityTimeoutLocked(controller);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800665 }
666 }
667}
668
Jeff Brown2352b972011-04-12 22:39:53 -0700669void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800670 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
Jeff Brown2352b972011-04-12 22:39:53 -0700671 controller->setInactivityTimeout(lightsOut
672 ? PointerController::INACTIVITY_TIMEOUT_SHORT
673 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800674}
675
Jeff Brown1a84fd12011-06-02 01:26:32 -0700676void NativeInputManager::setPointerSpeed(int32_t speed) {
Jeff Brown474dcb52011-06-14 20:22:50 -0700677 { // acquire lock
678 AutoMutex _l(mLock);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700679
Jeff Brown474dcb52011-06-14 20:22:50 -0700680 if (mLocked.pointerSpeed == speed) {
681 return;
682 }
683
Jeff Brown1a84fd12011-06-02 01:26:32 -0700684 LOGI("Setting pointer speed to %d.", speed);
685 mLocked.pointerSpeed = speed;
Jeff Brown474dcb52011-06-14 20:22:50 -0700686 } // release lock
Jeff Brown1a84fd12011-06-02 01:26:32 -0700687
Jeff Brown474dcb52011-06-14 20:22:50 -0700688 mInputManager->getReader()->requestRefreshConfiguration(
689 InputReaderConfiguration::CHANGE_POINTER_SPEED);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700690}
691
Jeff Browne20c9e02010-10-11 14:20:19 -0700692bool NativeInputManager::isScreenOn() {
693 return android_server_PowerManagerService_isScreenOn();
694}
695
696bool NativeInputManager::isScreenBright() {
697 return android_server_PowerManagerService_isScreenBright();
698}
699
Jeff Brown0029c662011-03-30 02:25:18 -0700700bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
701 jobject inputEventObj;
702
703 JNIEnv* env = jniEnv();
704 switch (inputEvent->getType()) {
705 case AINPUT_EVENT_TYPE_KEY:
706 inputEventObj = android_view_KeyEvent_fromNative(env,
707 static_cast<const KeyEvent*>(inputEvent));
708 break;
709 case AINPUT_EVENT_TYPE_MOTION:
710 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
711 static_cast<const MotionEvent*>(inputEvent));
712 break;
713 default:
714 return true; // dispatch the event normally
715 }
716
717 if (!inputEventObj) {
718 LOGE("Failed to obtain input event object for filterInputEvent.");
719 return true; // dispatch the event normally
720 }
721
722 // The callee is responsible for recycling the event.
723 jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
724 inputEventObj, policyFlags);
725 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
726 pass = true;
727 }
728 env->DeleteLocalRef(inputEventObj);
729 return pass;
730}
731
Jeff Brown1f245102010-11-18 20:53:46 -0800732void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
733 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700734 // Policy:
735 // - Ignore untrusted events and pass them along.
736 // - Ask the window manager what to do with normal events and trusted injected events.
737 // - For normal events wake and brighten the screen if currently off or dim.
738 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800739 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700740 bool isScreenOn = this->isScreenOn();
741 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700742
Jeff Brown3122e442010-10-11 23:32:49 -0700743 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800744 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
745 jint wmActions;
746 if (keyEventObj) {
747 wmActions = env->CallIntMethod(mCallbacksObj,
748 gCallbacksClassInfo.interceptKeyBeforeQueueing,
749 keyEventObj, policyFlags, isScreenOn);
750 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
751 wmActions = 0;
752 }
753 android_view_KeyEvent_recycle(env, keyEventObj);
754 env->DeleteLocalRef(keyEventObj);
755 } else {
756 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700757 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700758 }
759
Jeff Brown1f245102010-11-18 20:53:46 -0800760 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700761 if (!isScreenOn) {
762 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700763 }
764
765 if (!isScreenBright) {
766 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
767 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700768 }
769
Jeff Brown56194eb2011-03-02 19:23:13 -0800770 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700771 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700772 policyFlags |= POLICY_FLAG_PASS_TO_USER;
773 }
774}
775
Jeff Brown56194eb2011-03-02 19:23:13 -0800776void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700777 // Policy:
778 // - Ignore untrusted events and pass them along.
779 // - No special filtering for injected events required at this time.
780 // - Filter normal events based on screen state.
781 // - For normal events brighten (but do not wake) the screen if currently dim.
782 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
783 if (isScreenOn()) {
784 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700785
Jeff Brown3122e442010-10-11 23:32:49 -0700786 if (!isScreenBright()) {
787 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
788 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800789 } else {
790 JNIEnv* env = jniEnv();
791 jint wmActions = env->CallIntMethod(mCallbacksObj,
792 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
793 policyFlags);
794 if (checkAndClearExceptionFromCallback(env,
795 "interceptMotionBeforeQueueingWhenScreenOff")) {
796 wmActions = 0;
797 }
798
799 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
800 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700801 }
Jeff Brown3122e442010-10-11 23:32:49 -0700802 } else {
803 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700804 }
805}
806
Jeff Brown56194eb2011-03-02 19:23:13 -0800807void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
808 uint32_t& policyFlags) {
809 enum {
810 WM_ACTION_PASS_TO_USER = 1,
811 WM_ACTION_POKE_USER_ACTIVITY = 2,
812 WM_ACTION_GO_TO_SLEEP = 4,
813 };
814
815 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800816#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800817 LOGD("handleInterceptActions: Going to sleep.");
818#endif
819 android_server_PowerManagerService_goToSleep(when);
820 }
821
822 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800823#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800824 LOGD("handleInterceptActions: Poking user activity.");
825#endif
826 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
827 }
828
829 if (wmActions & WM_ACTION_PASS_TO_USER) {
830 policyFlags |= POLICY_FLAG_PASS_TO_USER;
831 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800832#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800833 LOGD("handleInterceptActions: Not passing key to user.");
834#endif
835 }
836}
837
Jeff Brown928e0542011-01-10 11:17:36 -0800838bool NativeInputManager::interceptKeyBeforeDispatching(
839 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700840 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700841 // Policy:
842 // - Ignore untrusted events and pass them along.
843 // - Filter normal events and trusted injected events through the window manager policy to
844 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800845 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700846 if (policyFlags & POLICY_FLAG_TRUSTED) {
847 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700848
Jeff Brown928e0542011-01-10 11:17:36 -0800849 // Note: inputWindowHandle may be null.
850 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800851 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
852 if (keyEventObj) {
853 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
854 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800855 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800856 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
857 android_view_KeyEvent_recycle(env, keyEventObj);
858 env->DeleteLocalRef(keyEventObj);
859 result = consumed && !error;
860 } else {
861 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800862 }
Jeff Brown928e0542011-01-10 11:17:36 -0800863 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700864 }
Jeff Brown1f245102010-11-18 20:53:46 -0800865 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700866}
867
Jeff Brown928e0542011-01-10 11:17:36 -0800868bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800869 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700870 // Policy:
871 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800872 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700873 if (policyFlags & POLICY_FLAG_TRUSTED) {
874 JNIEnv* env = jniEnv();
875
Jeff Brown928e0542011-01-10 11:17:36 -0800876 // Note: inputWindowHandle may be null.
877 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800878 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
879 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800880 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800881 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800882 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700883 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
884 fallbackKeyEventObj = NULL;
885 }
Jeff Brown1f245102010-11-18 20:53:46 -0800886 android_view_KeyEvent_recycle(env, keyEventObj);
887 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800888
889 if (fallbackKeyEventObj) {
890 // Note: outFallbackKeyEvent may be the same object as keyEvent.
891 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
892 outFallbackKeyEvent)) {
893 result = true;
894 }
895 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
896 env->DeleteLocalRef(fallbackKeyEventObj);
897 }
Jeff Brown1f245102010-11-18 20:53:46 -0800898 } else {
899 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800900 }
Jeff Brown928e0542011-01-10 11:17:36 -0800901 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700902 }
Jeff Brown1f245102010-11-18 20:53:46 -0800903 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700904}
905
Jeff Brown01ce2e92010-09-26 22:20:12 -0700906void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
907 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700908}
909
Jeff Brown349703e2010-06-22 01:27:15 -0700910
Jeff Brownb88102f2010-09-08 11:49:43 -0700911bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
912 int32_t injectorPid, int32_t injectorUid) {
913 JNIEnv* env = jniEnv();
914 jboolean result = env->CallBooleanMethod(mCallbacksObj,
915 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700916 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
917 result = false;
918 }
Jeff Brown349703e2010-06-22 01:27:15 -0700919 return result;
920}
921
Jeff Brown2352b972011-04-12 22:39:53 -0700922void NativeInputManager::loadPointerResources(PointerResources* outResources) {
923 JNIEnv* env = jniEnv();
924
925 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER,
926 &outResources->spotHover);
927 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH,
928 &outResources->spotTouch);
929 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR,
930 &outResources->spotAnchor);
931}
932
Jeff Brown83c09682010-12-23 17:50:18 -0800933
Jeff Brown9c3cda02010-06-15 01:31:58 -0700934// ----------------------------------------------------------------------------
935
936static sp<NativeInputManager> gNativeInputManager;
937
Jeff Brown46b9ac02010-04-22 18:58:52 -0700938static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700939 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700940 LOGE("Input manager not initialized.");
941 jniThrowRuntimeException(env, "Input manager not initialized.");
942 return true;
943 }
944 return false;
945}
946
947static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown2352b972011-04-12 22:39:53 -0700948 jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700949 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800950 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
Jeff Brown2352b972011-04-12 22:39:53 -0700951 gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700952 } else {
953 LOGE("Input manager already initialized.");
954 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700955 }
956}
957
958static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
959 if (checkInputManagerUnitialized(env)) {
960 return;
961 }
962
Jeff Brown9c3cda02010-06-15 01:31:58 -0700963 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700964 if (result) {
965 jniThrowRuntimeException(env, "Input manager could not be started.");
966 }
967}
968
969static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
970 jint displayId, jint width, jint height) {
971 if (checkInputManagerUnitialized(env)) {
972 return;
973 }
974
975 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
976 // to be passed in like this, not sure which is better but leaving it like this
977 // keeps the window manager in direct control of when display transitions propagate down
978 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700979 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700980}
981
982static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
983 jint displayId, jint orientation) {
984 if (checkInputManagerUnitialized(env)) {
985 return;
986 }
987
Jeff Brown9c3cda02010-06-15 01:31:58 -0700988 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700989}
990
991static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700992 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700993 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700994 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700995 }
996
Jeff Brownb88102f2010-09-08 11:49:43 -0700997 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700998 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700999}
1000
1001static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001002 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001003 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001004 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001005 }
1006
Jeff Brownb88102f2010-09-08 11:49:43 -07001007 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001008 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001009}
1010
1011static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001012 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001013 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001014 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001015 }
1016
Jeff Brownb88102f2010-09-08 11:49:43 -07001017 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001018 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001019}
1020
1021static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001022 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001023 if (checkInputManagerUnitialized(env)) {
1024 return JNI_FALSE;
1025 }
1026
1027 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1028 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1029 jsize numCodes = env->GetArrayLength(keyCodes);
1030 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001031 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001032 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001033 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001034 } else {
1035 result = JNI_FALSE;
1036 }
1037
1038 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1039 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1040 return result;
1041}
1042
1043static void throwInputChannelNotInitialized(JNIEnv* env) {
1044 jniThrowException(env, "java/lang/IllegalStateException",
1045 "inputChannel is not initialized");
1046}
1047
1048static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1049 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1050 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1051 "the input manager!", inputChannel->getName().string());
1052
Jeff Brown9c3cda02010-06-15 01:31:58 -07001053 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001054 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001055 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001056}
1057
1058static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001059 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001060 if (checkInputManagerUnitialized(env)) {
1061 return;
1062 }
1063
1064 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1065 inputChannelObj);
1066 if (inputChannel == NULL) {
1067 throwInputChannelNotInitialized(env);
1068 return;
1069 }
1070
Jeff Brown928e0542011-01-10 11:17:36 -08001071 sp<InputWindowHandle> inputWindowHandle =
1072 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001073
1074 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001075 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001076 if (status) {
1077 jniThrowRuntimeException(env, "Failed to register input channel. "
1078 "Check logs for details.");
1079 return;
1080 }
1081
Jeff Browna41ca772010-08-11 14:46:32 -07001082 if (! monitor) {
1083 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1084 android_server_InputManager_handleInputChannelDisposed, NULL);
1085 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001086}
1087
1088static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1089 jobject inputChannelObj) {
1090 if (checkInputManagerUnitialized(env)) {
1091 return;
1092 }
1093
1094 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1095 inputChannelObj);
1096 if (inputChannel == NULL) {
1097 throwInputChannelNotInitialized(env);
1098 return;
1099 }
1100
1101 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1102
Jeff Brown7fbdc842010-06-17 20:52:56 -07001103 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001104 if (status) {
1105 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1106 "Check logs for details.");
1107 }
1108}
1109
Jeff Brown0029c662011-03-30 02:25:18 -07001110static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
1111 jboolean enabled) {
1112 if (checkInputManagerUnitialized(env)) {
1113 return;
1114 }
1115
1116 gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1117}
1118
Jeff Brown6ec402b2010-07-28 15:48:59 -07001119static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1120 jobject inputEventObj, jint injectorPid, jint injectorUid,
Jeff Brown0029c662011-03-30 02:25:18 -07001121 jint syncMode, jint timeoutMillis, jint policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001122 if (checkInputManagerUnitialized(env)) {
1123 return INPUT_EVENT_INJECTION_FAILED;
1124 }
1125
Jeff Brown6ec402b2010-07-28 15:48:59 -07001126 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1127 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001128 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1129 if (status) {
1130 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1131 return INPUT_EVENT_INJECTION_FAILED;
1132 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001133
Jeff Brownb88102f2010-09-08 11:49:43 -07001134 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001135 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1136 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001137 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001138 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1139 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001140 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1141 return INPUT_EVENT_INJECTION_FAILED;
1142 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001143
Jeff Brownb88102f2010-09-08 11:49:43 -07001144 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001145 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1146 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001147 } else {
1148 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001149 return INPUT_EVENT_INJECTION_FAILED;
1150 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001151}
1152
Jeff Brown349703e2010-06-22 01:27:15 -07001153static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1154 jobjectArray windowObjArray) {
1155 if (checkInputManagerUnitialized(env)) {
1156 return;
1157 }
1158
1159 gNativeInputManager->setInputWindows(env, windowObjArray);
1160}
1161
1162static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1163 jobject applicationObj) {
1164 if (checkInputManagerUnitialized(env)) {
1165 return;
1166 }
1167
1168 gNativeInputManager->setFocusedApplication(env, applicationObj);
1169}
1170
1171static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1172 jclass clazz, jboolean enabled, jboolean frozen) {
1173 if (checkInputManagerUnitialized(env)) {
1174 return;
1175 }
1176
1177 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1178}
1179
Jeff Brown05dc66a2011-03-02 14:41:58 -08001180static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1181 jclass clazz, jint visibility) {
1182 if (checkInputManagerUnitialized(env)) {
1183 return;
1184 }
1185
1186 gNativeInputManager->setSystemUiVisibility(visibility);
1187}
1188
Jeff Brown8d608662010-08-30 03:02:23 -07001189static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1190 jclass clazz, jint deviceId) {
1191 if (checkInputManagerUnitialized(env)) {
1192 return NULL;
1193 }
1194
1195 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001196 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001197 deviceId, & deviceInfo);
1198 if (status) {
1199 return NULL;
1200 }
1201
1202 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1203 if (! deviceObj) {
1204 return NULL;
1205 }
1206
1207 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1208 if (! deviceNameObj) {
1209 return NULL;
1210 }
1211
1212 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1213 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1214 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1215 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1216
Jeff Brownefd32662011-03-08 15:13:06 -08001217 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001218 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001219 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001220 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001221 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001222 if (env->ExceptionCheck()) {
1223 return NULL;
1224 }
1225 }
1226
1227 return deviceObj;
1228}
1229
1230static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1231 jclass clazz) {
1232 if (checkInputManagerUnitialized(env)) {
1233 return NULL;
1234 }
1235
1236 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001237 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001238
1239 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1240 if (! deviceIdsObj) {
1241 return NULL;
1242 }
1243
1244 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1245 return deviceIdsObj;
1246}
1247
Jeff Brown57c59372010-09-21 18:22:55 -07001248static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1249 jclass clazz, jobject configObj) {
1250 if (checkInputManagerUnitialized(env)) {
1251 return;
1252 }
1253
1254 InputConfiguration config;
1255 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1256
1257 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1258 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1259 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1260}
1261
Jeff Browne6504122010-09-27 14:52:15 -07001262static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1263 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1264 if (checkInputManagerUnitialized(env)) {
1265 return false;
1266 }
1267
1268 sp<InputChannel> fromChannel =
1269 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1270 sp<InputChannel> toChannel =
1271 android_view_InputChannel_getInputChannel(env, toChannelObj);
1272
1273 if (fromChannel == NULL || toChannel == NULL) {
1274 return false;
1275 }
1276
1277 return gNativeInputManager->getInputManager()->getDispatcher()->
1278 transferTouchFocus(fromChannel, toChannel);
1279}
1280
Jeff Brown1a84fd12011-06-02 01:26:32 -07001281static void android_server_InputManager_nativeSetPointerSpeed(JNIEnv* env,
1282 jclass clazz, jint speed) {
1283 if (checkInputManagerUnitialized(env)) {
1284 return;
1285 }
1286
1287 gNativeInputManager->setPointerSpeed(speed);
1288}
1289
Jeff Browne33348b2010-07-15 23:54:05 -07001290static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1291 if (checkInputManagerUnitialized(env)) {
1292 return NULL;
1293 }
1294
Jeff Brownb88102f2010-09-08 11:49:43 -07001295 String8 dump;
1296 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001297 return env->NewStringUTF(dump.string());
1298}
1299
Jeff Brown9c3cda02010-06-15 01:31:58 -07001300// ----------------------------------------------------------------------------
1301
Jeff Brown46b9ac02010-04-22 18:58:52 -07001302static JNINativeMethod gInputManagerMethods[] = {
1303 /* name, signature, funcPtr */
Jeff Brown2352b972011-04-12 22:39:53 -07001304 { "nativeInit", "(Landroid/content/Context;"
1305 "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001306 (void*) android_server_InputManager_nativeInit },
1307 { "nativeStart", "()V",
1308 (void*) android_server_InputManager_nativeStart },
1309 { "nativeSetDisplaySize", "(III)V",
1310 (void*) android_server_InputManager_nativeSetDisplaySize },
1311 { "nativeSetDisplayOrientation", "(II)V",
1312 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1313 { "nativeGetScanCodeState", "(III)I",
1314 (void*) android_server_InputManager_nativeGetScanCodeState },
1315 { "nativeGetKeyCodeState", "(III)I",
1316 (void*) android_server_InputManager_nativeGetKeyCodeState },
1317 { "nativeGetSwitchState", "(III)I",
1318 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001319 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001320 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001321 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001322 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001323 (void*) android_server_InputManager_nativeRegisterInputChannel },
1324 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001325 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown0029c662011-03-30 02:25:18 -07001326 { "nativeSetInputFilterEnabled", "(Z)V",
1327 (void*) android_server_InputManager_nativeSetInputFilterEnabled },
1328 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
Jeff Brown6ec402b2010-07-28 15:48:59 -07001329 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001330 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001331 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001332 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001333 (void*) android_server_InputManager_nativeSetFocusedApplication },
1334 { "nativeSetInputDispatchMode", "(ZZ)V",
1335 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001336 { "nativeSetSystemUiVisibility", "(I)V",
1337 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001338 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1339 (void*) android_server_InputManager_nativeGetInputDevice },
1340 { "nativeGetInputDeviceIds", "()[I",
1341 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001342 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1343 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001344 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1345 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Brown1a84fd12011-06-02 01:26:32 -07001346 { "nativeSetPointerSpeed", "(I)V",
1347 (void*) android_server_InputManager_nativeSetPointerSpeed },
Jeff Browne33348b2010-07-15 23:54:05 -07001348 { "nativeDump", "()Ljava/lang/String;",
1349 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001350};
1351
1352#define FIND_CLASS(var, className) \
1353 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001354 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001355
1356#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1357 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1358 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1359
1360#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1361 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1362 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1363
1364int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001365 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001366 gInputManagerMethods, NELEM(gInputManagerMethods));
1367 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1368
Jeff Brown9c3cda02010-06-15 01:31:58 -07001369 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001370
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001371 jclass clazz;
1372 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001373
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001374 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001375 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001376
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001377 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001378 "notifyLidSwitchChanged", "(JZ)V");
1379
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001380 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001381 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001382
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001383 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001384 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001385 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001386
Jeff Brown0029c662011-03-30 02:25:18 -07001387 GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
1388 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1389
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001390 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001391 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001392
Jeff Brown56194eb2011-03-02 19:23:13 -08001393 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001394 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001395 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1396
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001397 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001398 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001399 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001400
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001401 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001402 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001403 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001404
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001405 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001406 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001407
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001408 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001409 "filterTouchEvents", "()Z");
1410
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001411 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001412 "filterJumpyTouchEvents", "()Z");
1413
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001414 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001415 "getVirtualKeyQuietTimeMillis", "()I");
1416
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001417 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001418 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1419
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001420 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001421 "getKeyRepeatTimeout", "()I");
1422
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001423 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001424 "getKeyRepeatDelay", "()I");
1425
Jeff Brown774ed9d2011-06-07 17:48:39 -07001426 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapTimeout, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001427 "getHoverTapTimeout", "()I");
1428
Jeff Brown774ed9d2011-06-07 17:48:39 -07001429 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapSlop, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001430 "getHoverTapSlop", "()I");
Jeff Brown214eaf42011-05-26 19:17:02 -07001431
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001432 GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001433 "getDoubleTapTimeout", "()I");
1434
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001435 GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001436 "getLongPressTimeout", "()I");
1437
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001438 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001439 "getMaxEventsPerSecond", "()I");
1440
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001441 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001442 "getPointerLayer", "()I");
1443
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001444 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Jeff Brown2352b972011-04-12 22:39:53 -07001445 "getPointerIcon", "()Landroid/view/PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001446
Jeff Brown6ec402b2010-07-28 15:48:59 -07001447 // KeyEvent
1448
1449 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001450 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1451
Jeff Brown6ec402b2010-07-28 15:48:59 -07001452
Jeff Brown8d608662010-08-30 03:02:23 -07001453 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001454
1455 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001456 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001457
Jeff Brown8d608662010-08-30 03:02:23 -07001458 // InputDevice
1459
1460 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001461 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001462
1463 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1464 "<init>", "()V");
1465
1466 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001467 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001468
1469 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1470 "mId", "I");
1471
1472 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1473 "mName", "Ljava/lang/String;");
1474
1475 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1476 "mSources", "I");
1477
1478 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1479 "mKeyboardType", "I");
1480
Jeff Brown57c59372010-09-21 18:22:55 -07001481 // Configuration
1482
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001483 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001484
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001485 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001486 "touchscreen", "I");
1487
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001488 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001489 "keyboard", "I");
1490
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001491 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001492 "navigation", "I");
1493
Jeff Brown46b9ac02010-04-22 18:58:52 -07001494 return 0;
1495}
1496
Jeff Brown46b9ac02010-04-22 18:58:52 -07001497} /* namespace android */