blob: 7c5084fda65064c96929a9a5eef0e429deebf2db [file] [log] [blame]
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputManager-JNI"
18
Jeff Brown9c3cda02010-06-15 01:31:58 -070019//#define LOG_NDEBUG 0
20
21// Log debug messages about InputReaderPolicy
Jeff Brown349703e2010-06-22 01:27:15 -070022#define DEBUG_INPUT_READER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070023
24// Log debug messages about InputDispatcherPolicy
Jeff Brown349703e2010-06-22 01:27:15 -070025#define DEBUG_INPUT_DISPATCHER_POLICY 0
Jeff Brown9c3cda02010-06-15 01:31:58 -070026
Jeff Brown83c09682010-12-23 17:50:18 -080027
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070028#include "JNIHelp.h"
29#include "jni.h"
Jeff Brown349703e2010-06-22 01:27:15 -070030#include <limits.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070031#include <android_runtime/AndroidRuntime.h>
Jeff Brownb4ff35d2011-01-02 16:37:43 -080032
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070033#include <utils/Log.h>
Jeff Brown05dc66a2011-03-02 14:41:58 -080034#include <utils/Looper.h>
Jeff Brown46b9ac0a2010-04-22 18:58:52 -070035#include <utils/threads.h>
Jeff Brown83c09682010-12-23 17:50:18 -080036
Jeff Brownb4ff35d2011-01-02 16:37:43 -080037#include <input/InputManager.h>
38#include <input/PointerController.h>
Jeff 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 Brown46b9ac0a2010-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 Brown46b9ac0a2010-04-22 18:58:52 -070061static struct {
Jeff Brown46b9ac0a2010-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 Brown46b9ac0a2010-04-22 18:58:52 -070072 jmethodID filterTouchEvents;
73 jmethodID filterJumpyTouchEvents;
Jeff Brownfe508922011-01-18 15:10:10 -080074 jmethodID getVirtualKeyQuietTimeMillis;
Jeff Brown46b9ac0a2010-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 Brown46b9ac0a2010-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 Brown5541de92011-04-11 11:54:25 -0700237 // Sprite controller singleton, created on first use.
238 sp<SpriteController> spriteController;
239
Jeff Brown83c09682010-12-23 17:50:18 -0800240 // Pointer controller singleton, created and destroyed as needed.
241 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800242 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700243
Jeff Brown2352b972011-04-12 22:39:53 -0700244 void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800245 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown5541de92011-04-11 11:54:25 -0700246 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800247
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700248 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700249 bool isScreenOn();
250 bool isScreenBright();
251
Jeff Brownb88102f2010-09-08 11:49:43 -0700252 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700253
Jeff Brown9c3cda02010-06-15 01:31:58 -0700254 static inline JNIEnv* jniEnv() {
255 return AndroidRuntime::getJNIEnv();
256 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700257};
258
Jeff Brown928e0542011-01-10 11:17:36 -0800259
Jeff Brown9c3cda02010-06-15 01:31:58 -0700260
Jeff Brown2352b972011-04-12 22:39:53 -0700261NativeInputManager::NativeInputManager(jobject contextObj,
262 jobject callbacksObj, const sp<Looper>& looper) :
Jeff Brown214eaf42011-05-26 19:17:02 -0700263 mLooper(looper) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700264 JNIEnv* env = jniEnv();
265
Jeff Brown2352b972011-04-12 22:39:53 -0700266 mContextObj = env->NewGlobalRef(contextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700267 mCallbacksObj = env->NewGlobalRef(callbacksObj);
268
Jeff Brown83c09682010-12-23 17:50:18 -0800269 {
270 AutoMutex _l(mLock);
271 mLocked.displayWidth = -1;
272 mLocked.displayHeight = -1;
273 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800274
275 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700276 mLocked.pointerSpeed = 0;
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 jboolean filterTouchEvents = env->CallBooleanMethod(mCallbacksObj,
381 gCallbacksClassInfo.filterTouchEvents);
382 if (!checkAndClearExceptionFromCallback(env, "filterTouchEvents")) {
383 outConfig->filterTouchEvents = filterTouchEvents;
384 }
385
386 jboolean filterJumpyTouchEvents = env->CallBooleanMethod(mCallbacksObj,
387 gCallbacksClassInfo.filterJumpyTouchEvents);
388 if (!checkAndClearExceptionFromCallback(env, "filterJumpyTouchEvents")) {
389 outConfig->filterJumpyTouchEvents = filterJumpyTouchEvents;
390 }
391
392 jint virtualKeyQuietTime = env->CallIntMethod(mCallbacksObj,
393 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
394 if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
395 outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
396 }
397
398 outConfig->excludedDeviceNames.clear();
399 jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mCallbacksObj,
Jeff Brown9c3cda02010-06-15 01:31:58 -0700400 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown214eaf42011-05-26 19:17:02 -0700401 if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
402 jsize length = env->GetArrayLength(excludedDeviceNames);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700403 for (jsize i = 0; i < length; i++) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700404 jstring item = jstring(env->GetObjectArrayElement(excludedDeviceNames, i));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700405 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
Jeff Brown214eaf42011-05-26 19:17:02 -0700406 outConfig->excludedDeviceNames.add(String8(deviceNameChars));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700407 env->ReleaseStringUTFChars(item, deviceNameChars);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700408 env->DeleteLocalRef(item);
409 }
Jeff Brown214eaf42011-05-26 19:17:02 -0700410 env->DeleteLocalRef(excludedDeviceNames);
411 }
412
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700413 jint hoverTapTimeout = env->CallIntMethod(mCallbacksObj,
414 gCallbacksClassInfo.getHoverTapTimeout);
415 if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700416 jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
417 gCallbacksClassInfo.getDoubleTapTimeout);
418 if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
419 jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
420 gCallbacksClassInfo.getLongPressTimeout);
421 if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700422 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700423
424 // We must ensure that the tap-drag interval is significantly shorter than
425 // the long-press timeout because the tap is held down for the entire duration
426 // of the double-tap timeout.
427 jint tapDragInterval = max(min(longPressTimeout - 100,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700428 doubleTapTimeout), hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700429 outConfig->pointerGestureTapDragInterval =
430 milliseconds_to_nanoseconds(tapDragInterval);
431 }
432 }
433 }
434
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700435 jint hoverTapSlop = env->CallIntMethod(mCallbacksObj,
436 gCallbacksClassInfo.getHoverTapSlop);
437 if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
438 outConfig->pointerGestureTapSlop = hoverTapSlop;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700439 }
Jeff Brown1a84fd12011-06-02 01:26:32 -0700440
441 { // acquire lock
442 AutoMutex _l(mLock);
443
444 outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
445 * POINTER_SPEED_EXPONENT);
446 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700447}
448
Jeff Brown83c09682010-12-23 17:50:18 -0800449sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
450 AutoMutex _l(mLock);
451
452 sp<PointerController> controller = mLocked.pointerController.promote();
453 if (controller == NULL) {
Jeff Brown5541de92011-04-11 11:54:25 -0700454 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800455
Jeff Brown2352b972011-04-12 22:39:53 -0700456 controller = new PointerController(this, mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800457 mLocked.pointerController = controller;
458
459 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
460 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800461
Jeff Brown5541de92011-04-11 11:54:25 -0700462 JNIEnv* env = jniEnv();
Jeff Brown2352b972011-04-12 22:39:53 -0700463 jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
464 gCallbacksClassInfo.getPointerIcon);
465 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
466 PointerIcon pointerIcon;
467 status_t status = android_view_PointerIcon_load(env, pointerIconObj,
468 mContextObj, &pointerIcon);
469 if (!status && !pointerIcon.isNullIcon()) {
470 controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
471 pointerIcon.hotSpotX, pointerIcon.hotSpotY));
472 } else {
473 controller->setPointerIcon(SpriteIcon());
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800474 }
Jeff Brown2352b972011-04-12 22:39:53 -0700475 env->DeleteLocalRef(pointerIconObj);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800476 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800477
Jeff Brown2352b972011-04-12 22:39:53 -0700478 updateInactivityTimeoutLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800479 }
480 return controller;
481}
482
Jeff Brown5541de92011-04-11 11:54:25 -0700483void NativeInputManager::ensureSpriteControllerLocked() {
484 if (mLocked.spriteController == NULL) {
485 JNIEnv* env = jniEnv();
486 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
487 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
488 layer = -1;
489 }
490 mLocked.spriteController = new SpriteController(mLooper, layer);
491 }
492}
493
Jeff Browne20c9e02010-10-11 14:20:19 -0700494void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
495 int32_t switchValue, uint32_t policyFlags) {
496#if DEBUG_INPUT_DISPATCHER_POLICY
497 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
498 when, switchCode, switchValue, policyFlags);
499#endif
500
501 JNIEnv* env = jniEnv();
502
503 switch (switchCode) {
504 case SW_LID:
505 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
506 when, switchValue == 0);
507 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
508 break;
509 }
510}
511
Jeff Brown9c3cda02010-06-15 01:31:58 -0700512void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
513#if DEBUG_INPUT_DISPATCHER_POLICY
514 LOGD("notifyConfigurationChanged - when=%lld", when);
515#endif
516
517 JNIEnv* env = jniEnv();
518
Jeff Brown57c59372010-09-21 18:22:55 -0700519 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700520 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700521}
522
Jeff Brown519e0242010-09-15 15:18:56 -0700523nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800524 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700525#if DEBUG_INPUT_DISPATCHER_POLICY
526 LOGD("notifyANR");
527#endif
528
529 JNIEnv* env = jniEnv();
530
Jeff Brown928e0542011-01-10 11:17:36 -0800531 jobject inputApplicationHandleObj =
532 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
533 jobject inputWindowHandleObj =
534 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700535
Jeff Brown519e0242010-09-15 15:18:56 -0700536 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800537 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700538 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
539 newTimeout = 0; // abort dispatch
540 } else {
541 assert(newTimeout >= 0);
542 }
543
Jeff Brown928e0542011-01-10 11:17:36 -0800544 env->DeleteLocalRef(inputWindowHandleObj);
545 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700546 return newTimeout;
547}
548
Jeff Brown928e0542011-01-10 11:17:36 -0800549void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700550#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800551 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700552#endif
553
Jeff Brown7fbdc842010-06-17 20:52:56 -0700554 JNIEnv* env = jniEnv();
555
Jeff Brown928e0542011-01-10 11:17:36 -0800556 jobject inputWindowHandleObj =
557 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
558 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700559 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800560 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700561 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
562
Jeff Brown928e0542011-01-10 11:17:36 -0800563 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700564 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700565}
566
Jeff Brown214eaf42011-05-26 19:17:02 -0700567void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
568 JNIEnv* env = jniEnv();
Jeff Browna4547672011-03-02 21:38:11 -0800569
Jeff Brown214eaf42011-05-26 19:17:02 -0700570 jint keyRepeatTimeout = env->CallIntMethod(mCallbacksObj,
571 gCallbacksClassInfo.getKeyRepeatTimeout);
572 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
573 outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
574 }
Jeff Browna4547672011-03-02 21:38:11 -0800575
Jeff Brown214eaf42011-05-26 19:17:02 -0700576 jint keyRepeatDelay = env->CallIntMethod(mCallbacksObj,
577 gCallbacksClassInfo.getKeyRepeatDelay);
578 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
579 outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
580 }
581
582 jint maxEventsPerSecond = env->CallIntMethod(mCallbacksObj,
583 gCallbacksClassInfo.getMaxEventsPerSecond);
584 if (!checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
585 outConfig->maxEventsPerSecond = maxEventsPerSecond;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700586 }
587}
588
Jeff Brown214eaf42011-05-26 19:17:02 -0700589bool NativeInputManager::isKeyRepeatEnabled() {
590 // Only enable automatic key repeating when the screen is on.
591 return isScreenOn();
Jeff Brownae9fc032010-08-18 15:51:08 -0700592}
593
Jeff Brown349703e2010-06-22 01:27:15 -0700594void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700595 Vector<InputWindow> windows;
Jeff Brown349703e2010-06-22 01:27:15 -0700596
Jeff Brownb88102f2010-09-08 11:49:43 -0700597 jsize length = env->GetArrayLength(windowObjArray);
598 for (jsize i = 0; i < length; i++) {
Jeff Brown928e0542011-01-10 11:17:36 -0800599 jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
600 if (! windowObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700601 break; // found null element indicating end of used portion of the array
Jeff Brown349703e2010-06-22 01:27:15 -0700602 }
603
Jeff Brownb88102f2010-09-08 11:49:43 -0700604 windows.push();
605 InputWindow& window = windows.editTop();
Jeff Brown928e0542011-01-10 11:17:36 -0800606 android_server_InputWindow_toNative(env, windowObj, &window);
607 if (window.inputChannel == NULL) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700608 windows.pop();
Jeff Brown349703e2010-06-22 01:27:15 -0700609 }
Jeff Brown928e0542011-01-10 11:17:36 -0800610 env->DeleteLocalRef(windowObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700611 }
Jeff Brown349703e2010-06-22 01:27:15 -0700612
Jeff Brownb88102f2010-09-08 11:49:43 -0700613 mInputManager->getDispatcher()->setInputWindows(windows);
Jeff Brown349703e2010-06-22 01:27:15 -0700614}
615
Jeff Brown349703e2010-06-22 01:27:15 -0700616void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700617 if (applicationObj) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700618 InputApplication application;
Jeff Brown928e0542011-01-10 11:17:36 -0800619 android_server_InputApplication_toNative(env, applicationObj, &application);
620 if (application.inputApplicationHandle != NULL) {
621 mInputManager->getDispatcher()->setFocusedApplication(&application);
Jeff Browna2cc28d2011-03-25 11:58:46 -0700622 return;
Jeff Brown928e0542011-01-10 11:17:36 -0800623 }
Jeff Brown349703e2010-06-22 01:27:15 -0700624 }
Jeff Brown928e0542011-01-10 11:17:36 -0800625 mInputManager->getDispatcher()->setFocusedApplication(NULL);
Jeff Brown349703e2010-06-22 01:27:15 -0700626}
627
628void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700629 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700630}
631
Jeff Brown05dc66a2011-03-02 14:41:58 -0800632void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
633 AutoMutex _l(mLock);
634
635 if (mLocked.systemUiVisibility != visibility) {
636 mLocked.systemUiVisibility = visibility;
637
638 sp<PointerController> controller = mLocked.pointerController.promote();
639 if (controller != NULL) {
Jeff Brown2352b972011-04-12 22:39:53 -0700640 updateInactivityTimeoutLocked(controller);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800641 }
642 }
643}
644
Jeff Brown2352b972011-04-12 22:39:53 -0700645void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800646 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
Jeff Brown2352b972011-04-12 22:39:53 -0700647 controller->setInactivityTimeout(lightsOut
648 ? PointerController::INACTIVITY_TIMEOUT_SHORT
649 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800650}
651
Jeff Brown1a84fd12011-06-02 01:26:32 -0700652void NativeInputManager::setPointerSpeed(int32_t speed) {
653 AutoMutex _l(mLock);
654
655 if (mLocked.pointerSpeed != speed) {
656 LOGI("Setting pointer speed to %d.", speed);
657 mLocked.pointerSpeed = speed;
658
659 mInputManager->getReader()->refreshConfiguration();
660 }
661}
662
Jeff Browne20c9e02010-10-11 14:20:19 -0700663bool NativeInputManager::isScreenOn() {
664 return android_server_PowerManagerService_isScreenOn();
665}
666
667bool NativeInputManager::isScreenBright() {
668 return android_server_PowerManagerService_isScreenBright();
669}
670
Jeff Brown0029c662011-03-30 02:25:18 -0700671bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
672 jobject inputEventObj;
673
674 JNIEnv* env = jniEnv();
675 switch (inputEvent->getType()) {
676 case AINPUT_EVENT_TYPE_KEY:
677 inputEventObj = android_view_KeyEvent_fromNative(env,
678 static_cast<const KeyEvent*>(inputEvent));
679 break;
680 case AINPUT_EVENT_TYPE_MOTION:
681 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
682 static_cast<const MotionEvent*>(inputEvent));
683 break;
684 default:
685 return true; // dispatch the event normally
686 }
687
688 if (!inputEventObj) {
689 LOGE("Failed to obtain input event object for filterInputEvent.");
690 return true; // dispatch the event normally
691 }
692
693 // The callee is responsible for recycling the event.
694 jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
695 inputEventObj, policyFlags);
696 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
697 pass = true;
698 }
699 env->DeleteLocalRef(inputEventObj);
700 return pass;
701}
702
Jeff Brown1f245102010-11-18 20:53:46 -0800703void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
704 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700705 // Policy:
706 // - Ignore untrusted events and pass them along.
707 // - Ask the window manager what to do with normal events and trusted injected events.
708 // - For normal events wake and brighten the screen if currently off or dim.
709 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800710 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700711 bool isScreenOn = this->isScreenOn();
712 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700713
Jeff Brown3122e442010-10-11 23:32:49 -0700714 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800715 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
716 jint wmActions;
717 if (keyEventObj) {
718 wmActions = env->CallIntMethod(mCallbacksObj,
719 gCallbacksClassInfo.interceptKeyBeforeQueueing,
720 keyEventObj, policyFlags, isScreenOn);
721 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
722 wmActions = 0;
723 }
724 android_view_KeyEvent_recycle(env, keyEventObj);
725 env->DeleteLocalRef(keyEventObj);
726 } else {
727 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700728 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700729 }
730
Jeff Brown1f245102010-11-18 20:53:46 -0800731 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700732 if (!isScreenOn) {
733 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700734 }
735
736 if (!isScreenBright) {
737 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
738 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700739 }
740
Jeff Brown56194eb2011-03-02 19:23:13 -0800741 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700742 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700743 policyFlags |= POLICY_FLAG_PASS_TO_USER;
744 }
745}
746
Jeff Brown56194eb2011-03-02 19:23:13 -0800747void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700748 // Policy:
749 // - Ignore untrusted events and pass them along.
750 // - No special filtering for injected events required at this time.
751 // - Filter normal events based on screen state.
752 // - For normal events brighten (but do not wake) the screen if currently dim.
753 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
754 if (isScreenOn()) {
755 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700756
Jeff Brown3122e442010-10-11 23:32:49 -0700757 if (!isScreenBright()) {
758 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
759 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800760 } else {
761 JNIEnv* env = jniEnv();
762 jint wmActions = env->CallIntMethod(mCallbacksObj,
763 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
764 policyFlags);
765 if (checkAndClearExceptionFromCallback(env,
766 "interceptMotionBeforeQueueingWhenScreenOff")) {
767 wmActions = 0;
768 }
769
770 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
771 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700772 }
Jeff Brown3122e442010-10-11 23:32:49 -0700773 } else {
774 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700775 }
776}
777
Jeff Brown56194eb2011-03-02 19:23:13 -0800778void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
779 uint32_t& policyFlags) {
780 enum {
781 WM_ACTION_PASS_TO_USER = 1,
782 WM_ACTION_POKE_USER_ACTIVITY = 2,
783 WM_ACTION_GO_TO_SLEEP = 4,
784 };
785
786 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800787#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800788 LOGD("handleInterceptActions: Going to sleep.");
789#endif
790 android_server_PowerManagerService_goToSleep(when);
791 }
792
793 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800794#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800795 LOGD("handleInterceptActions: Poking user activity.");
796#endif
797 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
798 }
799
800 if (wmActions & WM_ACTION_PASS_TO_USER) {
801 policyFlags |= POLICY_FLAG_PASS_TO_USER;
802 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800803#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800804 LOGD("handleInterceptActions: Not passing key to user.");
805#endif
806 }
807}
808
Jeff Brown928e0542011-01-10 11:17:36 -0800809bool NativeInputManager::interceptKeyBeforeDispatching(
810 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700811 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700812 // Policy:
813 // - Ignore untrusted events and pass them along.
814 // - Filter normal events and trusted injected events through the window manager policy to
815 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800816 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700817 if (policyFlags & POLICY_FLAG_TRUSTED) {
818 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700819
Jeff Brown928e0542011-01-10 11:17:36 -0800820 // Note: inputWindowHandle may be null.
821 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800822 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
823 if (keyEventObj) {
824 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
825 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800826 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800827 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
828 android_view_KeyEvent_recycle(env, keyEventObj);
829 env->DeleteLocalRef(keyEventObj);
830 result = consumed && !error;
831 } else {
832 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800833 }
Jeff Brown928e0542011-01-10 11:17:36 -0800834 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700835 }
Jeff Brown1f245102010-11-18 20:53:46 -0800836 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700837}
838
Jeff Brown928e0542011-01-10 11:17:36 -0800839bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800840 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700841 // Policy:
842 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800843 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700844 if (policyFlags & POLICY_FLAG_TRUSTED) {
845 JNIEnv* env = jniEnv();
846
Jeff Brown928e0542011-01-10 11:17:36 -0800847 // Note: inputWindowHandle may be null.
848 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800849 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
850 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800851 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800852 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800853 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700854 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
855 fallbackKeyEventObj = NULL;
856 }
Jeff Brown1f245102010-11-18 20:53:46 -0800857 android_view_KeyEvent_recycle(env, keyEventObj);
858 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800859
860 if (fallbackKeyEventObj) {
861 // Note: outFallbackKeyEvent may be the same object as keyEvent.
862 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
863 outFallbackKeyEvent)) {
864 result = true;
865 }
866 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
867 env->DeleteLocalRef(fallbackKeyEventObj);
868 }
Jeff Brown1f245102010-11-18 20:53:46 -0800869 } else {
870 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800871 }
Jeff Brown928e0542011-01-10 11:17:36 -0800872 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700873 }
Jeff Brown1f245102010-11-18 20:53:46 -0800874 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700875}
876
Jeff Brown01ce2e92010-09-26 22:20:12 -0700877void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
878 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700879}
880
Jeff Brown349703e2010-06-22 01:27:15 -0700881
Jeff Brownb88102f2010-09-08 11:49:43 -0700882bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
883 int32_t injectorPid, int32_t injectorUid) {
884 JNIEnv* env = jniEnv();
885 jboolean result = env->CallBooleanMethod(mCallbacksObj,
886 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700887 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
888 result = false;
889 }
Jeff Brown349703e2010-06-22 01:27:15 -0700890 return result;
891}
892
Jeff Brown2352b972011-04-12 22:39:53 -0700893void NativeInputManager::loadPointerResources(PointerResources* outResources) {
894 JNIEnv* env = jniEnv();
895
896 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER,
897 &outResources->spotHover);
898 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH,
899 &outResources->spotTouch);
900 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR,
901 &outResources->spotAnchor);
902}
903
Jeff Brown83c09682010-12-23 17:50:18 -0800904
Jeff Brown9c3cda02010-06-15 01:31:58 -0700905// ----------------------------------------------------------------------------
906
907static sp<NativeInputManager> gNativeInputManager;
908
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700909static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700910 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700911 LOGE("Input manager not initialized.");
912 jniThrowRuntimeException(env, "Input manager not initialized.");
913 return true;
914 }
915 return false;
916}
917
918static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown2352b972011-04-12 22:39:53 -0700919 jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700920 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800921 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
Jeff Brown2352b972011-04-12 22:39:53 -0700922 gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700923 } else {
924 LOGE("Input manager already initialized.");
925 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700926 }
927}
928
929static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
930 if (checkInputManagerUnitialized(env)) {
931 return;
932 }
933
Jeff Brown9c3cda02010-06-15 01:31:58 -0700934 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700935 if (result) {
936 jniThrowRuntimeException(env, "Input manager could not be started.");
937 }
938}
939
940static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
941 jint displayId, jint width, jint height) {
942 if (checkInputManagerUnitialized(env)) {
943 return;
944 }
945
946 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
947 // to be passed in like this, not sure which is better but leaving it like this
948 // keeps the window manager in direct control of when display transitions propagate down
949 // to the input dispatcher
Jeff Brown9c3cda02010-06-15 01:31:58 -0700950 gNativeInputManager->setDisplaySize(displayId, width, height);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700951}
952
953static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
954 jint displayId, jint orientation) {
955 if (checkInputManagerUnitialized(env)) {
956 return;
957 }
958
Jeff Brown9c3cda02010-06-15 01:31:58 -0700959 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700960}
961
962static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700963 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700964 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700965 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700966 }
967
Jeff Brownb88102f2010-09-08 11:49:43 -0700968 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700969 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700970}
971
972static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700973 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700974 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700975 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700976 }
977
Jeff Brownb88102f2010-09-08 11:49:43 -0700978 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700979 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700980}
981
982static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700983 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700984 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700985 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700986 }
987
Jeff Brownb88102f2010-09-08 11:49:43 -0700988 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700989 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700990}
991
992static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700993 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -0700994 if (checkInputManagerUnitialized(env)) {
995 return JNI_FALSE;
996 }
997
998 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
999 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1000 jsize numCodes = env->GetArrayLength(keyCodes);
1001 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001002 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001003 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001004 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001005 } else {
1006 result = JNI_FALSE;
1007 }
1008
1009 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1010 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1011 return result;
1012}
1013
1014static void throwInputChannelNotInitialized(JNIEnv* env) {
1015 jniThrowException(env, "java/lang/IllegalStateException",
1016 "inputChannel is not initialized");
1017}
1018
1019static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1020 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1021 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1022 "the input manager!", inputChannel->getName().string());
1023
Jeff Brown9c3cda02010-06-15 01:31:58 -07001024 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001025 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001026 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001027}
1028
1029static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001030 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001031 if (checkInputManagerUnitialized(env)) {
1032 return;
1033 }
1034
1035 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1036 inputChannelObj);
1037 if (inputChannel == NULL) {
1038 throwInputChannelNotInitialized(env);
1039 return;
1040 }
1041
Jeff Brown928e0542011-01-10 11:17:36 -08001042 sp<InputWindowHandle> inputWindowHandle =
1043 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001044
1045 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001046 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001047 if (status) {
1048 jniThrowRuntimeException(env, "Failed to register input channel. "
1049 "Check logs for details.");
1050 return;
1051 }
1052
Jeff Browna41ca772010-08-11 14:46:32 -07001053 if (! monitor) {
1054 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1055 android_server_InputManager_handleInputChannelDisposed, NULL);
1056 }
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001057}
1058
1059static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1060 jobject inputChannelObj) {
1061 if (checkInputManagerUnitialized(env)) {
1062 return;
1063 }
1064
1065 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1066 inputChannelObj);
1067 if (inputChannel == NULL) {
1068 throwInputChannelNotInitialized(env);
1069 return;
1070 }
1071
1072 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1073
Jeff Brown7fbdc842010-06-17 20:52:56 -07001074 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001075 if (status) {
1076 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1077 "Check logs for details.");
1078 }
1079}
1080
Jeff Brown0029c662011-03-30 02:25:18 -07001081static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
1082 jboolean enabled) {
1083 if (checkInputManagerUnitialized(env)) {
1084 return;
1085 }
1086
1087 gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1088}
1089
Jeff Brown6ec402b2010-07-28 15:48:59 -07001090static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1091 jobject inputEventObj, jint injectorPid, jint injectorUid,
Jeff Brown0029c662011-03-30 02:25:18 -07001092 jint syncMode, jint timeoutMillis, jint policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001093 if (checkInputManagerUnitialized(env)) {
1094 return INPUT_EVENT_INJECTION_FAILED;
1095 }
1096
Jeff Brown6ec402b2010-07-28 15:48:59 -07001097 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1098 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001099 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1100 if (status) {
1101 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1102 return INPUT_EVENT_INJECTION_FAILED;
1103 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001104
Jeff Brownb88102f2010-09-08 11:49:43 -07001105 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001106 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1107 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001108 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001109 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1110 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001111 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1112 return INPUT_EVENT_INJECTION_FAILED;
1113 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001114
Jeff Brownb88102f2010-09-08 11:49:43 -07001115 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001116 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1117 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001118 } else {
1119 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001120 return INPUT_EVENT_INJECTION_FAILED;
1121 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001122}
1123
Jeff Brown349703e2010-06-22 01:27:15 -07001124static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
1125 jobjectArray windowObjArray) {
1126 if (checkInputManagerUnitialized(env)) {
1127 return;
1128 }
1129
1130 gNativeInputManager->setInputWindows(env, windowObjArray);
1131}
1132
1133static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
1134 jobject applicationObj) {
1135 if (checkInputManagerUnitialized(env)) {
1136 return;
1137 }
1138
1139 gNativeInputManager->setFocusedApplication(env, applicationObj);
1140}
1141
1142static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1143 jclass clazz, jboolean enabled, jboolean frozen) {
1144 if (checkInputManagerUnitialized(env)) {
1145 return;
1146 }
1147
1148 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1149}
1150
Jeff Brown05dc66a2011-03-02 14:41:58 -08001151static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1152 jclass clazz, jint visibility) {
1153 if (checkInputManagerUnitialized(env)) {
1154 return;
1155 }
1156
1157 gNativeInputManager->setSystemUiVisibility(visibility);
1158}
1159
Jeff Brown8d608662010-08-30 03:02:23 -07001160static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1161 jclass clazz, jint deviceId) {
1162 if (checkInputManagerUnitialized(env)) {
1163 return NULL;
1164 }
1165
1166 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001167 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001168 deviceId, & deviceInfo);
1169 if (status) {
1170 return NULL;
1171 }
1172
1173 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1174 if (! deviceObj) {
1175 return NULL;
1176 }
1177
1178 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1179 if (! deviceNameObj) {
1180 return NULL;
1181 }
1182
1183 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1184 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1185 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1186 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1187
Jeff Brownefd32662011-03-08 15:13:06 -08001188 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001189 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001190 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001191 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001192 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001193 if (env->ExceptionCheck()) {
1194 return NULL;
1195 }
1196 }
1197
1198 return deviceObj;
1199}
1200
1201static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1202 jclass clazz) {
1203 if (checkInputManagerUnitialized(env)) {
1204 return NULL;
1205 }
1206
1207 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001208 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001209
1210 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1211 if (! deviceIdsObj) {
1212 return NULL;
1213 }
1214
1215 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1216 return deviceIdsObj;
1217}
1218
Jeff Brown57c59372010-09-21 18:22:55 -07001219static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1220 jclass clazz, jobject configObj) {
1221 if (checkInputManagerUnitialized(env)) {
1222 return;
1223 }
1224
1225 InputConfiguration config;
1226 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1227
1228 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1229 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1230 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1231}
1232
Jeff Browne6504122010-09-27 14:52:15 -07001233static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1234 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1235 if (checkInputManagerUnitialized(env)) {
1236 return false;
1237 }
1238
1239 sp<InputChannel> fromChannel =
1240 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1241 sp<InputChannel> toChannel =
1242 android_view_InputChannel_getInputChannel(env, toChannelObj);
1243
1244 if (fromChannel == NULL || toChannel == NULL) {
1245 return false;
1246 }
1247
1248 return gNativeInputManager->getInputManager()->getDispatcher()->
1249 transferTouchFocus(fromChannel, toChannel);
1250}
1251
Jeff Brown1a84fd12011-06-02 01:26:32 -07001252static void android_server_InputManager_nativeSetPointerSpeed(JNIEnv* env,
1253 jclass clazz, jint speed) {
1254 if (checkInputManagerUnitialized(env)) {
1255 return;
1256 }
1257
1258 gNativeInputManager->setPointerSpeed(speed);
1259}
1260
Jeff Browne33348b2010-07-15 23:54:05 -07001261static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1262 if (checkInputManagerUnitialized(env)) {
1263 return NULL;
1264 }
1265
Jeff Brownb88102f2010-09-08 11:49:43 -07001266 String8 dump;
1267 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001268 return env->NewStringUTF(dump.string());
1269}
1270
Jeff Brown9c3cda02010-06-15 01:31:58 -07001271// ----------------------------------------------------------------------------
1272
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001273static JNINativeMethod gInputManagerMethods[] = {
1274 /* name, signature, funcPtr */
Jeff Brown2352b972011-04-12 22:39:53 -07001275 { "nativeInit", "(Landroid/content/Context;"
1276 "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001277 (void*) android_server_InputManager_nativeInit },
1278 { "nativeStart", "()V",
1279 (void*) android_server_InputManager_nativeStart },
1280 { "nativeSetDisplaySize", "(III)V",
1281 (void*) android_server_InputManager_nativeSetDisplaySize },
1282 { "nativeSetDisplayOrientation", "(II)V",
1283 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1284 { "nativeGetScanCodeState", "(III)I",
1285 (void*) android_server_InputManager_nativeGetScanCodeState },
1286 { "nativeGetKeyCodeState", "(III)I",
1287 (void*) android_server_InputManager_nativeGetKeyCodeState },
1288 { "nativeGetSwitchState", "(III)I",
1289 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001290 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001291 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001292 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001293 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001294 (void*) android_server_InputManager_nativeRegisterInputChannel },
1295 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001296 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown0029c662011-03-30 02:25:18 -07001297 { "nativeSetInputFilterEnabled", "(Z)V",
1298 (void*) android_server_InputManager_nativeSetInputFilterEnabled },
1299 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
Jeff Brown6ec402b2010-07-28 15:48:59 -07001300 (void*) android_server_InputManager_nativeInjectInputEvent },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001301 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindow;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001302 (void*) android_server_InputManager_nativeSetInputWindows },
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001303 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplication;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001304 (void*) android_server_InputManager_nativeSetFocusedApplication },
1305 { "nativeSetInputDispatchMode", "(ZZ)V",
1306 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001307 { "nativeSetSystemUiVisibility", "(I)V",
1308 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001309 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1310 (void*) android_server_InputManager_nativeGetInputDevice },
1311 { "nativeGetInputDeviceIds", "()[I",
1312 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001313 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1314 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001315 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1316 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Brown1a84fd12011-06-02 01:26:32 -07001317 { "nativeSetPointerSpeed", "(I)V",
1318 (void*) android_server_InputManager_nativeSetPointerSpeed },
Jeff Browne33348b2010-07-15 23:54:05 -07001319 { "nativeDump", "()Ljava/lang/String;",
1320 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001321};
1322
1323#define FIND_CLASS(var, className) \
1324 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001325 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001326
1327#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1328 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1329 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1330
1331#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1332 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1333 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1334
1335int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001336 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001337 gInputManagerMethods, NELEM(gInputManagerMethods));
1338 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1339
Jeff Brown9c3cda02010-06-15 01:31:58 -07001340 // Callbacks
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001341
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001342 jclass clazz;
1343 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001344
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001345 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001346 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001347
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001348 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001349 "notifyLidSwitchChanged", "(JZ)V");
1350
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001351 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001352 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001353
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001354 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001355 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001356 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001357
Jeff Brown0029c662011-03-30 02:25:18 -07001358 GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
1359 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1360
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001361 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001362 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001363
Jeff Brown56194eb2011-03-02 19:23:13 -08001364 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001365 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001366 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1367
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001368 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001369 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001370 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001371
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001372 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001373 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001374 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001375
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001376 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001377 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001378
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001379 GET_METHOD_ID(gCallbacksClassInfo.filterTouchEvents, clazz,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001380 "filterTouchEvents", "()Z");
1381
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001382 GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, clazz,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001383 "filterJumpyTouchEvents", "()Z");
1384
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001385 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001386 "getVirtualKeyQuietTimeMillis", "()I");
1387
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001388 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001389 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1390
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001391 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001392 "getKeyRepeatTimeout", "()I");
1393
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001394 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001395 "getKeyRepeatDelay", "()I");
1396
Jeff Brown774ed9d2011-06-07 17:48:39 -07001397 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapTimeout, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001398 "getHoverTapTimeout", "()I");
1399
Jeff Brown774ed9d2011-06-07 17:48:39 -07001400 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapSlop, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001401 "getHoverTapSlop", "()I");
Jeff Brown214eaf42011-05-26 19:17:02 -07001402
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001403 GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001404 "getDoubleTapTimeout", "()I");
1405
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001406 GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001407 "getLongPressTimeout", "()I");
1408
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001409 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001410 "getMaxEventsPerSecond", "()I");
1411
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001412 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001413 "getPointerLayer", "()I");
1414
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001415 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Jeff Brown2352b972011-04-12 22:39:53 -07001416 "getPointerIcon", "()Landroid/view/PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001417
Jeff Brown6ec402b2010-07-28 15:48:59 -07001418 // KeyEvent
1419
1420 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001421 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1422
Jeff Brown6ec402b2010-07-28 15:48:59 -07001423
Jeff Brown8d608662010-08-30 03:02:23 -07001424 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001425
1426 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001427 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001428
Jeff Brown8d608662010-08-30 03:02:23 -07001429 // InputDevice
1430
1431 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001432 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001433
1434 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1435 "<init>", "()V");
1436
1437 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001438 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001439
1440 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1441 "mId", "I");
1442
1443 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1444 "mName", "Ljava/lang/String;");
1445
1446 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1447 "mSources", "I");
1448
1449 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1450 "mKeyboardType", "I");
1451
Jeff Brown57c59372010-09-21 18:22:55 -07001452 // Configuration
1453
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001454 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001455
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001456 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001457 "touchscreen", "I");
1458
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001459 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001460 "keyboard", "I");
1461
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001462 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001463 "navigation", "I");
1464
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001465 return 0;
1466}
1467
Jeff Brown46b9ac0a2010-04-22 18:58:52 -07001468} /* namespace android */