blob: de9c9d0dbb18c265a8ab2c67b611801a540f4a44 [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_InputApplicationHandle.h"
Jeff Brown928e0542011-01-10 11:17:36 -080050#include "com_android_server_InputWindowHandle.h"
Jeff Brown46b9ac02010-04-22 18:58:52 -070051
52namespace android {
53
Jeff Brown1a84fd12011-06-02 01:26:32 -070054// The exponent used to calculate the pointer speed scaling factor.
55// The scaling factor is calculated as 2 ^ (speed * exponent),
56// where the speed ranges from -7 to + 7 and is supplied by the user.
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -070057static const float POINTER_SPEED_EXPONENT = 1.0f / 4;
Jeff Brown1a84fd12011-06-02 01:26:32 -070058
Jeff Brown46b9ac02010-04-22 18:58:52 -070059static struct {
Jeff Brown46b9ac02010-04-22 18:58:52 -070060 jmethodID notifyConfigurationChanged;
61 jmethodID notifyLidSwitchChanged;
Jeff Brown7fbdc842010-06-17 20:52:56 -070062 jmethodID notifyInputChannelBroken;
Jeff Brown349703e2010-06-22 01:27:15 -070063 jmethodID notifyANR;
Jeff Brown0029c662011-03-30 02:25:18 -070064 jmethodID filterInputEvent;
Jeff Brown349703e2010-06-22 01:27:15 -070065 jmethodID interceptKeyBeforeQueueing;
Jeff Brown56194eb2011-03-02 19:23:13 -080066 jmethodID interceptMotionBeforeQueueingWhenScreenOff;
Jeff Brown349703e2010-06-22 01:27:15 -070067 jmethodID interceptKeyBeforeDispatching;
Jeff Brown3915bb82010-11-05 15:02:16 -070068 jmethodID dispatchUnhandledKey;
Jeff Brown349703e2010-06-22 01:27:15 -070069 jmethodID checkInjectEventsPermission;
Jeff Brownfe508922011-01-18 15:10:10 -080070 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac02010-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 Brownbb3fcba0c2011-06-06 19:23:05 -070075 jmethodID getHoverTapTimeout;
76 jmethodID getHoverTapSlop;
Jeff Brown214eaf42011-05-26 19:17:02 -070077 jmethodID getDoubleTapTimeout;
78 jmethodID getLongPressTimeout;
Jeff Brown83c09682010-12-23 17:50:18 -080079 jmethodID getPointerLayer;
Jeff Brownb4ff35d2011-01-02 16:37:43 -080080 jmethodID getPointerIcon;
Jeff Brown46b9ac02010-04-22 18:58:52 -070081} gCallbacksClassInfo;
82
83static struct {
84 jclass clazz;
Jeff Brown6ec402b2010-07-28 15:48:59 -070085} gKeyEventClassInfo;
86
87static struct {
88 jclass clazz;
89} gMotionEventClassInfo;
90
Jeff Brown8d608662010-08-30 03:02:23 -070091static struct {
92 jclass clazz;
93
94 jmethodID ctor;
95 jmethodID addMotionRange;
96
97 jfieldID mId;
98 jfieldID mName;
99 jfieldID mSources;
100 jfieldID mKeyboardType;
Jeff Brown8d608662010-08-30 03:02:23 -0700101} gInputDeviceClassInfo;
102
Jeff Brown57c59372010-09-21 18:22:55 -0700103static struct {
Jeff Brown57c59372010-09-21 18:22:55 -0700104 jfieldID touchscreen;
105 jfieldID keyboard;
106 jfieldID navigation;
107} gConfigurationClassInfo;
108
Jeff Brown928e0542011-01-10 11:17:36 -0800109
110// --- Global functions ---
111
Jeff Brown214eaf42011-05-26 19:17:02 -0700112template<typename T>
113inline static T min(const T& a, const T& b) {
114 return a < b ? a : b;
115}
116
117template<typename T>
118inline static T max(const T& a, const T& b) {
119 return a > b ? a : b;
120}
121
Jeff Brown928e0542011-01-10 11:17:36 -0800122static jobject getInputApplicationHandleObjLocalRef(JNIEnv* env,
123 const sp<InputApplicationHandle>& inputApplicationHandle) {
124 if (inputApplicationHandle == NULL) {
125 return NULL;
126 }
127 return static_cast<NativeInputApplicationHandle*>(inputApplicationHandle.get())->
128 getInputApplicationHandleObjLocalRef(env);
129}
130
131static jobject getInputWindowHandleObjLocalRef(JNIEnv* env,
132 const sp<InputWindowHandle>& inputWindowHandle) {
133 if (inputWindowHandle == NULL) {
134 return NULL;
135 }
136 return static_cast<NativeInputWindowHandle*>(inputWindowHandle.get())->
137 getInputWindowHandleObjLocalRef(env);
138}
139
Jeff Brown2352b972011-04-12 22:39:53 -0700140static void loadSystemIconAsSprite(JNIEnv* env, jobject contextObj, int32_t style,
141 SpriteIcon* outSpriteIcon) {
142 PointerIcon pointerIcon;
143 status_t status = android_view_PointerIcon_loadSystemIcon(env,
144 contextObj, style, &pointerIcon);
145 if (!status) {
146 pointerIcon.bitmap.copyTo(&outSpriteIcon->bitmap, SkBitmap::kARGB_8888_Config);
147 outSpriteIcon->hotSpotX = pointerIcon.hotSpotX;
148 outSpriteIcon->hotSpotY = pointerIcon.hotSpotY;
149 }
150}
151
Jeff Brown928e0542011-01-10 11:17:36 -0800152
153// --- NativeInputManager ---
Jeff Brown83c09682010-12-23 17:50:18 -0800154
Jeff Brown9c3cda02010-06-15 01:31:58 -0700155class NativeInputManager : public virtual RefBase,
156 public virtual InputReaderPolicyInterface,
Jeff Brown2352b972011-04-12 22:39:53 -0700157 public virtual InputDispatcherPolicyInterface,
158 public virtual PointerControllerPolicyInterface {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700159protected:
160 virtual ~NativeInputManager();
161
162public:
Jeff Brown2352b972011-04-12 22:39:53 -0700163 NativeInputManager(jobject contextObj, jobject callbacksObj, const sp<Looper>& looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700164
165 inline sp<InputManager> getInputManager() const { return mInputManager; }
166
Jeff Brownb88102f2010-09-08 11:49:43 -0700167 void dump(String8& dump);
Jeff Browne33348b2010-07-15 23:54:05 -0700168
Jeff Brown9c3cda02010-06-15 01:31:58 -0700169 void setDisplaySize(int32_t displayId, int32_t width, int32_t height);
170 void setDisplayOrientation(int32_t displayId, int32_t orientation);
171
Jeff Brown7fbdc842010-06-17 20:52:56 -0700172 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800173 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700174 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
175
Jeff Brown9302c872011-07-13 22:51:29 -0700176 void setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray);
177 void setFocusedApplication(JNIEnv* env, jobject applicationHandleObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700178 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800179 void setSystemUiVisibility(int32_t visibility);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700180 void setPointerSpeed(int32_t speed);
Jeff Brown349703e2010-06-22 01:27:15 -0700181
Jeff Brown9c3cda02010-06-15 01:31:58 -0700182 /* --- InputReaderPolicyInterface implementation --- */
183
184 virtual bool getDisplayInfo(int32_t displayId,
185 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown214eaf42011-05-26 19:17:02 -0700186 virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);
Jeff Brown83c09682010-12-23 17:50:18 -0800187 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700188
189 /* --- InputDispatcherPolicyInterface implementation --- */
190
Jeff Browne20c9e02010-10-11 14:20:19 -0700191 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
192 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700193 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700194 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800195 const sp<InputWindowHandle>& inputWindowHandle);
196 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown0029c662011-03-30 02:25:18 -0700197 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
Jeff Brown214eaf42011-05-26 19:17:02 -0700198 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
199 virtual bool isKeyRepeatEnabled();
Jeff Brown1f245102010-11-18 20:53:46 -0800200 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800201 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800202 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700203 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800204 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800205 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700206 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700207 virtual bool checkInjectEventsPermissionNonReentrant(
208 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700209
Jeff Brown2352b972011-04-12 22:39:53 -0700210 /* --- PointerControllerPolicyInterface implementation --- */
211
212 virtual void loadPointerResources(PointerResources* outResources);
213
Jeff Brown9c3cda02010-06-15 01:31:58 -0700214private:
215 sp<InputManager> mInputManager;
216
Jeff Brown2352b972011-04-12 22:39:53 -0700217 jobject mContextObj;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700218 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800219 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700220
Jeff Brown83c09682010-12-23 17:50:18 -0800221 Mutex mLock;
222 struct Locked {
223 // Display size information.
224 int32_t displayWidth, displayHeight; // -1 when initialized
225 int32_t displayOrientation;
226
Jeff Brown05dc66a2011-03-02 14:41:58 -0800227 // System UI visibility.
228 int32_t systemUiVisibility;
229
Jeff Brown1a84fd12011-06-02 01:26:32 -0700230 // Pointer speed.
231 int32_t pointerSpeed;
232
Jeff Brown474dcb52011-06-14 20:22:50 -0700233 // True if pointer gestures are enabled.
234 bool pointerGesturesEnabled;
235
Jeff Brown5541de92011-04-11 11:54:25 -0700236 // Sprite controller singleton, created on first use.
237 sp<SpriteController> spriteController;
238
Jeff Brown83c09682010-12-23 17:50:18 -0800239 // Pointer controller singleton, created and destroyed as needed.
240 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800241 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700242
Jeff Brown2352b972011-04-12 22:39:53 -0700243 void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800244 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown5541de92011-04-11 11:54:25 -0700245 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800246
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700247 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700248 bool isScreenOn();
249 bool isScreenBright();
250
Jeff Brownb88102f2010-09-08 11:49:43 -0700251 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700252
Jeff Brown9c3cda02010-06-15 01:31:58 -0700253 static inline JNIEnv* jniEnv() {
254 return AndroidRuntime::getJNIEnv();
255 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700256};
257
Jeff Brown928e0542011-01-10 11:17:36 -0800258
Jeff Brown9c3cda02010-06-15 01:31:58 -0700259
Jeff Brown2352b972011-04-12 22:39:53 -0700260NativeInputManager::NativeInputManager(jobject contextObj,
261 jobject callbacksObj, const sp<Looper>& looper) :
Jeff Brown214eaf42011-05-26 19:17:02 -0700262 mLooper(looper) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700263 JNIEnv* env = jniEnv();
264
Jeff Brown2352b972011-04-12 22:39:53 -0700265 mContextObj = env->NewGlobalRef(contextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700266 mCallbacksObj = env->NewGlobalRef(callbacksObj);
267
Jeff Brown83c09682010-12-23 17:50:18 -0800268 {
269 AutoMutex _l(mLock);
270 mLocked.displayWidth = -1;
271 mLocked.displayHeight = -1;
272 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800273
274 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700275 mLocked.pointerSpeed = 0;
Jeff Brown474dcb52011-06-14 20:22:50 -0700276 mLocked.pointerGesturesEnabled = true;
Jeff Brown83c09682010-12-23 17:50:18 -0800277 }
278
Jeff Brown9c3cda02010-06-15 01:31:58 -0700279 sp<EventHub> eventHub = new EventHub();
280 mInputManager = new InputManager(eventHub, this, this);
281}
282
283NativeInputManager::~NativeInputManager() {
284 JNIEnv* env = jniEnv();
285
Jeff Brown2352b972011-04-12 22:39:53 -0700286 env->DeleteGlobalRef(mContextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700287 env->DeleteGlobalRef(mCallbacksObj);
288}
289
Jeff Brownb88102f2010-09-08 11:49:43 -0700290void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700291 mInputManager->getReader()->dump(dump);
292 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700293
Jeff Brownb88102f2010-09-08 11:49:43 -0700294 mInputManager->getDispatcher()->dump(dump);
295 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700296}
297
Jeff Brown7fbdc842010-06-17 20:52:56 -0700298bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700299 if (env->ExceptionCheck()) {
300 LOGE("An exception was thrown by callback '%s'.", methodName);
301 LOGE_EX(env);
302 env->ExceptionClear();
303 return true;
304 }
305 return false;
306}
307
308void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height) {
309 if (displayId == 0) {
Jeff Brown2352b972011-04-12 22:39:53 -0700310 { // acquire lock
311 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700312
Jeff Brown2352b972011-04-12 22:39:53 -0700313 if (mLocked.displayWidth == width && mLocked.displayHeight == height) {
314 return;
315 }
316
Jeff Brown83c09682010-12-23 17:50:18 -0800317 mLocked.displayWidth = width;
318 mLocked.displayHeight = height;
319
320 sp<PointerController> controller = mLocked.pointerController.promote();
321 if (controller != NULL) {
322 controller->setDisplaySize(width, height);
323 }
Jeff Brown2352b972011-04-12 22:39:53 -0700324 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700325 }
326}
327
328void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
329 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800330 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700331
Jeff Brown83c09682010-12-23 17:50:18 -0800332 if (mLocked.displayOrientation != orientation) {
333 mLocked.displayOrientation = orientation;
334
335 sp<PointerController> controller = mLocked.pointerController.promote();
336 if (controller != NULL) {
337 controller->setDisplayOrientation(orientation);
338 }
339 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700340 }
341}
342
Jeff Brown7fbdc842010-06-17 20:52:56 -0700343status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800344 const sp<InputChannel>& inputChannel,
345 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
346 return mInputManager->getDispatcher()->registerInputChannel(
347 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700348}
349
350status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
351 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700352 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700353}
354
Jeff Brown9c3cda02010-06-15 01:31:58 -0700355bool NativeInputManager::getDisplayInfo(int32_t displayId,
356 int32_t* width, int32_t* height, int32_t* orientation) {
357 bool result = false;
358 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800359 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700360
Jeff Brown83c09682010-12-23 17:50:18 -0800361 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700362 if (width) {
Jeff Brown83c09682010-12-23 17:50:18 -0800363 *width = mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700364 }
365 if (height) {
Jeff Brown83c09682010-12-23 17:50:18 -0800366 *height = mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700367 }
368 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800369 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700370 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700371 result = true;
372 }
373 }
374 return result;
375}
376
Jeff Brown214eaf42011-05-26 19:17:02 -0700377void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700378 JNIEnv* env = jniEnv();
379
Jeff Brown214eaf42011-05-26 19:17:02 -0700380 jint virtualKeyQuietTime = env->CallIntMethod(mCallbacksObj,
381 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
382 if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
383 outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
384 }
385
386 outConfig->excludedDeviceNames.clear();
387 jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mCallbacksObj,
Jeff Brown9c3cda02010-06-15 01:31:58 -0700388 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown214eaf42011-05-26 19:17:02 -0700389 if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
390 jsize length = env->GetArrayLength(excludedDeviceNames);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700391 for (jsize i = 0; i < length; i++) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700392 jstring item = jstring(env->GetObjectArrayElement(excludedDeviceNames, i));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700393 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
Jeff Brown214eaf42011-05-26 19:17:02 -0700394 outConfig->excludedDeviceNames.add(String8(deviceNameChars));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700395 env->ReleaseStringUTFChars(item, deviceNameChars);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700396 env->DeleteLocalRef(item);
397 }
Jeff Brown214eaf42011-05-26 19:17:02 -0700398 env->DeleteLocalRef(excludedDeviceNames);
399 }
400
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700401 jint hoverTapTimeout = env->CallIntMethod(mCallbacksObj,
402 gCallbacksClassInfo.getHoverTapTimeout);
403 if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700404 jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
405 gCallbacksClassInfo.getDoubleTapTimeout);
406 if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
407 jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
408 gCallbacksClassInfo.getLongPressTimeout);
409 if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700410 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700411
412 // We must ensure that the tap-drag interval is significantly shorter than
413 // the long-press timeout because the tap is held down for the entire duration
414 // of the double-tap timeout.
415 jint tapDragInterval = max(min(longPressTimeout - 100,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700416 doubleTapTimeout), hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700417 outConfig->pointerGestureTapDragInterval =
418 milliseconds_to_nanoseconds(tapDragInterval);
419 }
420 }
421 }
422
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700423 jint hoverTapSlop = env->CallIntMethod(mCallbacksObj,
424 gCallbacksClassInfo.getHoverTapSlop);
425 if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
426 outConfig->pointerGestureTapSlop = hoverTapSlop;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700427 }
Jeff Brown1a84fd12011-06-02 01:26:32 -0700428
429 { // acquire lock
430 AutoMutex _l(mLock);
431
432 outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
433 * POINTER_SPEED_EXPONENT);
Jeff Brown474dcb52011-06-14 20:22:50 -0700434 outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700435 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700436}
437
Jeff Brown83c09682010-12-23 17:50:18 -0800438sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
439 AutoMutex _l(mLock);
440
441 sp<PointerController> controller = mLocked.pointerController.promote();
442 if (controller == NULL) {
Jeff Brown5541de92011-04-11 11:54:25 -0700443 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800444
Jeff Brown2352b972011-04-12 22:39:53 -0700445 controller = new PointerController(this, mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800446 mLocked.pointerController = controller;
447
448 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
449 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800450
Jeff Brown5541de92011-04-11 11:54:25 -0700451 JNIEnv* env = jniEnv();
Jeff Brown2352b972011-04-12 22:39:53 -0700452 jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
453 gCallbacksClassInfo.getPointerIcon);
454 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
455 PointerIcon pointerIcon;
456 status_t status = android_view_PointerIcon_load(env, pointerIconObj,
457 mContextObj, &pointerIcon);
458 if (!status && !pointerIcon.isNullIcon()) {
459 controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
460 pointerIcon.hotSpotX, pointerIcon.hotSpotY));
461 } else {
462 controller->setPointerIcon(SpriteIcon());
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800463 }
Jeff Brown2352b972011-04-12 22:39:53 -0700464 env->DeleteLocalRef(pointerIconObj);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800465 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800466
Jeff Brown2352b972011-04-12 22:39:53 -0700467 updateInactivityTimeoutLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800468 }
469 return controller;
470}
471
Jeff Brown5541de92011-04-11 11:54:25 -0700472void NativeInputManager::ensureSpriteControllerLocked() {
473 if (mLocked.spriteController == NULL) {
474 JNIEnv* env = jniEnv();
475 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
476 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
477 layer = -1;
478 }
479 mLocked.spriteController = new SpriteController(mLooper, layer);
480 }
481}
482
Jeff Browne20c9e02010-10-11 14:20:19 -0700483void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
484 int32_t switchValue, uint32_t policyFlags) {
485#if DEBUG_INPUT_DISPATCHER_POLICY
486 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
487 when, switchCode, switchValue, policyFlags);
488#endif
489
490 JNIEnv* env = jniEnv();
491
492 switch (switchCode) {
493 case SW_LID:
494 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
495 when, switchValue == 0);
496 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
497 break;
498 }
499}
500
Jeff Brown9c3cda02010-06-15 01:31:58 -0700501void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
502#if DEBUG_INPUT_DISPATCHER_POLICY
503 LOGD("notifyConfigurationChanged - when=%lld", when);
504#endif
505
506 JNIEnv* env = jniEnv();
507
Jeff Brown57c59372010-09-21 18:22:55 -0700508 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700509 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700510}
511
Jeff Brown519e0242010-09-15 15:18:56 -0700512nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800513 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700514#if DEBUG_INPUT_DISPATCHER_POLICY
515 LOGD("notifyANR");
516#endif
517
518 JNIEnv* env = jniEnv();
519
Jeff Brown928e0542011-01-10 11:17:36 -0800520 jobject inputApplicationHandleObj =
521 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
522 jobject inputWindowHandleObj =
523 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700524
Jeff Brown519e0242010-09-15 15:18:56 -0700525 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800526 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700527 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
528 newTimeout = 0; // abort dispatch
529 } else {
530 assert(newTimeout >= 0);
531 }
532
Jeff Brown928e0542011-01-10 11:17:36 -0800533 env->DeleteLocalRef(inputWindowHandleObj);
534 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700535 return newTimeout;
536}
537
Jeff Brown928e0542011-01-10 11:17:36 -0800538void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700539#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800540 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700541#endif
542
Jeff Brown7fbdc842010-06-17 20:52:56 -0700543 JNIEnv* env = jniEnv();
544
Jeff Brown928e0542011-01-10 11:17:36 -0800545 jobject inputWindowHandleObj =
546 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
547 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700548 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800549 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700550 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
551
Jeff Brown928e0542011-01-10 11:17:36 -0800552 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700553 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700554}
555
Jeff Brown214eaf42011-05-26 19:17:02 -0700556void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
557 JNIEnv* env = jniEnv();
Jeff Browna4547672011-03-02 21:38:11 -0800558
Jeff Brown214eaf42011-05-26 19:17:02 -0700559 jint keyRepeatTimeout = env->CallIntMethod(mCallbacksObj,
560 gCallbacksClassInfo.getKeyRepeatTimeout);
561 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
562 outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
563 }
Jeff Browna4547672011-03-02 21:38:11 -0800564
Jeff Brown214eaf42011-05-26 19:17:02 -0700565 jint keyRepeatDelay = env->CallIntMethod(mCallbacksObj,
566 gCallbacksClassInfo.getKeyRepeatDelay);
567 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
568 outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
569 }
570
571 jint maxEventsPerSecond = env->CallIntMethod(mCallbacksObj,
572 gCallbacksClassInfo.getMaxEventsPerSecond);
573 if (!checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
574 outConfig->maxEventsPerSecond = maxEventsPerSecond;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700575 }
576}
577
Jeff Brown214eaf42011-05-26 19:17:02 -0700578bool NativeInputManager::isKeyRepeatEnabled() {
579 // Only enable automatic key repeating when the screen is on.
580 return isScreenOn();
Jeff Brownae9fc032010-08-18 15:51:08 -0700581}
582
Jeff Brown9302c872011-07-13 22:51:29 -0700583void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray) {
584 Vector<sp<InputWindowHandle> > windowHandles;
Jeff Brown349703e2010-06-22 01:27:15 -0700585
Jeff Brown9302c872011-07-13 22:51:29 -0700586 if (windowHandleObjArray) {
587 jsize length = env->GetArrayLength(windowHandleObjArray);
588 for (jsize i = 0; i < length; i++) {
589 jobject windowHandleObj = env->GetObjectArrayElement(windowHandleObjArray, i);
590 if (! windowHandleObj) {
591 break; // found null element indicating end of used portion of the array
Jeff Brown474dcb52011-06-14 20:22:50 -0700592 }
Jeff Brown9302c872011-07-13 22:51:29 -0700593
594 sp<InputWindowHandle> windowHandle =
595 android_server_InputWindowHandle_getHandle(env, windowHandleObj);
596 if (windowHandle != NULL) {
597 windowHandles.push(windowHandle);
598 }
599 env->DeleteLocalRef(windowHandleObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700600 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700601 }
Jeff Brown349703e2010-06-22 01:27:15 -0700602
Jeff Brown9302c872011-07-13 22:51:29 -0700603 mInputManager->getDispatcher()->setInputWindows(windowHandles);
604
605 // Do this after the dispatcher has updated the window handle state.
606 bool newPointerGesturesEnabled = true;
607 size_t numWindows = windowHandles.size();
608 for (size_t i = 0; i < numWindows; i++) {
609 const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
610 if (windowHandle->hasFocus && (windowHandle->inputFeatures
611 & InputWindowHandle::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES)) {
612 newPointerGesturesEnabled = false;
613 }
614 }
Jeff Brown474dcb52011-06-14 20:22:50 -0700615
616 uint32_t changes = 0;
617 { // acquire lock
618 AutoMutex _l(mLock);
619
620 if (mLocked.pointerGesturesEnabled != newPointerGesturesEnabled) {
621 mLocked.pointerGesturesEnabled = newPointerGesturesEnabled;
622 changes |= InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT;
623 }
624 } // release lock
625
626 if (changes) {
627 mInputManager->getReader()->requestRefreshConfiguration(changes);
628 }
Jeff Brown349703e2010-06-22 01:27:15 -0700629}
630
Jeff Brown9302c872011-07-13 22:51:29 -0700631void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationHandleObj) {
632 sp<InputApplicationHandle> applicationHandle =
633 android_server_InputApplicationHandle_getHandle(env, applicationHandleObj);
634 mInputManager->getDispatcher()->setFocusedApplication(applicationHandle);
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) {
Jeff Brown2352b972011-04-12 22:39:53 -0700649 updateInactivityTimeoutLocked(controller);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800650 }
651 }
652}
653
Jeff Brown2352b972011-04-12 22:39:53 -0700654void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800655 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
Jeff Brown2352b972011-04-12 22:39:53 -0700656 controller->setInactivityTimeout(lightsOut
657 ? PointerController::INACTIVITY_TIMEOUT_SHORT
658 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800659}
660
Jeff Brown1a84fd12011-06-02 01:26:32 -0700661void NativeInputManager::setPointerSpeed(int32_t speed) {
Jeff Brown474dcb52011-06-14 20:22:50 -0700662 { // acquire lock
663 AutoMutex _l(mLock);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700664
Jeff Brown474dcb52011-06-14 20:22:50 -0700665 if (mLocked.pointerSpeed == speed) {
666 return;
667 }
668
Jeff Brown1a84fd12011-06-02 01:26:32 -0700669 LOGI("Setting pointer speed to %d.", speed);
670 mLocked.pointerSpeed = speed;
Jeff Brown474dcb52011-06-14 20:22:50 -0700671 } // release lock
Jeff Brown1a84fd12011-06-02 01:26:32 -0700672
Jeff Brown474dcb52011-06-14 20:22:50 -0700673 mInputManager->getReader()->requestRefreshConfiguration(
674 InputReaderConfiguration::CHANGE_POINTER_SPEED);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700675}
676
Jeff Browne20c9e02010-10-11 14:20:19 -0700677bool NativeInputManager::isScreenOn() {
678 return android_server_PowerManagerService_isScreenOn();
679}
680
681bool NativeInputManager::isScreenBright() {
682 return android_server_PowerManagerService_isScreenBright();
683}
684
Jeff Brown0029c662011-03-30 02:25:18 -0700685bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
686 jobject inputEventObj;
687
688 JNIEnv* env = jniEnv();
689 switch (inputEvent->getType()) {
690 case AINPUT_EVENT_TYPE_KEY:
691 inputEventObj = android_view_KeyEvent_fromNative(env,
692 static_cast<const KeyEvent*>(inputEvent));
693 break;
694 case AINPUT_EVENT_TYPE_MOTION:
695 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
696 static_cast<const MotionEvent*>(inputEvent));
697 break;
698 default:
699 return true; // dispatch the event normally
700 }
701
702 if (!inputEventObj) {
703 LOGE("Failed to obtain input event object for filterInputEvent.");
704 return true; // dispatch the event normally
705 }
706
707 // The callee is responsible for recycling the event.
708 jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
709 inputEventObj, policyFlags);
710 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
711 pass = true;
712 }
713 env->DeleteLocalRef(inputEventObj);
714 return pass;
715}
716
Jeff Brown1f245102010-11-18 20:53:46 -0800717void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
718 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700719 // Policy:
720 // - Ignore untrusted events and pass them along.
721 // - Ask the window manager what to do with normal events and trusted injected events.
722 // - For normal events wake and brighten the screen if currently off or dim.
723 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800724 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700725 bool isScreenOn = this->isScreenOn();
726 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700727
Jeff Brown3122e442010-10-11 23:32:49 -0700728 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800729 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
730 jint wmActions;
731 if (keyEventObj) {
732 wmActions = env->CallIntMethod(mCallbacksObj,
733 gCallbacksClassInfo.interceptKeyBeforeQueueing,
734 keyEventObj, policyFlags, isScreenOn);
735 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
736 wmActions = 0;
737 }
738 android_view_KeyEvent_recycle(env, keyEventObj);
739 env->DeleteLocalRef(keyEventObj);
740 } else {
741 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700742 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700743 }
744
Jeff Brown1f245102010-11-18 20:53:46 -0800745 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700746 if (!isScreenOn) {
747 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700748 }
749
750 if (!isScreenBright) {
751 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
752 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700753 }
754
Jeff Brown56194eb2011-03-02 19:23:13 -0800755 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700756 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700757 policyFlags |= POLICY_FLAG_PASS_TO_USER;
758 }
759}
760
Jeff Brown56194eb2011-03-02 19:23:13 -0800761void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700762 // Policy:
763 // - Ignore untrusted events and pass them along.
764 // - No special filtering for injected events required at this time.
765 // - Filter normal events based on screen state.
766 // - For normal events brighten (but do not wake) the screen if currently dim.
767 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
768 if (isScreenOn()) {
769 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700770
Jeff Brown3122e442010-10-11 23:32:49 -0700771 if (!isScreenBright()) {
772 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
773 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800774 } else {
775 JNIEnv* env = jniEnv();
776 jint wmActions = env->CallIntMethod(mCallbacksObj,
777 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
778 policyFlags);
779 if (checkAndClearExceptionFromCallback(env,
780 "interceptMotionBeforeQueueingWhenScreenOff")) {
781 wmActions = 0;
782 }
783
784 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
785 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700786 }
Jeff Brown3122e442010-10-11 23:32:49 -0700787 } else {
788 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700789 }
790}
791
Jeff Brown56194eb2011-03-02 19:23:13 -0800792void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
793 uint32_t& policyFlags) {
794 enum {
795 WM_ACTION_PASS_TO_USER = 1,
796 WM_ACTION_POKE_USER_ACTIVITY = 2,
797 WM_ACTION_GO_TO_SLEEP = 4,
798 };
799
800 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800801#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800802 LOGD("handleInterceptActions: Going to sleep.");
803#endif
804 android_server_PowerManagerService_goToSleep(when);
805 }
806
807 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800808#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800809 LOGD("handleInterceptActions: Poking user activity.");
810#endif
811 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
812 }
813
814 if (wmActions & WM_ACTION_PASS_TO_USER) {
815 policyFlags |= POLICY_FLAG_PASS_TO_USER;
816 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800817#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800818 LOGD("handleInterceptActions: Not passing key to user.");
819#endif
820 }
821}
822
Jeff Brown928e0542011-01-10 11:17:36 -0800823bool NativeInputManager::interceptKeyBeforeDispatching(
824 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700825 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700826 // Policy:
827 // - Ignore untrusted events and pass them along.
828 // - Filter normal events and trusted injected events through the window manager policy to
829 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800830 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700831 if (policyFlags & POLICY_FLAG_TRUSTED) {
832 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700833
Jeff Brown928e0542011-01-10 11:17:36 -0800834 // Note: inputWindowHandle may be null.
835 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800836 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
837 if (keyEventObj) {
838 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
839 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800840 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800841 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
842 android_view_KeyEvent_recycle(env, keyEventObj);
843 env->DeleteLocalRef(keyEventObj);
844 result = consumed && !error;
845 } else {
846 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800847 }
Jeff Brown928e0542011-01-10 11:17:36 -0800848 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700849 }
Jeff Brown1f245102010-11-18 20:53:46 -0800850 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700851}
852
Jeff Brown928e0542011-01-10 11:17:36 -0800853bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800854 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700855 // Policy:
856 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800857 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700858 if (policyFlags & POLICY_FLAG_TRUSTED) {
859 JNIEnv* env = jniEnv();
860
Jeff Brown928e0542011-01-10 11:17:36 -0800861 // Note: inputWindowHandle may be null.
862 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800863 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
864 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800865 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800866 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800867 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700868 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
869 fallbackKeyEventObj = NULL;
870 }
Jeff Brown1f245102010-11-18 20:53:46 -0800871 android_view_KeyEvent_recycle(env, keyEventObj);
872 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800873
874 if (fallbackKeyEventObj) {
875 // Note: outFallbackKeyEvent may be the same object as keyEvent.
876 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
877 outFallbackKeyEvent)) {
878 result = true;
879 }
880 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
881 env->DeleteLocalRef(fallbackKeyEventObj);
882 }
Jeff Brown1f245102010-11-18 20:53:46 -0800883 } else {
884 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800885 }
Jeff Brown928e0542011-01-10 11:17:36 -0800886 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700887 }
Jeff Brown1f245102010-11-18 20:53:46 -0800888 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700889}
890
Jeff Brown01ce2e92010-09-26 22:20:12 -0700891void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
892 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700893}
894
Jeff Brown349703e2010-06-22 01:27:15 -0700895
Jeff Brownb88102f2010-09-08 11:49:43 -0700896bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
897 int32_t injectorPid, int32_t injectorUid) {
898 JNIEnv* env = jniEnv();
899 jboolean result = env->CallBooleanMethod(mCallbacksObj,
900 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700901 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
902 result = false;
903 }
Jeff Brown349703e2010-06-22 01:27:15 -0700904 return result;
905}
906
Jeff Brown2352b972011-04-12 22:39:53 -0700907void NativeInputManager::loadPointerResources(PointerResources* outResources) {
908 JNIEnv* env = jniEnv();
909
910 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER,
911 &outResources->spotHover);
912 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH,
913 &outResources->spotTouch);
914 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR,
915 &outResources->spotAnchor);
916}
917
Jeff Brown83c09682010-12-23 17:50:18 -0800918
Jeff Brown9c3cda02010-06-15 01:31:58 -0700919// ----------------------------------------------------------------------------
920
921static sp<NativeInputManager> gNativeInputManager;
922
Jeff Brown46b9ac02010-04-22 18:58:52 -0700923static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700924 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700925 LOGE("Input manager not initialized.");
926 jniThrowRuntimeException(env, "Input manager not initialized.");
927 return true;
928 }
929 return false;
930}
931
932static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown2352b972011-04-12 22:39:53 -0700933 jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700934 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800935 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
Jeff Brown2352b972011-04-12 22:39:53 -0700936 gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700937 } else {
938 LOGE("Input manager already initialized.");
939 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700940 }
941}
942
943static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
944 if (checkInputManagerUnitialized(env)) {
945 return;
946 }
947
Jeff Brown9c3cda02010-06-15 01:31:58 -0700948 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700949 if (result) {
950 jniThrowRuntimeException(env, "Input manager could not be started.");
951 }
952}
953
954static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
955 jint displayId, jint width, jint height) {
956 if (checkInputManagerUnitialized(env)) {
957 return;
958 }
959
960 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
961 // to be passed in like this, not sure which is better but leaving it like this
962 // keeps the window manager in direct control of when display transitions propagate down
963 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700964 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700965}
966
967static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
968 jint displayId, jint orientation) {
969 if (checkInputManagerUnitialized(env)) {
970 return;
971 }
972
Jeff Brown9c3cda02010-06-15 01:31:58 -0700973 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700974}
975
976static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700977 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700978 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700979 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700980 }
981
Jeff Brownb88102f2010-09-08 11:49:43 -0700982 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700983 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700984}
985
986static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700987 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700988 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700989 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700990 }
991
Jeff Brownb88102f2010-09-08 11:49:43 -0700992 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700993 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700994}
995
996static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700997 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700998 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700999 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001000 }
1001
Jeff Brownb88102f2010-09-08 11:49:43 -07001002 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001003 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001004}
1005
1006static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001007 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001008 if (checkInputManagerUnitialized(env)) {
1009 return JNI_FALSE;
1010 }
1011
1012 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1013 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1014 jsize numCodes = env->GetArrayLength(keyCodes);
1015 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001016 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001017 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001018 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001019 } else {
1020 result = JNI_FALSE;
1021 }
1022
1023 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1024 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1025 return result;
1026}
1027
1028static void throwInputChannelNotInitialized(JNIEnv* env) {
1029 jniThrowException(env, "java/lang/IllegalStateException",
1030 "inputChannel is not initialized");
1031}
1032
1033static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1034 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1035 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1036 "the input manager!", inputChannel->getName().string());
1037
Jeff Brown9c3cda02010-06-15 01:31:58 -07001038 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001039 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001040 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001041}
1042
1043static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001044 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001045 if (checkInputManagerUnitialized(env)) {
1046 return;
1047 }
1048
1049 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1050 inputChannelObj);
1051 if (inputChannel == NULL) {
1052 throwInputChannelNotInitialized(env);
1053 return;
1054 }
1055
Jeff Brown928e0542011-01-10 11:17:36 -08001056 sp<InputWindowHandle> inputWindowHandle =
1057 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001058
1059 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001060 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001061 if (status) {
1062 jniThrowRuntimeException(env, "Failed to register input channel. "
1063 "Check logs for details.");
1064 return;
1065 }
1066
Jeff Browna41ca772010-08-11 14:46:32 -07001067 if (! monitor) {
1068 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1069 android_server_InputManager_handleInputChannelDisposed, NULL);
1070 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001071}
1072
1073static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1074 jobject inputChannelObj) {
1075 if (checkInputManagerUnitialized(env)) {
1076 return;
1077 }
1078
1079 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1080 inputChannelObj);
1081 if (inputChannel == NULL) {
1082 throwInputChannelNotInitialized(env);
1083 return;
1084 }
1085
1086 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1087
Jeff Brown7fbdc842010-06-17 20:52:56 -07001088 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001089 if (status) {
1090 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1091 "Check logs for details.");
1092 }
1093}
1094
Jeff Brown0029c662011-03-30 02:25:18 -07001095static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
1096 jboolean enabled) {
1097 if (checkInputManagerUnitialized(env)) {
1098 return;
1099 }
1100
1101 gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1102}
1103
Jeff Brown6ec402b2010-07-28 15:48:59 -07001104static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1105 jobject inputEventObj, jint injectorPid, jint injectorUid,
Jeff Brown0029c662011-03-30 02:25:18 -07001106 jint syncMode, jint timeoutMillis, jint policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001107 if (checkInputManagerUnitialized(env)) {
1108 return INPUT_EVENT_INJECTION_FAILED;
1109 }
1110
Jeff Brown6ec402b2010-07-28 15:48:59 -07001111 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1112 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001113 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1114 if (status) {
1115 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1116 return INPUT_EVENT_INJECTION_FAILED;
1117 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001118
Jeff Brownb88102f2010-09-08 11:49:43 -07001119 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001120 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1121 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001122 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001123 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1124 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001125 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1126 return INPUT_EVENT_INJECTION_FAILED;
1127 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001128
Jeff Brownb88102f2010-09-08 11:49:43 -07001129 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001130 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1131 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001132 } else {
1133 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001134 return INPUT_EVENT_INJECTION_FAILED;
1135 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001136}
1137
Jeff Brown349703e2010-06-22 01:27:15 -07001138static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
Jeff Brown9302c872011-07-13 22:51:29 -07001139 jobjectArray windowHandleObjArray) {
Jeff Brown349703e2010-06-22 01:27:15 -07001140 if (checkInputManagerUnitialized(env)) {
1141 return;
1142 }
1143
Jeff Brown9302c872011-07-13 22:51:29 -07001144 gNativeInputManager->setInputWindows(env, windowHandleObjArray);
Jeff Brown349703e2010-06-22 01:27:15 -07001145}
1146
1147static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
Jeff Brown9302c872011-07-13 22:51:29 -07001148 jobject applicationHandleObj) {
Jeff Brown349703e2010-06-22 01:27:15 -07001149 if (checkInputManagerUnitialized(env)) {
1150 return;
1151 }
1152
Jeff Brown9302c872011-07-13 22:51:29 -07001153 gNativeInputManager->setFocusedApplication(env, applicationHandleObj);
Jeff Brown349703e2010-06-22 01:27:15 -07001154}
1155
1156static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1157 jclass clazz, jboolean enabled, jboolean frozen) {
1158 if (checkInputManagerUnitialized(env)) {
1159 return;
1160 }
1161
1162 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1163}
1164
Jeff Brown05dc66a2011-03-02 14:41:58 -08001165static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1166 jclass clazz, jint visibility) {
1167 if (checkInputManagerUnitialized(env)) {
1168 return;
1169 }
1170
1171 gNativeInputManager->setSystemUiVisibility(visibility);
1172}
1173
Jeff Brown8d608662010-08-30 03:02:23 -07001174static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1175 jclass clazz, jint deviceId) {
1176 if (checkInputManagerUnitialized(env)) {
1177 return NULL;
1178 }
1179
1180 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001181 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001182 deviceId, & deviceInfo);
1183 if (status) {
1184 return NULL;
1185 }
1186
1187 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1188 if (! deviceObj) {
1189 return NULL;
1190 }
1191
1192 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1193 if (! deviceNameObj) {
1194 return NULL;
1195 }
1196
1197 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1198 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1199 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1200 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1201
Jeff Brownefd32662011-03-08 15:13:06 -08001202 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001203 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001204 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001205 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001206 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001207 if (env->ExceptionCheck()) {
1208 return NULL;
1209 }
1210 }
1211
1212 return deviceObj;
1213}
1214
1215static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1216 jclass clazz) {
1217 if (checkInputManagerUnitialized(env)) {
1218 return NULL;
1219 }
1220
1221 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001222 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001223
1224 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1225 if (! deviceIdsObj) {
1226 return NULL;
1227 }
1228
1229 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1230 return deviceIdsObj;
1231}
1232
Jeff Brown57c59372010-09-21 18:22:55 -07001233static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1234 jclass clazz, jobject configObj) {
1235 if (checkInputManagerUnitialized(env)) {
1236 return;
1237 }
1238
1239 InputConfiguration config;
1240 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1241
1242 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1243 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1244 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1245}
1246
Jeff Browne6504122010-09-27 14:52:15 -07001247static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1248 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1249 if (checkInputManagerUnitialized(env)) {
1250 return false;
1251 }
1252
1253 sp<InputChannel> fromChannel =
1254 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1255 sp<InputChannel> toChannel =
1256 android_view_InputChannel_getInputChannel(env, toChannelObj);
1257
1258 if (fromChannel == NULL || toChannel == NULL) {
1259 return false;
1260 }
1261
1262 return gNativeInputManager->getInputManager()->getDispatcher()->
1263 transferTouchFocus(fromChannel, toChannel);
1264}
1265
Jeff Brown1a84fd12011-06-02 01:26:32 -07001266static void android_server_InputManager_nativeSetPointerSpeed(JNIEnv* env,
1267 jclass clazz, jint speed) {
1268 if (checkInputManagerUnitialized(env)) {
1269 return;
1270 }
1271
1272 gNativeInputManager->setPointerSpeed(speed);
1273}
1274
Jeff Browne33348b2010-07-15 23:54:05 -07001275static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1276 if (checkInputManagerUnitialized(env)) {
1277 return NULL;
1278 }
1279
Jeff Brownb88102f2010-09-08 11:49:43 -07001280 String8 dump;
1281 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001282 return env->NewStringUTF(dump.string());
1283}
1284
Jeff Brown9c3cda02010-06-15 01:31:58 -07001285// ----------------------------------------------------------------------------
1286
Jeff Brown46b9ac02010-04-22 18:58:52 -07001287static JNINativeMethod gInputManagerMethods[] = {
1288 /* name, signature, funcPtr */
Jeff Brown2352b972011-04-12 22:39:53 -07001289 { "nativeInit", "(Landroid/content/Context;"
1290 "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001291 (void*) android_server_InputManager_nativeInit },
1292 { "nativeStart", "()V",
1293 (void*) android_server_InputManager_nativeStart },
1294 { "nativeSetDisplaySize", "(III)V",
1295 (void*) android_server_InputManager_nativeSetDisplaySize },
1296 { "nativeSetDisplayOrientation", "(II)V",
1297 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1298 { "nativeGetScanCodeState", "(III)I",
1299 (void*) android_server_InputManager_nativeGetScanCodeState },
1300 { "nativeGetKeyCodeState", "(III)I",
1301 (void*) android_server_InputManager_nativeGetKeyCodeState },
1302 { "nativeGetSwitchState", "(III)I",
1303 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001304 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001305 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001306 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001307 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001308 (void*) android_server_InputManager_nativeRegisterInputChannel },
1309 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001310 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown0029c662011-03-30 02:25:18 -07001311 { "nativeSetInputFilterEnabled", "(Z)V",
1312 (void*) android_server_InputManager_nativeSetInputFilterEnabled },
1313 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
Jeff Brown6ec402b2010-07-28 15:48:59 -07001314 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown9302c872011-07-13 22:51:29 -07001315 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindowHandle;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001316 (void*) android_server_InputManager_nativeSetInputWindows },
Jeff Brown9302c872011-07-13 22:51:29 -07001317 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplicationHandle;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001318 (void*) android_server_InputManager_nativeSetFocusedApplication },
1319 { "nativeSetInputDispatchMode", "(ZZ)V",
1320 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001321 { "nativeSetSystemUiVisibility", "(I)V",
1322 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001323 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1324 (void*) android_server_InputManager_nativeGetInputDevice },
1325 { "nativeGetInputDeviceIds", "()[I",
1326 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001327 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1328 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001329 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1330 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Brown1a84fd12011-06-02 01:26:32 -07001331 { "nativeSetPointerSpeed", "(I)V",
1332 (void*) android_server_InputManager_nativeSetPointerSpeed },
Jeff Browne33348b2010-07-15 23:54:05 -07001333 { "nativeDump", "()Ljava/lang/String;",
1334 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001335};
1336
1337#define FIND_CLASS(var, className) \
1338 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001339 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001340
1341#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1342 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1343 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1344
1345#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1346 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1347 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1348
1349int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001350 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001351 gInputManagerMethods, NELEM(gInputManagerMethods));
1352 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1353
Jeff Brown9c3cda02010-06-15 01:31:58 -07001354 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001355
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001356 jclass clazz;
1357 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001358
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001359 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001360 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001361
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001362 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001363 "notifyLidSwitchChanged", "(JZ)V");
1364
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001365 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001366 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001367
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001368 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001369 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001370 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001371
Jeff Brown0029c662011-03-30 02:25:18 -07001372 GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
1373 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1374
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001375 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001376 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001377
Jeff Brown56194eb2011-03-02 19:23:13 -08001378 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001379 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001380 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1381
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001382 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001383 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001384 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001385
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001386 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001387 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001388 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001389
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001390 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001391 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001392
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001393 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001394 "getVirtualKeyQuietTimeMillis", "()I");
1395
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001396 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001397 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1398
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001399 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001400 "getKeyRepeatTimeout", "()I");
1401
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001402 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001403 "getKeyRepeatDelay", "()I");
1404
Jeff Brown774ed9d2011-06-07 17:48:39 -07001405 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapTimeout, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001406 "getHoverTapTimeout", "()I");
1407
Jeff Brown774ed9d2011-06-07 17:48:39 -07001408 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapSlop, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001409 "getHoverTapSlop", "()I");
Jeff Brown214eaf42011-05-26 19:17:02 -07001410
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001411 GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001412 "getDoubleTapTimeout", "()I");
1413
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001414 GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001415 "getLongPressTimeout", "()I");
1416
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001417 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001418 "getMaxEventsPerSecond", "()I");
1419
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001420 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001421 "getPointerLayer", "()I");
1422
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001423 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Jeff Brown2352b972011-04-12 22:39:53 -07001424 "getPointerIcon", "()Landroid/view/PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001425
Jeff Brown6ec402b2010-07-28 15:48:59 -07001426 // KeyEvent
1427
1428 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001429 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1430
Jeff Brown6ec402b2010-07-28 15:48:59 -07001431
Jeff Brown8d608662010-08-30 03:02:23 -07001432 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001433
1434 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001435 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001436
Jeff Brown8d608662010-08-30 03:02:23 -07001437 // InputDevice
1438
1439 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001440 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001441
1442 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1443 "<init>", "()V");
1444
1445 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001446 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001447
1448 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1449 "mId", "I");
1450
1451 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1452 "mName", "Ljava/lang/String;");
1453
1454 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1455 "mSources", "I");
1456
1457 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1458 "mKeyboardType", "I");
1459
Jeff Brown57c59372010-09-21 18:22:55 -07001460 // Configuration
1461
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001462 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001463
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001464 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001465 "touchscreen", "I");
1466
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001467 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001468 "keyboard", "I");
1469
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001470 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001471 "navigation", "I");
1472
Jeff Brown46b9ac02010-04-22 18:58:52 -07001473 return 0;
1474}
1475
Jeff Brown46b9ac02010-04-22 18:58:52 -07001476} /* namespace android */