blob: 3414eea518b886cc3b8e436b18665f06f147c2d6 [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 Brownbc68a592011-07-25 12:58:12 -0700169 void setDisplaySize(int32_t displayId, int32_t width, int32_t height,
170 int32_t externalWidth, int32_t externalHeight);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700171 void setDisplayOrientation(int32_t displayId, int32_t orientation);
172
Jeff Brown7fbdc842010-06-17 20:52:56 -0700173 status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
Jeff Brown928e0542011-01-10 11:17:36 -0800174 const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700175 status_t unregisterInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel);
176
Jeff Brown9302c872011-07-13 22:51:29 -0700177 void setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray);
178 void setFocusedApplication(JNIEnv* env, jobject applicationHandleObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700179 void setInputDispatchMode(bool enabled, bool frozen);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800180 void setSystemUiVisibility(int32_t visibility);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700181 void setPointerSpeed(int32_t speed);
Jeff Brown349703e2010-06-22 01:27:15 -0700182
Jeff Brown9c3cda02010-06-15 01:31:58 -0700183 /* --- InputReaderPolicyInterface implementation --- */
184
Jeff Brownbc68a592011-07-25 12:58:12 -0700185 virtual bool getDisplayInfo(int32_t displayId, bool external,
Jeff Brown9c3cda02010-06-15 01:31:58 -0700186 int32_t* width, int32_t* height, int32_t* orientation);
Jeff Brown214eaf42011-05-26 19:17:02 -0700187 virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);
Jeff Brown83c09682010-12-23 17:50:18 -0800188 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700189
190 /* --- InputDispatcherPolicyInterface implementation --- */
191
Jeff Browne20c9e02010-10-11 14:20:19 -0700192 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
193 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700194 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700195 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800196 const sp<InputWindowHandle>& inputWindowHandle);
197 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown0029c662011-03-30 02:25:18 -0700198 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
Jeff Brown214eaf42011-05-26 19:17:02 -0700199 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
200 virtual bool isKeyRepeatEnabled();
Jeff Brown1f245102010-11-18 20:53:46 -0800201 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800202 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800203 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700204 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800205 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800206 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700207 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700208 virtual bool checkInjectEventsPermissionNonReentrant(
209 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700210
Jeff Brown2352b972011-04-12 22:39:53 -0700211 /* --- PointerControllerPolicyInterface implementation --- */
212
213 virtual void loadPointerResources(PointerResources* outResources);
214
Jeff Brown9c3cda02010-06-15 01:31:58 -0700215private:
216 sp<InputManager> mInputManager;
217
Jeff Brown2352b972011-04-12 22:39:53 -0700218 jobject mContextObj;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700219 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800220 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700221
Jeff Brown83c09682010-12-23 17:50:18 -0800222 Mutex mLock;
223 struct Locked {
224 // Display size information.
Jeff Brownbc68a592011-07-25 12:58:12 -0700225 int32_t displayWidth, displayHeight; // -1 when not initialized
226 int32_t displayExternalWidth, displayExternalHeight; // -1 when not initialized
Jeff Brown83c09682010-12-23 17:50:18 -0800227 int32_t displayOrientation;
228
Jeff Brown05dc66a2011-03-02 14:41:58 -0800229 // System UI visibility.
230 int32_t systemUiVisibility;
231
Jeff Brown1a84fd12011-06-02 01:26:32 -0700232 // Pointer speed.
233 int32_t pointerSpeed;
234
Jeff Brown474dcb52011-06-14 20:22:50 -0700235 // True if pointer gestures are enabled.
236 bool pointerGesturesEnabled;
237
Jeff Brown5541de92011-04-11 11:54:25 -0700238 // Sprite controller singleton, created on first use.
239 sp<SpriteController> spriteController;
240
Jeff Brown83c09682010-12-23 17:50:18 -0800241 // Pointer controller singleton, created and destroyed as needed.
242 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800243 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700244
Jeff Brown2352b972011-04-12 22:39:53 -0700245 void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800246 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown5541de92011-04-11 11:54:25 -0700247 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800248
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700249 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700250 bool isScreenOn();
251 bool isScreenBright();
252
Jeff Brownb88102f2010-09-08 11:49:43 -0700253 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700254
Jeff Brown9c3cda02010-06-15 01:31:58 -0700255 static inline JNIEnv* jniEnv() {
256 return AndroidRuntime::getJNIEnv();
257 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700258};
259
Jeff Brown928e0542011-01-10 11:17:36 -0800260
Jeff Brown9c3cda02010-06-15 01:31:58 -0700261
Jeff Brown2352b972011-04-12 22:39:53 -0700262NativeInputManager::NativeInputManager(jobject contextObj,
263 jobject callbacksObj, const sp<Looper>& looper) :
Jeff Brown214eaf42011-05-26 19:17:02 -0700264 mLooper(looper) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700265 JNIEnv* env = jniEnv();
266
Jeff Brown2352b972011-04-12 22:39:53 -0700267 mContextObj = env->NewGlobalRef(contextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700268 mCallbacksObj = env->NewGlobalRef(callbacksObj);
269
Jeff Brown83c09682010-12-23 17:50:18 -0800270 {
271 AutoMutex _l(mLock);
272 mLocked.displayWidth = -1;
273 mLocked.displayHeight = -1;
Jeff Brownbc68a592011-07-25 12:58:12 -0700274 mLocked.displayExternalWidth = -1;
275 mLocked.displayExternalHeight = -1;
Jeff Brown83c09682010-12-23 17:50:18 -0800276 mLocked.displayOrientation = ROTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800277
278 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700279 mLocked.pointerSpeed = 0;
Jeff Brown474dcb52011-06-14 20:22:50 -0700280 mLocked.pointerGesturesEnabled = true;
Jeff Brown83c09682010-12-23 17:50:18 -0800281 }
282
Jeff Brown9c3cda02010-06-15 01:31:58 -0700283 sp<EventHub> eventHub = new EventHub();
284 mInputManager = new InputManager(eventHub, this, this);
285}
286
287NativeInputManager::~NativeInputManager() {
288 JNIEnv* env = jniEnv();
289
Jeff Brown2352b972011-04-12 22:39:53 -0700290 env->DeleteGlobalRef(mContextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700291 env->DeleteGlobalRef(mCallbacksObj);
292}
293
Jeff Brownb88102f2010-09-08 11:49:43 -0700294void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700295 mInputManager->getReader()->dump(dump);
296 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700297
Jeff Brownb88102f2010-09-08 11:49:43 -0700298 mInputManager->getDispatcher()->dump(dump);
299 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700300}
301
Jeff Brown7fbdc842010-06-17 20:52:56 -0700302bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700303 if (env->ExceptionCheck()) {
304 LOGE("An exception was thrown by callback '%s'.", methodName);
305 LOGE_EX(env);
306 env->ExceptionClear();
307 return true;
308 }
309 return false;
310}
311
Jeff Brownbc68a592011-07-25 12:58:12 -0700312void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height,
313 int32_t externalWidth, int32_t externalHeight) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700314 if (displayId == 0) {
Jeff Brown2352b972011-04-12 22:39:53 -0700315 { // acquire lock
316 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700317
Jeff Brownbc68a592011-07-25 12:58:12 -0700318 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
319 mLocked.displayWidth = width;
320 mLocked.displayHeight = height;
321
322 sp<PointerController> controller = mLocked.pointerController.promote();
323 if (controller != NULL) {
324 controller->setDisplaySize(width, height);
325 }
Jeff Brown2352b972011-04-12 22:39:53 -0700326 }
327
Jeff Brownbc68a592011-07-25 12:58:12 -0700328 mLocked.displayExternalWidth = externalWidth;
329 mLocked.displayExternalHeight = externalHeight;
Jeff Brown2352b972011-04-12 22:39:53 -0700330 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700331 }
332}
333
334void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
335 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800336 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700337
Jeff Brown83c09682010-12-23 17:50:18 -0800338 if (mLocked.displayOrientation != orientation) {
339 mLocked.displayOrientation = orientation;
340
341 sp<PointerController> controller = mLocked.pointerController.promote();
342 if (controller != NULL) {
343 controller->setDisplayOrientation(orientation);
344 }
345 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700346 }
347}
348
Jeff Brown7fbdc842010-06-17 20:52:56 -0700349status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800350 const sp<InputChannel>& inputChannel,
351 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
352 return mInputManager->getDispatcher()->registerInputChannel(
353 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700354}
355
356status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
357 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700358 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700359}
360
Jeff Brownbc68a592011-07-25 12:58:12 -0700361bool NativeInputManager::getDisplayInfo(int32_t displayId, bool external,
Jeff Brown9c3cda02010-06-15 01:31:58 -0700362 int32_t* width, int32_t* height, int32_t* orientation) {
363 bool result = false;
364 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800365 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700366
Jeff Brown83c09682010-12-23 17:50:18 -0800367 if (mLocked.displayWidth > 0 && mLocked.displayHeight > 0) {
Jeff Brown6d0fec22010-07-23 21:28:06 -0700368 if (width) {
Jeff Brownbc68a592011-07-25 12:58:12 -0700369 *width = external ? mLocked.displayExternalWidth : mLocked.displayWidth;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700370 }
371 if (height) {
Jeff Brownbc68a592011-07-25 12:58:12 -0700372 *height = external ? mLocked.displayExternalHeight : mLocked.displayHeight;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700373 }
374 if (orientation) {
Jeff Brown83c09682010-12-23 17:50:18 -0800375 *orientation = mLocked.displayOrientation;
Jeff Brown6d0fec22010-07-23 21:28:06 -0700376 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700377 result = true;
378 }
379 }
380 return result;
381}
382
Jeff Brown214eaf42011-05-26 19:17:02 -0700383void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700384 JNIEnv* env = jniEnv();
385
Jeff Brown214eaf42011-05-26 19:17:02 -0700386 jint virtualKeyQuietTime = env->CallIntMethod(mCallbacksObj,
387 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
388 if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
389 outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
390 }
391
392 outConfig->excludedDeviceNames.clear();
393 jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mCallbacksObj,
Jeff Brown9c3cda02010-06-15 01:31:58 -0700394 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown214eaf42011-05-26 19:17:02 -0700395 if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
396 jsize length = env->GetArrayLength(excludedDeviceNames);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700397 for (jsize i = 0; i < length; i++) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700398 jstring item = jstring(env->GetObjectArrayElement(excludedDeviceNames, i));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700399 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
Jeff Brown214eaf42011-05-26 19:17:02 -0700400 outConfig->excludedDeviceNames.add(String8(deviceNameChars));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700401 env->ReleaseStringUTFChars(item, deviceNameChars);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700402 env->DeleteLocalRef(item);
403 }
Jeff Brown214eaf42011-05-26 19:17:02 -0700404 env->DeleteLocalRef(excludedDeviceNames);
405 }
406
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700407 jint hoverTapTimeout = env->CallIntMethod(mCallbacksObj,
408 gCallbacksClassInfo.getHoverTapTimeout);
409 if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700410 jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
411 gCallbacksClassInfo.getDoubleTapTimeout);
412 if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
413 jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
414 gCallbacksClassInfo.getLongPressTimeout);
415 if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700416 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700417
418 // We must ensure that the tap-drag interval is significantly shorter than
419 // the long-press timeout because the tap is held down for the entire duration
420 // of the double-tap timeout.
421 jint tapDragInterval = max(min(longPressTimeout - 100,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700422 doubleTapTimeout), hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700423 outConfig->pointerGestureTapDragInterval =
424 milliseconds_to_nanoseconds(tapDragInterval);
425 }
426 }
427 }
428
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700429 jint hoverTapSlop = env->CallIntMethod(mCallbacksObj,
430 gCallbacksClassInfo.getHoverTapSlop);
431 if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
432 outConfig->pointerGestureTapSlop = hoverTapSlop;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700433 }
Jeff Brown1a84fd12011-06-02 01:26:32 -0700434
435 { // acquire lock
436 AutoMutex _l(mLock);
437
438 outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
439 * POINTER_SPEED_EXPONENT);
Jeff Brown474dcb52011-06-14 20:22:50 -0700440 outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700441 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700442}
443
Jeff Brown83c09682010-12-23 17:50:18 -0800444sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
445 AutoMutex _l(mLock);
446
447 sp<PointerController> controller = mLocked.pointerController.promote();
448 if (controller == NULL) {
Jeff Brown5541de92011-04-11 11:54:25 -0700449 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800450
Jeff Brown2352b972011-04-12 22:39:53 -0700451 controller = new PointerController(this, mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800452 mLocked.pointerController = controller;
453
454 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
455 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800456
Jeff Brown5541de92011-04-11 11:54:25 -0700457 JNIEnv* env = jniEnv();
Jeff Brown2352b972011-04-12 22:39:53 -0700458 jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
459 gCallbacksClassInfo.getPointerIcon);
460 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
461 PointerIcon pointerIcon;
462 status_t status = android_view_PointerIcon_load(env, pointerIconObj,
463 mContextObj, &pointerIcon);
464 if (!status && !pointerIcon.isNullIcon()) {
465 controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
466 pointerIcon.hotSpotX, pointerIcon.hotSpotY));
467 } else {
468 controller->setPointerIcon(SpriteIcon());
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800469 }
Jeff Brown2352b972011-04-12 22:39:53 -0700470 env->DeleteLocalRef(pointerIconObj);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800471 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800472
Jeff Brown2352b972011-04-12 22:39:53 -0700473 updateInactivityTimeoutLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800474 }
475 return controller;
476}
477
Jeff Brown5541de92011-04-11 11:54:25 -0700478void NativeInputManager::ensureSpriteControllerLocked() {
479 if (mLocked.spriteController == NULL) {
480 JNIEnv* env = jniEnv();
481 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
482 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
483 layer = -1;
484 }
485 mLocked.spriteController = new SpriteController(mLooper, layer);
486 }
487}
488
Jeff Browne20c9e02010-10-11 14:20:19 -0700489void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
490 int32_t switchValue, uint32_t policyFlags) {
491#if DEBUG_INPUT_DISPATCHER_POLICY
492 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
493 when, switchCode, switchValue, policyFlags);
494#endif
495
496 JNIEnv* env = jniEnv();
497
498 switch (switchCode) {
499 case SW_LID:
500 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
501 when, switchValue == 0);
502 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
503 break;
504 }
505}
506
Jeff Brown9c3cda02010-06-15 01:31:58 -0700507void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
508#if DEBUG_INPUT_DISPATCHER_POLICY
509 LOGD("notifyConfigurationChanged - when=%lld", when);
510#endif
511
512 JNIEnv* env = jniEnv();
513
Jeff Brown57c59372010-09-21 18:22:55 -0700514 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700515 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700516}
517
Jeff Brown519e0242010-09-15 15:18:56 -0700518nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800519 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700520#if DEBUG_INPUT_DISPATCHER_POLICY
521 LOGD("notifyANR");
522#endif
523
524 JNIEnv* env = jniEnv();
525
Jeff Brown928e0542011-01-10 11:17:36 -0800526 jobject inputApplicationHandleObj =
527 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
528 jobject inputWindowHandleObj =
529 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700530
Jeff Brown519e0242010-09-15 15:18:56 -0700531 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800532 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700533 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
534 newTimeout = 0; // abort dispatch
535 } else {
536 assert(newTimeout >= 0);
537 }
538
Jeff Brown928e0542011-01-10 11:17:36 -0800539 env->DeleteLocalRef(inputWindowHandleObj);
540 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700541 return newTimeout;
542}
543
Jeff Brown928e0542011-01-10 11:17:36 -0800544void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700545#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800546 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700547#endif
548
Jeff Brown7fbdc842010-06-17 20:52:56 -0700549 JNIEnv* env = jniEnv();
550
Jeff Brown928e0542011-01-10 11:17:36 -0800551 jobject inputWindowHandleObj =
552 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
553 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700554 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800555 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700556 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
557
Jeff Brown928e0542011-01-10 11:17:36 -0800558 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700559 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700560}
561
Jeff Brown214eaf42011-05-26 19:17:02 -0700562void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
563 JNIEnv* env = jniEnv();
Jeff Browna4547672011-03-02 21:38:11 -0800564
Jeff Brown214eaf42011-05-26 19:17:02 -0700565 jint keyRepeatTimeout = env->CallIntMethod(mCallbacksObj,
566 gCallbacksClassInfo.getKeyRepeatTimeout);
567 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
568 outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
569 }
Jeff Browna4547672011-03-02 21:38:11 -0800570
Jeff Brown214eaf42011-05-26 19:17:02 -0700571 jint keyRepeatDelay = env->CallIntMethod(mCallbacksObj,
572 gCallbacksClassInfo.getKeyRepeatDelay);
573 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
574 outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
575 }
576
577 jint maxEventsPerSecond = env->CallIntMethod(mCallbacksObj,
578 gCallbacksClassInfo.getMaxEventsPerSecond);
579 if (!checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
580 outConfig->maxEventsPerSecond = maxEventsPerSecond;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700581 }
582}
583
Jeff Brown214eaf42011-05-26 19:17:02 -0700584bool NativeInputManager::isKeyRepeatEnabled() {
585 // Only enable automatic key repeating when the screen is on.
586 return isScreenOn();
Jeff Brownae9fc032010-08-18 15:51:08 -0700587}
588
Jeff Brown9302c872011-07-13 22:51:29 -0700589void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray) {
590 Vector<sp<InputWindowHandle> > windowHandles;
Jeff Brown349703e2010-06-22 01:27:15 -0700591
Jeff Brown9302c872011-07-13 22:51:29 -0700592 if (windowHandleObjArray) {
593 jsize length = env->GetArrayLength(windowHandleObjArray);
594 for (jsize i = 0; i < length; i++) {
595 jobject windowHandleObj = env->GetObjectArrayElement(windowHandleObjArray, i);
596 if (! windowHandleObj) {
597 break; // found null element indicating end of used portion of the array
Jeff Brown474dcb52011-06-14 20:22:50 -0700598 }
Jeff Brown9302c872011-07-13 22:51:29 -0700599
600 sp<InputWindowHandle> windowHandle =
601 android_server_InputWindowHandle_getHandle(env, windowHandleObj);
602 if (windowHandle != NULL) {
603 windowHandles.push(windowHandle);
604 }
605 env->DeleteLocalRef(windowHandleObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700606 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700607 }
Jeff Brown349703e2010-06-22 01:27:15 -0700608
Jeff Brown9302c872011-07-13 22:51:29 -0700609 mInputManager->getDispatcher()->setInputWindows(windowHandles);
610
611 // Do this after the dispatcher has updated the window handle state.
612 bool newPointerGesturesEnabled = true;
613 size_t numWindows = windowHandles.size();
614 for (size_t i = 0; i < numWindows; i++) {
615 const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
616 if (windowHandle->hasFocus && (windowHandle->inputFeatures
617 & InputWindowHandle::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES)) {
618 newPointerGesturesEnabled = false;
619 }
620 }
Jeff Brown474dcb52011-06-14 20:22:50 -0700621
622 uint32_t changes = 0;
623 { // acquire lock
624 AutoMutex _l(mLock);
625
626 if (mLocked.pointerGesturesEnabled != newPointerGesturesEnabled) {
627 mLocked.pointerGesturesEnabled = newPointerGesturesEnabled;
628 changes |= InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT;
629 }
630 } // release lock
631
632 if (changes) {
633 mInputManager->getReader()->requestRefreshConfiguration(changes);
634 }
Jeff Brown349703e2010-06-22 01:27:15 -0700635}
636
Jeff Brown9302c872011-07-13 22:51:29 -0700637void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationHandleObj) {
638 sp<InputApplicationHandle> applicationHandle =
639 android_server_InputApplicationHandle_getHandle(env, applicationHandleObj);
640 mInputManager->getDispatcher()->setFocusedApplication(applicationHandle);
Jeff Brown349703e2010-06-22 01:27:15 -0700641}
642
643void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700644 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700645}
646
Jeff Brown05dc66a2011-03-02 14:41:58 -0800647void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
648 AutoMutex _l(mLock);
649
650 if (mLocked.systemUiVisibility != visibility) {
651 mLocked.systemUiVisibility = visibility;
652
653 sp<PointerController> controller = mLocked.pointerController.promote();
654 if (controller != NULL) {
Jeff Brown2352b972011-04-12 22:39:53 -0700655 updateInactivityTimeoutLocked(controller);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800656 }
657 }
658}
659
Jeff Brown2352b972011-04-12 22:39:53 -0700660void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800661 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
Jeff Brown2352b972011-04-12 22:39:53 -0700662 controller->setInactivityTimeout(lightsOut
663 ? PointerController::INACTIVITY_TIMEOUT_SHORT
664 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800665}
666
Jeff Brown1a84fd12011-06-02 01:26:32 -0700667void NativeInputManager::setPointerSpeed(int32_t speed) {
Jeff Brown474dcb52011-06-14 20:22:50 -0700668 { // acquire lock
669 AutoMutex _l(mLock);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700670
Jeff Brown474dcb52011-06-14 20:22:50 -0700671 if (mLocked.pointerSpeed == speed) {
672 return;
673 }
674
Jeff Brown1a84fd12011-06-02 01:26:32 -0700675 LOGI("Setting pointer speed to %d.", speed);
676 mLocked.pointerSpeed = speed;
Jeff Brown474dcb52011-06-14 20:22:50 -0700677 } // release lock
Jeff Brown1a84fd12011-06-02 01:26:32 -0700678
Jeff Brown474dcb52011-06-14 20:22:50 -0700679 mInputManager->getReader()->requestRefreshConfiguration(
680 InputReaderConfiguration::CHANGE_POINTER_SPEED);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700681}
682
Jeff Browne20c9e02010-10-11 14:20:19 -0700683bool NativeInputManager::isScreenOn() {
684 return android_server_PowerManagerService_isScreenOn();
685}
686
687bool NativeInputManager::isScreenBright() {
688 return android_server_PowerManagerService_isScreenBright();
689}
690
Jeff Brown0029c662011-03-30 02:25:18 -0700691bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
692 jobject inputEventObj;
693
694 JNIEnv* env = jniEnv();
695 switch (inputEvent->getType()) {
696 case AINPUT_EVENT_TYPE_KEY:
697 inputEventObj = android_view_KeyEvent_fromNative(env,
698 static_cast<const KeyEvent*>(inputEvent));
699 break;
700 case AINPUT_EVENT_TYPE_MOTION:
701 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
702 static_cast<const MotionEvent*>(inputEvent));
703 break;
704 default:
705 return true; // dispatch the event normally
706 }
707
708 if (!inputEventObj) {
709 LOGE("Failed to obtain input event object for filterInputEvent.");
710 return true; // dispatch the event normally
711 }
712
713 // The callee is responsible for recycling the event.
714 jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
715 inputEventObj, policyFlags);
716 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
717 pass = true;
718 }
719 env->DeleteLocalRef(inputEventObj);
720 return pass;
721}
722
Jeff Brown1f245102010-11-18 20:53:46 -0800723void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
724 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700725 // Policy:
726 // - Ignore untrusted events and pass them along.
727 // - Ask the window manager what to do with normal events and trusted injected events.
728 // - For normal events wake and brighten the screen if currently off or dim.
729 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800730 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700731 bool isScreenOn = this->isScreenOn();
732 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700733
Jeff Brown3122e442010-10-11 23:32:49 -0700734 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800735 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
736 jint wmActions;
737 if (keyEventObj) {
738 wmActions = env->CallIntMethod(mCallbacksObj,
739 gCallbacksClassInfo.interceptKeyBeforeQueueing,
740 keyEventObj, policyFlags, isScreenOn);
741 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
742 wmActions = 0;
743 }
744 android_view_KeyEvent_recycle(env, keyEventObj);
745 env->DeleteLocalRef(keyEventObj);
746 } else {
747 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700748 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700749 }
750
Jeff Brown1f245102010-11-18 20:53:46 -0800751 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700752 if (!isScreenOn) {
753 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700754 }
755
756 if (!isScreenBright) {
757 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
758 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700759 }
760
Jeff Brown56194eb2011-03-02 19:23:13 -0800761 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700762 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700763 policyFlags |= POLICY_FLAG_PASS_TO_USER;
764 }
765}
766
Jeff Brown56194eb2011-03-02 19:23:13 -0800767void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700768 // Policy:
769 // - Ignore untrusted events and pass them along.
770 // - No special filtering for injected events required at this time.
771 // - Filter normal events based on screen state.
772 // - For normal events brighten (but do not wake) the screen if currently dim.
773 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
774 if (isScreenOn()) {
775 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700776
Jeff Brown3122e442010-10-11 23:32:49 -0700777 if (!isScreenBright()) {
778 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
779 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800780 } else {
781 JNIEnv* env = jniEnv();
782 jint wmActions = env->CallIntMethod(mCallbacksObj,
783 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
784 policyFlags);
785 if (checkAndClearExceptionFromCallback(env,
786 "interceptMotionBeforeQueueingWhenScreenOff")) {
787 wmActions = 0;
788 }
789
790 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
791 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700792 }
Jeff Brown3122e442010-10-11 23:32:49 -0700793 } else {
794 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700795 }
796}
797
Jeff Brown56194eb2011-03-02 19:23:13 -0800798void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
799 uint32_t& policyFlags) {
800 enum {
801 WM_ACTION_PASS_TO_USER = 1,
802 WM_ACTION_POKE_USER_ACTIVITY = 2,
803 WM_ACTION_GO_TO_SLEEP = 4,
804 };
805
806 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800807#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800808 LOGD("handleInterceptActions: Going to sleep.");
809#endif
810 android_server_PowerManagerService_goToSleep(when);
811 }
812
813 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800814#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800815 LOGD("handleInterceptActions: Poking user activity.");
816#endif
817 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
818 }
819
820 if (wmActions & WM_ACTION_PASS_TO_USER) {
821 policyFlags |= POLICY_FLAG_PASS_TO_USER;
822 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800823#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800824 LOGD("handleInterceptActions: Not passing key to user.");
825#endif
826 }
827}
828
Jeff Brown928e0542011-01-10 11:17:36 -0800829bool NativeInputManager::interceptKeyBeforeDispatching(
830 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700831 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700832 // Policy:
833 // - Ignore untrusted events and pass them along.
834 // - Filter normal events and trusted injected events through the window manager policy to
835 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800836 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700837 if (policyFlags & POLICY_FLAG_TRUSTED) {
838 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700839
Jeff Brown928e0542011-01-10 11:17:36 -0800840 // Note: inputWindowHandle may be null.
841 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800842 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
843 if (keyEventObj) {
844 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
845 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800846 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800847 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
848 android_view_KeyEvent_recycle(env, keyEventObj);
849 env->DeleteLocalRef(keyEventObj);
850 result = consumed && !error;
851 } else {
852 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800853 }
Jeff Brown928e0542011-01-10 11:17:36 -0800854 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700855 }
Jeff Brown1f245102010-11-18 20:53:46 -0800856 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700857}
858
Jeff Brown928e0542011-01-10 11:17:36 -0800859bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800860 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700861 // Policy:
862 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800863 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700864 if (policyFlags & POLICY_FLAG_TRUSTED) {
865 JNIEnv* env = jniEnv();
866
Jeff Brown928e0542011-01-10 11:17:36 -0800867 // Note: inputWindowHandle may be null.
868 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800869 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
870 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800871 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800872 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800873 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700874 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
875 fallbackKeyEventObj = NULL;
876 }
Jeff Brown1f245102010-11-18 20:53:46 -0800877 android_view_KeyEvent_recycle(env, keyEventObj);
878 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800879
880 if (fallbackKeyEventObj) {
881 // Note: outFallbackKeyEvent may be the same object as keyEvent.
882 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
883 outFallbackKeyEvent)) {
884 result = true;
885 }
886 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
887 env->DeleteLocalRef(fallbackKeyEventObj);
888 }
Jeff Brown1f245102010-11-18 20:53:46 -0800889 } else {
890 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800891 }
Jeff Brown928e0542011-01-10 11:17:36 -0800892 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700893 }
Jeff Brown1f245102010-11-18 20:53:46 -0800894 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700895}
896
Jeff Brown01ce2e92010-09-26 22:20:12 -0700897void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
898 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700899}
900
Jeff Brown349703e2010-06-22 01:27:15 -0700901
Jeff Brownb88102f2010-09-08 11:49:43 -0700902bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
903 int32_t injectorPid, int32_t injectorUid) {
904 JNIEnv* env = jniEnv();
905 jboolean result = env->CallBooleanMethod(mCallbacksObj,
906 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700907 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
908 result = false;
909 }
Jeff Brown349703e2010-06-22 01:27:15 -0700910 return result;
911}
912
Jeff Brown2352b972011-04-12 22:39:53 -0700913void NativeInputManager::loadPointerResources(PointerResources* outResources) {
914 JNIEnv* env = jniEnv();
915
916 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER,
917 &outResources->spotHover);
918 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH,
919 &outResources->spotTouch);
920 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR,
921 &outResources->spotAnchor);
922}
923
Jeff Brown83c09682010-12-23 17:50:18 -0800924
Jeff Brown9c3cda02010-06-15 01:31:58 -0700925// ----------------------------------------------------------------------------
926
927static sp<NativeInputManager> gNativeInputManager;
928
Jeff Brown46b9ac02010-04-22 18:58:52 -0700929static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700930 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700931 LOGE("Input manager not initialized.");
932 jniThrowRuntimeException(env, "Input manager not initialized.");
933 return true;
934 }
935 return false;
936}
937
938static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown2352b972011-04-12 22:39:53 -0700939 jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700940 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800941 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
Jeff Brown2352b972011-04-12 22:39:53 -0700942 gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700943 } else {
944 LOGE("Input manager already initialized.");
945 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700946 }
947}
948
949static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
950 if (checkInputManagerUnitialized(env)) {
951 return;
952 }
953
Jeff Brown9c3cda02010-06-15 01:31:58 -0700954 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700955 if (result) {
956 jniThrowRuntimeException(env, "Input manager could not be started.");
957 }
958}
959
960static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
Jeff Brownbc68a592011-07-25 12:58:12 -0700961 jint displayId, jint width, jint height, jint externalWidth, jint externalHeight) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700962 if (checkInputManagerUnitialized(env)) {
963 return;
964 }
965
966 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
967 // to be passed in like this, not sure which is better but leaving it like this
968 // keeps the window manager in direct control of when display transitions propagate down
969 // to the input dispatcher
Jeff Brownbc68a592011-07-25 12:58:12 -0700970 gNativeInputManager->setDisplaySize(displayId, width, height, externalWidth, externalHeight);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700971}
972
973static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
974 jint displayId, jint orientation) {
975 if (checkInputManagerUnitialized(env)) {
976 return;
977 }
978
Jeff Brown9c3cda02010-06-15 01:31:58 -0700979 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700980}
981
982static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700983 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700984 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700985 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700986 }
987
Jeff Brownb88102f2010-09-08 11:49:43 -0700988 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700989 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700990}
991
992static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700993 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700994 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700995 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700996 }
997
Jeff Brownb88102f2010-09-08 11:49:43 -0700998 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700999 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001000}
1001
1002static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001003 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001004 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001005 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001006 }
1007
Jeff Brownb88102f2010-09-08 11:49:43 -07001008 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001009 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001010}
1011
1012static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001013 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001014 if (checkInputManagerUnitialized(env)) {
1015 return JNI_FALSE;
1016 }
1017
1018 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1019 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1020 jsize numCodes = env->GetArrayLength(keyCodes);
1021 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001022 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001023 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001024 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001025 } else {
1026 result = JNI_FALSE;
1027 }
1028
1029 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1030 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1031 return result;
1032}
1033
1034static void throwInputChannelNotInitialized(JNIEnv* env) {
1035 jniThrowException(env, "java/lang/IllegalStateException",
1036 "inputChannel is not initialized");
1037}
1038
1039static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1040 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1041 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1042 "the input manager!", inputChannel->getName().string());
1043
Jeff Brown9c3cda02010-06-15 01:31:58 -07001044 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001045 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001046 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001047}
1048
1049static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001050 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001051 if (checkInputManagerUnitialized(env)) {
1052 return;
1053 }
1054
1055 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1056 inputChannelObj);
1057 if (inputChannel == NULL) {
1058 throwInputChannelNotInitialized(env);
1059 return;
1060 }
1061
Jeff Brown928e0542011-01-10 11:17:36 -08001062 sp<InputWindowHandle> inputWindowHandle =
1063 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001064
1065 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001066 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001067 if (status) {
1068 jniThrowRuntimeException(env, "Failed to register input channel. "
1069 "Check logs for details.");
1070 return;
1071 }
1072
Jeff Browna41ca772010-08-11 14:46:32 -07001073 if (! monitor) {
1074 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1075 android_server_InputManager_handleInputChannelDisposed, NULL);
1076 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001077}
1078
1079static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1080 jobject inputChannelObj) {
1081 if (checkInputManagerUnitialized(env)) {
1082 return;
1083 }
1084
1085 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1086 inputChannelObj);
1087 if (inputChannel == NULL) {
1088 throwInputChannelNotInitialized(env);
1089 return;
1090 }
1091
1092 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1093
Jeff Brown7fbdc842010-06-17 20:52:56 -07001094 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001095 if (status) {
1096 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1097 "Check logs for details.");
1098 }
1099}
1100
Jeff Brown0029c662011-03-30 02:25:18 -07001101static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
1102 jboolean enabled) {
1103 if (checkInputManagerUnitialized(env)) {
1104 return;
1105 }
1106
1107 gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1108}
1109
Jeff Brown6ec402b2010-07-28 15:48:59 -07001110static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1111 jobject inputEventObj, jint injectorPid, jint injectorUid,
Jeff Brown0029c662011-03-30 02:25:18 -07001112 jint syncMode, jint timeoutMillis, jint policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001113 if (checkInputManagerUnitialized(env)) {
1114 return INPUT_EVENT_INJECTION_FAILED;
1115 }
1116
Jeff Brown6ec402b2010-07-28 15:48:59 -07001117 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1118 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001119 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1120 if (status) {
1121 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1122 return INPUT_EVENT_INJECTION_FAILED;
1123 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001124
Jeff Brownb88102f2010-09-08 11:49:43 -07001125 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001126 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1127 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001128 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001129 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1130 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001131 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1132 return INPUT_EVENT_INJECTION_FAILED;
1133 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001134
Jeff Brownb88102f2010-09-08 11:49:43 -07001135 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001136 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1137 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001138 } else {
1139 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001140 return INPUT_EVENT_INJECTION_FAILED;
1141 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001142}
1143
Jeff Brown349703e2010-06-22 01:27:15 -07001144static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
Jeff Brown9302c872011-07-13 22:51:29 -07001145 jobjectArray windowHandleObjArray) {
Jeff Brown349703e2010-06-22 01:27:15 -07001146 if (checkInputManagerUnitialized(env)) {
1147 return;
1148 }
1149
Jeff Brown9302c872011-07-13 22:51:29 -07001150 gNativeInputManager->setInputWindows(env, windowHandleObjArray);
Jeff Brown349703e2010-06-22 01:27:15 -07001151}
1152
1153static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
Jeff Brown9302c872011-07-13 22:51:29 -07001154 jobject applicationHandleObj) {
Jeff Brown349703e2010-06-22 01:27:15 -07001155 if (checkInputManagerUnitialized(env)) {
1156 return;
1157 }
1158
Jeff Brown9302c872011-07-13 22:51:29 -07001159 gNativeInputManager->setFocusedApplication(env, applicationHandleObj);
Jeff Brown349703e2010-06-22 01:27:15 -07001160}
1161
1162static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1163 jclass clazz, jboolean enabled, jboolean frozen) {
1164 if (checkInputManagerUnitialized(env)) {
1165 return;
1166 }
1167
1168 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1169}
1170
Jeff Brown05dc66a2011-03-02 14:41:58 -08001171static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1172 jclass clazz, jint visibility) {
1173 if (checkInputManagerUnitialized(env)) {
1174 return;
1175 }
1176
1177 gNativeInputManager->setSystemUiVisibility(visibility);
1178}
1179
Jeff Brown8d608662010-08-30 03:02:23 -07001180static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1181 jclass clazz, jint deviceId) {
1182 if (checkInputManagerUnitialized(env)) {
1183 return NULL;
1184 }
1185
1186 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001187 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001188 deviceId, & deviceInfo);
1189 if (status) {
1190 return NULL;
1191 }
1192
1193 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1194 if (! deviceObj) {
1195 return NULL;
1196 }
1197
1198 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1199 if (! deviceNameObj) {
1200 return NULL;
1201 }
1202
1203 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1204 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1205 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1206 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1207
Jeff Brownefd32662011-03-08 15:13:06 -08001208 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001209 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001210 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001211 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001212 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001213 if (env->ExceptionCheck()) {
1214 return NULL;
1215 }
1216 }
1217
1218 return deviceObj;
1219}
1220
1221static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1222 jclass clazz) {
1223 if (checkInputManagerUnitialized(env)) {
1224 return NULL;
1225 }
1226
1227 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001228 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001229
1230 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1231 if (! deviceIdsObj) {
1232 return NULL;
1233 }
1234
1235 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1236 return deviceIdsObj;
1237}
1238
Jeff Brown57c59372010-09-21 18:22:55 -07001239static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1240 jclass clazz, jobject configObj) {
1241 if (checkInputManagerUnitialized(env)) {
1242 return;
1243 }
1244
1245 InputConfiguration config;
1246 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1247
1248 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1249 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1250 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1251}
1252
Jeff Browne6504122010-09-27 14:52:15 -07001253static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1254 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1255 if (checkInputManagerUnitialized(env)) {
1256 return false;
1257 }
1258
1259 sp<InputChannel> fromChannel =
1260 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1261 sp<InputChannel> toChannel =
1262 android_view_InputChannel_getInputChannel(env, toChannelObj);
1263
1264 if (fromChannel == NULL || toChannel == NULL) {
1265 return false;
1266 }
1267
1268 return gNativeInputManager->getInputManager()->getDispatcher()->
1269 transferTouchFocus(fromChannel, toChannel);
1270}
1271
Jeff Brown1a84fd12011-06-02 01:26:32 -07001272static void android_server_InputManager_nativeSetPointerSpeed(JNIEnv* env,
1273 jclass clazz, jint speed) {
1274 if (checkInputManagerUnitialized(env)) {
1275 return;
1276 }
1277
1278 gNativeInputManager->setPointerSpeed(speed);
1279}
1280
Jeff Browne33348b2010-07-15 23:54:05 -07001281static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1282 if (checkInputManagerUnitialized(env)) {
1283 return NULL;
1284 }
1285
Jeff Brownb88102f2010-09-08 11:49:43 -07001286 String8 dump;
1287 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001288 return env->NewStringUTF(dump.string());
1289}
1290
Jeff Brown9c3cda02010-06-15 01:31:58 -07001291// ----------------------------------------------------------------------------
1292
Jeff Brown46b9ac02010-04-22 18:58:52 -07001293static JNINativeMethod gInputManagerMethods[] = {
1294 /* name, signature, funcPtr */
Jeff Brown2352b972011-04-12 22:39:53 -07001295 { "nativeInit", "(Landroid/content/Context;"
1296 "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001297 (void*) android_server_InputManager_nativeInit },
1298 { "nativeStart", "()V",
1299 (void*) android_server_InputManager_nativeStart },
Jeff Brownbc68a592011-07-25 12:58:12 -07001300 { "nativeSetDisplaySize", "(IIIII)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001301 (void*) android_server_InputManager_nativeSetDisplaySize },
1302 { "nativeSetDisplayOrientation", "(II)V",
1303 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1304 { "nativeGetScanCodeState", "(III)I",
1305 (void*) android_server_InputManager_nativeGetScanCodeState },
1306 { "nativeGetKeyCodeState", "(III)I",
1307 (void*) android_server_InputManager_nativeGetKeyCodeState },
1308 { "nativeGetSwitchState", "(III)I",
1309 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001310 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001311 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001312 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001313 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001314 (void*) android_server_InputManager_nativeRegisterInputChannel },
1315 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001316 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown0029c662011-03-30 02:25:18 -07001317 { "nativeSetInputFilterEnabled", "(Z)V",
1318 (void*) android_server_InputManager_nativeSetInputFilterEnabled },
1319 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
Jeff Brown6ec402b2010-07-28 15:48:59 -07001320 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown9302c872011-07-13 22:51:29 -07001321 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindowHandle;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001322 (void*) android_server_InputManager_nativeSetInputWindows },
Jeff Brown9302c872011-07-13 22:51:29 -07001323 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplicationHandle;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001324 (void*) android_server_InputManager_nativeSetFocusedApplication },
1325 { "nativeSetInputDispatchMode", "(ZZ)V",
1326 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001327 { "nativeSetSystemUiVisibility", "(I)V",
1328 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001329 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1330 (void*) android_server_InputManager_nativeGetInputDevice },
1331 { "nativeGetInputDeviceIds", "()[I",
1332 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001333 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1334 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001335 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1336 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Brown1a84fd12011-06-02 01:26:32 -07001337 { "nativeSetPointerSpeed", "(I)V",
1338 (void*) android_server_InputManager_nativeSetPointerSpeed },
Jeff Browne33348b2010-07-15 23:54:05 -07001339 { "nativeDump", "()Ljava/lang/String;",
1340 (void*) android_server_InputManager_nativeDump },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001341};
1342
1343#define FIND_CLASS(var, className) \
1344 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001345 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001346
1347#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1348 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1349 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1350
1351#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1352 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1353 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1354
1355int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001356 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001357 gInputManagerMethods, NELEM(gInputManagerMethods));
1358 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1359
Jeff Brown9c3cda02010-06-15 01:31:58 -07001360 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001361
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001362 jclass clazz;
1363 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001364
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001365 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001366 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001367
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001368 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001369 "notifyLidSwitchChanged", "(JZ)V");
1370
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001371 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001372 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001373
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001374 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001375 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001376 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001377
Jeff Brown0029c662011-03-30 02:25:18 -07001378 GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
1379 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1380
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001381 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001382 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001383
Jeff Brown56194eb2011-03-02 19:23:13 -08001384 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001385 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001386 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1387
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001388 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001389 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001390 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001391
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001392 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001393 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001394 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001395
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001396 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001397 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001398
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001399 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001400 "getVirtualKeyQuietTimeMillis", "()I");
1401
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001402 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001403 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1404
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001405 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001406 "getKeyRepeatTimeout", "()I");
1407
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001408 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001409 "getKeyRepeatDelay", "()I");
1410
Jeff Brown774ed9d2011-06-07 17:48:39 -07001411 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapTimeout, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001412 "getHoverTapTimeout", "()I");
1413
Jeff Brown774ed9d2011-06-07 17:48:39 -07001414 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapSlop, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001415 "getHoverTapSlop", "()I");
Jeff Brown214eaf42011-05-26 19:17:02 -07001416
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001417 GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001418 "getDoubleTapTimeout", "()I");
1419
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001420 GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001421 "getLongPressTimeout", "()I");
1422
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001423 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001424 "getMaxEventsPerSecond", "()I");
1425
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001426 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001427 "getPointerLayer", "()I");
1428
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001429 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Jeff Brown2352b972011-04-12 22:39:53 -07001430 "getPointerIcon", "()Landroid/view/PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001431
Jeff Brown6ec402b2010-07-28 15:48:59 -07001432 // KeyEvent
1433
1434 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001435 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1436
Jeff Brown6ec402b2010-07-28 15:48:59 -07001437
Jeff Brown8d608662010-08-30 03:02:23 -07001438 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001439
1440 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001441 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001442
Jeff Brown8d608662010-08-30 03:02:23 -07001443 // InputDevice
1444
1445 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001446 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001447
1448 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1449 "<init>", "()V");
1450
1451 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001452 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001453
1454 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1455 "mId", "I");
1456
1457 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1458 "mName", "Ljava/lang/String;");
1459
1460 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1461 "mSources", "I");
1462
1463 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1464 "mKeyboardType", "I");
1465
Jeff Brown57c59372010-09-21 18:22:55 -07001466 // Configuration
1467
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001468 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001469
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001470 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001471 "touchscreen", "I");
1472
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001473 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001474 "keyboard", "I");
1475
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001476 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001477 "navigation", "I");
1478
Jeff Brown46b9ac02010-04-22 18:58:52 -07001479 return 0;
1480}
1481
Jeff Brown46b9ac02010-04-22 18:58:52 -07001482} /* namespace android */