blob: f2a0a71725d1b834cb47b6babac8445300a16985 [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 Brown214eaf42011-05-26 19:17:02 -0700185 virtual void getReaderConfiguration(InputReaderConfiguration* outConfig);
Jeff Brown83c09682010-12-23 17:50:18 -0800186 virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700187
188 /* --- InputDispatcherPolicyInterface implementation --- */
189
Jeff Browne20c9e02010-10-11 14:20:19 -0700190 virtual void notifySwitch(nsecs_t when, int32_t switchCode, int32_t switchValue,
191 uint32_t policyFlags);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700192 virtual void notifyConfigurationChanged(nsecs_t when);
Jeff Brown519e0242010-09-15 15:18:56 -0700193 virtual nsecs_t notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800194 const sp<InputWindowHandle>& inputWindowHandle);
195 virtual void notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle);
Jeff Brown0029c662011-03-30 02:25:18 -0700196 virtual bool filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags);
Jeff Brown214eaf42011-05-26 19:17:02 -0700197 virtual void getDispatcherConfiguration(InputDispatcherConfiguration* outConfig);
198 virtual bool isKeyRepeatEnabled();
Jeff Brown1f245102010-11-18 20:53:46 -0800199 virtual void interceptKeyBeforeQueueing(const KeyEvent* keyEvent, uint32_t& policyFlags);
Jeff Brown56194eb2011-03-02 19:23:13 -0800200 virtual void interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800201 virtual bool interceptKeyBeforeDispatching(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brownb88102f2010-09-08 11:49:43 -0700202 const KeyEvent* keyEvent, uint32_t policyFlags);
Jeff Brown928e0542011-01-10 11:17:36 -0800203 virtual bool dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800204 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent);
Jeff Brown01ce2e92010-09-26 22:20:12 -0700205 virtual void pokeUserActivity(nsecs_t eventTime, int32_t eventType);
Jeff Brownb88102f2010-09-08 11:49:43 -0700206 virtual bool checkInjectEventsPermissionNonReentrant(
207 int32_t injectorPid, int32_t injectorUid);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700208
Jeff Brown2352b972011-04-12 22:39:53 -0700209 /* --- PointerControllerPolicyInterface implementation --- */
210
211 virtual void loadPointerResources(PointerResources* outResources);
212
Jeff Brown9c3cda02010-06-15 01:31:58 -0700213private:
214 sp<InputManager> mInputManager;
215
Jeff Brown2352b972011-04-12 22:39:53 -0700216 jobject mContextObj;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700217 jobject mCallbacksObj;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800218 sp<Looper> mLooper;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700219
Jeff Brown83c09682010-12-23 17:50:18 -0800220 Mutex mLock;
221 struct Locked {
222 // Display size information.
Jeff Brownbc68a592011-07-25 12:58:12 -0700223 int32_t displayWidth, displayHeight; // -1 when not initialized
224 int32_t displayExternalWidth, displayExternalHeight; // -1 when not initialized
Jeff Brown83c09682010-12-23 17:50:18 -0800225 int32_t displayOrientation;
226
Jeff Brown05dc66a2011-03-02 14:41:58 -0800227 // System UI visibility.
228 int32_t systemUiVisibility;
229
Jeff Brown1a84fd12011-06-02 01:26:32 -0700230 // Pointer speed.
231 int32_t pointerSpeed;
232
Jeff Brown474dcb52011-06-14 20:22:50 -0700233 // True if pointer gestures are enabled.
234 bool pointerGesturesEnabled;
235
Jeff Brown5541de92011-04-11 11:54:25 -0700236 // Sprite controller singleton, created on first use.
237 sp<SpriteController> spriteController;
238
Jeff Brown83c09682010-12-23 17:50:18 -0800239 // Pointer controller singleton, created and destroyed as needed.
240 wp<PointerController> pointerController;
Jeff Brown83c09682010-12-23 17:50:18 -0800241 } mLocked;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700242
Jeff Brown2352b972011-04-12 22:39:53 -0700243 void updateInactivityTimeoutLocked(const sp<PointerController>& controller);
Jeff Brown56194eb2011-03-02 19:23:13 -0800244 void handleInterceptActions(jint wmActions, nsecs_t when, uint32_t& policyFlags);
Jeff Brown5541de92011-04-11 11:54:25 -0700245 void ensureSpriteControllerLocked();
Jeff Brown05dc66a2011-03-02 14:41:58 -0800246
Jeff Brown00fa7bd2010-07-02 15:37:36 -0700247 // Power manager interactions.
Jeff Brown9c3cda02010-06-15 01:31:58 -0700248 bool isScreenOn();
249 bool isScreenBright();
250
Jeff Brownb88102f2010-09-08 11:49:43 -0700251 static bool checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName);
Jeff Browna41ca772010-08-11 14:46:32 -0700252
Jeff Brown9c3cda02010-06-15 01:31:58 -0700253 static inline JNIEnv* jniEnv() {
254 return AndroidRuntime::getJNIEnv();
255 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700256};
257
Jeff Brown928e0542011-01-10 11:17:36 -0800258
Jeff Brown9c3cda02010-06-15 01:31:58 -0700259
Jeff Brown2352b972011-04-12 22:39:53 -0700260NativeInputManager::NativeInputManager(jobject contextObj,
261 jobject callbacksObj, const sp<Looper>& looper) :
Jeff Brown214eaf42011-05-26 19:17:02 -0700262 mLooper(looper) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700263 JNIEnv* env = jniEnv();
264
Jeff Brown2352b972011-04-12 22:39:53 -0700265 mContextObj = env->NewGlobalRef(contextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700266 mCallbacksObj = env->NewGlobalRef(callbacksObj);
267
Jeff Brown83c09682010-12-23 17:50:18 -0800268 {
269 AutoMutex _l(mLock);
270 mLocked.displayWidth = -1;
271 mLocked.displayHeight = -1;
Jeff Brownbc68a592011-07-25 12:58:12 -0700272 mLocked.displayExternalWidth = -1;
273 mLocked.displayExternalHeight = -1;
Jeff Brown65fd2512011-08-18 11:20:58 -0700274 mLocked.displayOrientation = DISPLAY_ORIENTATION_0;
Jeff Brown05dc66a2011-03-02 14:41:58 -0800275
276 mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
Jeff Brown1a84fd12011-06-02 01:26:32 -0700277 mLocked.pointerSpeed = 0;
Jeff Brown474dcb52011-06-14 20:22:50 -0700278 mLocked.pointerGesturesEnabled = true;
Jeff Brown83c09682010-12-23 17:50:18 -0800279 }
280
Jeff Brown9c3cda02010-06-15 01:31:58 -0700281 sp<EventHub> eventHub = new EventHub();
282 mInputManager = new InputManager(eventHub, this, this);
283}
284
285NativeInputManager::~NativeInputManager() {
286 JNIEnv* env = jniEnv();
287
Jeff Brown2352b972011-04-12 22:39:53 -0700288 env->DeleteGlobalRef(mContextObj);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700289 env->DeleteGlobalRef(mCallbacksObj);
290}
291
Jeff Brownb88102f2010-09-08 11:49:43 -0700292void NativeInputManager::dump(String8& dump) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700293 mInputManager->getReader()->dump(dump);
294 dump.append("\n");
Jeff Brown6d0fec22010-07-23 21:28:06 -0700295
Jeff Brownb88102f2010-09-08 11:49:43 -0700296 mInputManager->getDispatcher()->dump(dump);
297 dump.append("\n");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700298}
299
Jeff Brown7fbdc842010-06-17 20:52:56 -0700300bool NativeInputManager::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700301 if (env->ExceptionCheck()) {
302 LOGE("An exception was thrown by callback '%s'.", methodName);
303 LOGE_EX(env);
304 env->ExceptionClear();
305 return true;
306 }
307 return false;
308}
309
Jeff Brownbc68a592011-07-25 12:58:12 -0700310void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height,
311 int32_t externalWidth, int32_t externalHeight) {
Jeff Brown65fd2512011-08-18 11:20:58 -0700312 bool changed = false;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700313 if (displayId == 0) {
Jeff Brown65fd2512011-08-18 11:20:58 -0700314 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700315
Jeff Brown65fd2512011-08-18 11:20:58 -0700316 if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
317 changed = true;
318 mLocked.displayWidth = width;
319 mLocked.displayHeight = height;
Jeff Brownbc68a592011-07-25 12:58:12 -0700320
Jeff Brown65fd2512011-08-18 11:20:58 -0700321 sp<PointerController> controller = mLocked.pointerController.promote();
322 if (controller != NULL) {
323 controller->setDisplaySize(width, height);
Jeff Brown2352b972011-04-12 22:39:53 -0700324 }
Jeff Brown65fd2512011-08-18 11:20:58 -0700325 }
Jeff Brown2352b972011-04-12 22:39:53 -0700326
Jeff Brown65fd2512011-08-18 11:20:58 -0700327 if (mLocked.displayExternalWidth != externalWidth
328 || mLocked.displayExternalHeight != externalHeight) {
329 changed = true;
Jeff Brownbc68a592011-07-25 12:58:12 -0700330 mLocked.displayExternalWidth = externalWidth;
331 mLocked.displayExternalHeight = externalHeight;
Jeff Brown65fd2512011-08-18 11:20:58 -0700332 }
333 }
334
335 if (changed) {
336 mInputManager->getReader()->requestRefreshConfiguration(
337 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700338 }
339}
340
341void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation) {
Jeff Brown65fd2512011-08-18 11:20:58 -0700342 bool changed = false;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700343 if (displayId == 0) {
Jeff Brown83c09682010-12-23 17:50:18 -0800344 AutoMutex _l(mLock);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700345
Jeff Brown83c09682010-12-23 17:50:18 -0800346 if (mLocked.displayOrientation != orientation) {
Jeff Brown65fd2512011-08-18 11:20:58 -0700347 changed = true;
Jeff Brown83c09682010-12-23 17:50:18 -0800348 mLocked.displayOrientation = orientation;
349
350 sp<PointerController> controller = mLocked.pointerController.promote();
351 if (controller != NULL) {
352 controller->setDisplayOrientation(orientation);
353 }
354 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700355 }
Jeff Brown65fd2512011-08-18 11:20:58 -0700356
357 if (changed) {
358 mInputManager->getReader()->requestRefreshConfiguration(
359 InputReaderConfiguration::CHANGE_DISPLAY_INFO);
360 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700361}
362
Jeff Brown7fbdc842010-06-17 20:52:56 -0700363status_t NativeInputManager::registerInputChannel(JNIEnv* env,
Jeff Brown928e0542011-01-10 11:17:36 -0800364 const sp<InputChannel>& inputChannel,
365 const sp<InputWindowHandle>& inputWindowHandle, bool monitor) {
366 return mInputManager->getDispatcher()->registerInputChannel(
367 inputChannel, inputWindowHandle, monitor);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700368}
369
370status_t NativeInputManager::unregisterInputChannel(JNIEnv* env,
371 const sp<InputChannel>& inputChannel) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700372 return mInputManager->getDispatcher()->unregisterInputChannel(inputChannel);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700373}
374
Jeff Brown214eaf42011-05-26 19:17:02 -0700375void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outConfig) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700376 JNIEnv* env = jniEnv();
377
Jeff Brown214eaf42011-05-26 19:17:02 -0700378 jint virtualKeyQuietTime = env->CallIntMethod(mCallbacksObj,
379 gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
380 if (!checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
381 outConfig->virtualKeyQuietTime = milliseconds_to_nanoseconds(virtualKeyQuietTime);
382 }
383
384 outConfig->excludedDeviceNames.clear();
385 jobjectArray excludedDeviceNames = jobjectArray(env->CallObjectMethod(mCallbacksObj,
Jeff Brown9c3cda02010-06-15 01:31:58 -0700386 gCallbacksClassInfo.getExcludedDeviceNames));
Jeff Brown214eaf42011-05-26 19:17:02 -0700387 if (!checkAndClearExceptionFromCallback(env, "getExcludedDeviceNames") && excludedDeviceNames) {
388 jsize length = env->GetArrayLength(excludedDeviceNames);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700389 for (jsize i = 0; i < length; i++) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700390 jstring item = jstring(env->GetObjectArrayElement(excludedDeviceNames, i));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700391 const char* deviceNameChars = env->GetStringUTFChars(item, NULL);
Jeff Brown214eaf42011-05-26 19:17:02 -0700392 outConfig->excludedDeviceNames.add(String8(deviceNameChars));
Jeff Brown9c3cda02010-06-15 01:31:58 -0700393 env->ReleaseStringUTFChars(item, deviceNameChars);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700394 env->DeleteLocalRef(item);
395 }
Jeff Brown214eaf42011-05-26 19:17:02 -0700396 env->DeleteLocalRef(excludedDeviceNames);
397 }
398
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700399 jint hoverTapTimeout = env->CallIntMethod(mCallbacksObj,
400 gCallbacksClassInfo.getHoverTapTimeout);
401 if (!checkAndClearExceptionFromCallback(env, "getHoverTapTimeout")) {
Jeff Brown214eaf42011-05-26 19:17:02 -0700402 jint doubleTapTimeout = env->CallIntMethod(mCallbacksObj,
403 gCallbacksClassInfo.getDoubleTapTimeout);
404 if (!checkAndClearExceptionFromCallback(env, "getDoubleTapTimeout")) {
405 jint longPressTimeout = env->CallIntMethod(mCallbacksObj,
406 gCallbacksClassInfo.getLongPressTimeout);
407 if (!checkAndClearExceptionFromCallback(env, "getLongPressTimeout")) {
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700408 outConfig->pointerGestureTapInterval = milliseconds_to_nanoseconds(hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700409
410 // We must ensure that the tap-drag interval is significantly shorter than
411 // the long-press timeout because the tap is held down for the entire duration
412 // of the double-tap timeout.
413 jint tapDragInterval = max(min(longPressTimeout - 100,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700414 doubleTapTimeout), hoverTapTimeout);
Jeff Brown214eaf42011-05-26 19:17:02 -0700415 outConfig->pointerGestureTapDragInterval =
416 milliseconds_to_nanoseconds(tapDragInterval);
417 }
418 }
419 }
420
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -0700421 jint hoverTapSlop = env->CallIntMethod(mCallbacksObj,
422 gCallbacksClassInfo.getHoverTapSlop);
423 if (!checkAndClearExceptionFromCallback(env, "getHoverTapSlop")) {
424 outConfig->pointerGestureTapSlop = hoverTapSlop;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700425 }
Jeff Brown1a84fd12011-06-02 01:26:32 -0700426
427 { // acquire lock
428 AutoMutex _l(mLock);
429
430 outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
431 * POINTER_SPEED_EXPONENT);
Jeff Brown474dcb52011-06-14 20:22:50 -0700432 outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled;
Jeff Brown65fd2512011-08-18 11:20:58 -0700433
434 outConfig->setDisplayInfo(0, false /*external*/,
435 mLocked.displayWidth, mLocked.displayHeight, mLocked.displayOrientation);
436 outConfig->setDisplayInfo(0, true /*external*/,
437 mLocked.displayExternalWidth, mLocked.displayExternalHeight,
438 mLocked.displayOrientation);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700439 } // release lock
Jeff Brown9c3cda02010-06-15 01:31:58 -0700440}
441
Jeff Brown83c09682010-12-23 17:50:18 -0800442sp<PointerControllerInterface> NativeInputManager::obtainPointerController(int32_t deviceId) {
443 AutoMutex _l(mLock);
444
445 sp<PointerController> controller = mLocked.pointerController.promote();
446 if (controller == NULL) {
Jeff Brown5541de92011-04-11 11:54:25 -0700447 ensureSpriteControllerLocked();
Jeff Brown83c09682010-12-23 17:50:18 -0800448
Jeff Brown2352b972011-04-12 22:39:53 -0700449 controller = new PointerController(this, mLooper, mLocked.spriteController);
Jeff Brown83c09682010-12-23 17:50:18 -0800450 mLocked.pointerController = controller;
451
452 controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
453 controller->setDisplayOrientation(mLocked.displayOrientation);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800454
Jeff Brown5541de92011-04-11 11:54:25 -0700455 JNIEnv* env = jniEnv();
Jeff Brown2352b972011-04-12 22:39:53 -0700456 jobject pointerIconObj = env->CallObjectMethod(mCallbacksObj,
457 gCallbacksClassInfo.getPointerIcon);
458 if (!checkAndClearExceptionFromCallback(env, "getPointerIcon")) {
459 PointerIcon pointerIcon;
460 status_t status = android_view_PointerIcon_load(env, pointerIconObj,
461 mContextObj, &pointerIcon);
462 if (!status && !pointerIcon.isNullIcon()) {
463 controller->setPointerIcon(SpriteIcon(pointerIcon.bitmap,
464 pointerIcon.hotSpotX, pointerIcon.hotSpotY));
465 } else {
466 controller->setPointerIcon(SpriteIcon());
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800467 }
Jeff Brown2352b972011-04-12 22:39:53 -0700468 env->DeleteLocalRef(pointerIconObj);
Jeff Brownb4ff35d2011-01-02 16:37:43 -0800469 }
Jeff Brown05dc66a2011-03-02 14:41:58 -0800470
Jeff Brown2352b972011-04-12 22:39:53 -0700471 updateInactivityTimeoutLocked(controller);
Jeff Brown83c09682010-12-23 17:50:18 -0800472 }
473 return controller;
474}
475
Jeff Brown5541de92011-04-11 11:54:25 -0700476void NativeInputManager::ensureSpriteControllerLocked() {
477 if (mLocked.spriteController == NULL) {
478 JNIEnv* env = jniEnv();
479 jint layer = env->CallIntMethod(mCallbacksObj, gCallbacksClassInfo.getPointerLayer);
480 if (checkAndClearExceptionFromCallback(env, "getPointerLayer")) {
481 layer = -1;
482 }
483 mLocked.spriteController = new SpriteController(mLooper, layer);
484 }
485}
486
Jeff Browne20c9e02010-10-11 14:20:19 -0700487void NativeInputManager::notifySwitch(nsecs_t when, int32_t switchCode,
488 int32_t switchValue, uint32_t policyFlags) {
489#if DEBUG_INPUT_DISPATCHER_POLICY
490 LOGD("notifySwitch - when=%lld, switchCode=%d, switchValue=%d, policyFlags=0x%x",
491 when, switchCode, switchValue, policyFlags);
492#endif
493
494 JNIEnv* env = jniEnv();
495
496 switch (switchCode) {
497 case SW_LID:
498 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyLidSwitchChanged,
499 when, switchValue == 0);
500 checkAndClearExceptionFromCallback(env, "notifyLidSwitchChanged");
501 break;
502 }
503}
504
Jeff Brown9c3cda02010-06-15 01:31:58 -0700505void NativeInputManager::notifyConfigurationChanged(nsecs_t when) {
506#if DEBUG_INPUT_DISPATCHER_POLICY
507 LOGD("notifyConfigurationChanged - when=%lld", when);
508#endif
509
510 JNIEnv* env = jniEnv();
511
Jeff Brown57c59372010-09-21 18:22:55 -0700512 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyConfigurationChanged, when);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700513 checkAndClearExceptionFromCallback(env, "notifyConfigurationChanged");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700514}
515
Jeff Brown519e0242010-09-15 15:18:56 -0700516nsecs_t NativeInputManager::notifyANR(const sp<InputApplicationHandle>& inputApplicationHandle,
Jeff Brown928e0542011-01-10 11:17:36 -0800517 const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700518#if DEBUG_INPUT_DISPATCHER_POLICY
519 LOGD("notifyANR");
520#endif
521
522 JNIEnv* env = jniEnv();
523
Jeff Brown928e0542011-01-10 11:17:36 -0800524 jobject inputApplicationHandleObj =
525 getInputApplicationHandleObjLocalRef(env, inputApplicationHandle);
526 jobject inputWindowHandleObj =
527 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brownb88102f2010-09-08 11:49:43 -0700528
Jeff Brown519e0242010-09-15 15:18:56 -0700529 jlong newTimeout = env->CallLongMethod(mCallbacksObj,
Jeff Brown928e0542011-01-10 11:17:36 -0800530 gCallbacksClassInfo.notifyANR, inputApplicationHandleObj, inputWindowHandleObj);
Jeff Brown519e0242010-09-15 15:18:56 -0700531 if (checkAndClearExceptionFromCallback(env, "notifyANR")) {
532 newTimeout = 0; // abort dispatch
533 } else {
534 assert(newTimeout >= 0);
535 }
536
Jeff Brown928e0542011-01-10 11:17:36 -0800537 env->DeleteLocalRef(inputWindowHandleObj);
538 env->DeleteLocalRef(inputApplicationHandleObj);
Jeff Brownb88102f2010-09-08 11:49:43 -0700539 return newTimeout;
540}
541
Jeff Brown928e0542011-01-10 11:17:36 -0800542void NativeInputManager::notifyInputChannelBroken(const sp<InputWindowHandle>& inputWindowHandle) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700543#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown928e0542011-01-10 11:17:36 -0800544 LOGD("notifyInputChannelBroken");
Jeff Brown9c3cda02010-06-15 01:31:58 -0700545#endif
546
Jeff Brown7fbdc842010-06-17 20:52:56 -0700547 JNIEnv* env = jniEnv();
548
Jeff Brown928e0542011-01-10 11:17:36 -0800549 jobject inputWindowHandleObj =
550 getInputWindowHandleObjLocalRef(env, inputWindowHandle);
551 if (inputWindowHandleObj) {
Jeff Brown7fbdc842010-06-17 20:52:56 -0700552 env->CallVoidMethod(mCallbacksObj, gCallbacksClassInfo.notifyInputChannelBroken,
Jeff Brown928e0542011-01-10 11:17:36 -0800553 inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700554 checkAndClearExceptionFromCallback(env, "notifyInputChannelBroken");
555
Jeff Brown928e0542011-01-10 11:17:36 -0800556 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -0700557 }
Jeff Brown9c3cda02010-06-15 01:31:58 -0700558}
559
Jeff Brown214eaf42011-05-26 19:17:02 -0700560void NativeInputManager::getDispatcherConfiguration(InputDispatcherConfiguration* outConfig) {
561 JNIEnv* env = jniEnv();
Jeff Browna4547672011-03-02 21:38:11 -0800562
Jeff Brown214eaf42011-05-26 19:17:02 -0700563 jint keyRepeatTimeout = env->CallIntMethod(mCallbacksObj,
564 gCallbacksClassInfo.getKeyRepeatTimeout);
565 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatTimeout")) {
566 outConfig->keyRepeatTimeout = milliseconds_to_nanoseconds(keyRepeatTimeout);
567 }
Jeff Browna4547672011-03-02 21:38:11 -0800568
Jeff Brown214eaf42011-05-26 19:17:02 -0700569 jint keyRepeatDelay = env->CallIntMethod(mCallbacksObj,
570 gCallbacksClassInfo.getKeyRepeatDelay);
571 if (!checkAndClearExceptionFromCallback(env, "getKeyRepeatDelay")) {
572 outConfig->keyRepeatDelay = milliseconds_to_nanoseconds(keyRepeatDelay);
573 }
574
575 jint maxEventsPerSecond = env->CallIntMethod(mCallbacksObj,
576 gCallbacksClassInfo.getMaxEventsPerSecond);
577 if (!checkAndClearExceptionFromCallback(env, "getMaxEventsPerSecond")) {
578 outConfig->maxEventsPerSecond = maxEventsPerSecond;
Jeff Brown9c3cda02010-06-15 01:31:58 -0700579 }
580}
581
Jeff Brown214eaf42011-05-26 19:17:02 -0700582bool NativeInputManager::isKeyRepeatEnabled() {
583 // Only enable automatic key repeating when the screen is on.
584 return isScreenOn();
Jeff Brownae9fc032010-08-18 15:51:08 -0700585}
586
Jeff Brown9302c872011-07-13 22:51:29 -0700587void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowHandleObjArray) {
588 Vector<sp<InputWindowHandle> > windowHandles;
Jeff Brown349703e2010-06-22 01:27:15 -0700589
Jeff Brown9302c872011-07-13 22:51:29 -0700590 if (windowHandleObjArray) {
591 jsize length = env->GetArrayLength(windowHandleObjArray);
592 for (jsize i = 0; i < length; i++) {
593 jobject windowHandleObj = env->GetObjectArrayElement(windowHandleObjArray, i);
594 if (! windowHandleObj) {
595 break; // found null element indicating end of used portion of the array
Jeff Brown474dcb52011-06-14 20:22:50 -0700596 }
Jeff Brown9302c872011-07-13 22:51:29 -0700597
598 sp<InputWindowHandle> windowHandle =
599 android_server_InputWindowHandle_getHandle(env, windowHandleObj);
600 if (windowHandle != NULL) {
601 windowHandles.push(windowHandle);
602 }
603 env->DeleteLocalRef(windowHandleObj);
Jeff Brown349703e2010-06-22 01:27:15 -0700604 }
Jeff Brownb88102f2010-09-08 11:49:43 -0700605 }
Jeff Brown349703e2010-06-22 01:27:15 -0700606
Jeff Brown9302c872011-07-13 22:51:29 -0700607 mInputManager->getDispatcher()->setInputWindows(windowHandles);
608
609 // Do this after the dispatcher has updated the window handle state.
610 bool newPointerGesturesEnabled = true;
611 size_t numWindows = windowHandles.size();
612 for (size_t i = 0; i < numWindows; i++) {
613 const sp<InputWindowHandle>& windowHandle = windowHandles.itemAt(i);
614 if (windowHandle->hasFocus && (windowHandle->inputFeatures
615 & InputWindowHandle::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES)) {
616 newPointerGesturesEnabled = false;
617 }
618 }
Jeff Brown474dcb52011-06-14 20:22:50 -0700619
620 uint32_t changes = 0;
621 { // acquire lock
622 AutoMutex _l(mLock);
623
624 if (mLocked.pointerGesturesEnabled != newPointerGesturesEnabled) {
625 mLocked.pointerGesturesEnabled = newPointerGesturesEnabled;
626 changes |= InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT;
627 }
628 } // release lock
629
630 if (changes) {
631 mInputManager->getReader()->requestRefreshConfiguration(changes);
632 }
Jeff Brown349703e2010-06-22 01:27:15 -0700633}
634
Jeff Brown9302c872011-07-13 22:51:29 -0700635void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationHandleObj) {
636 sp<InputApplicationHandle> applicationHandle =
637 android_server_InputApplicationHandle_getHandle(env, applicationHandleObj);
638 mInputManager->getDispatcher()->setFocusedApplication(applicationHandle);
Jeff Brown349703e2010-06-22 01:27:15 -0700639}
640
641void NativeInputManager::setInputDispatchMode(bool enabled, bool frozen) {
Jeff Brownb88102f2010-09-08 11:49:43 -0700642 mInputManager->getDispatcher()->setInputDispatchMode(enabled, frozen);
Jeff Brown349703e2010-06-22 01:27:15 -0700643}
644
Jeff Brown05dc66a2011-03-02 14:41:58 -0800645void NativeInputManager::setSystemUiVisibility(int32_t visibility) {
646 AutoMutex _l(mLock);
647
648 if (mLocked.systemUiVisibility != visibility) {
649 mLocked.systemUiVisibility = visibility;
650
651 sp<PointerController> controller = mLocked.pointerController.promote();
652 if (controller != NULL) {
Jeff Brown2352b972011-04-12 22:39:53 -0700653 updateInactivityTimeoutLocked(controller);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800654 }
655 }
656}
657
Jeff Brown2352b972011-04-12 22:39:53 -0700658void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerController>& controller) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800659 bool lightsOut = mLocked.systemUiVisibility & ASYSTEM_UI_VISIBILITY_STATUS_BAR_HIDDEN;
Jeff Brown2352b972011-04-12 22:39:53 -0700660 controller->setInactivityTimeout(lightsOut
661 ? PointerController::INACTIVITY_TIMEOUT_SHORT
662 : PointerController::INACTIVITY_TIMEOUT_NORMAL);
Jeff Brown05dc66a2011-03-02 14:41:58 -0800663}
664
Jeff Brown1a84fd12011-06-02 01:26:32 -0700665void NativeInputManager::setPointerSpeed(int32_t speed) {
Jeff Brown474dcb52011-06-14 20:22:50 -0700666 { // acquire lock
667 AutoMutex _l(mLock);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700668
Jeff Brown474dcb52011-06-14 20:22:50 -0700669 if (mLocked.pointerSpeed == speed) {
670 return;
671 }
672
Jeff Brown1a84fd12011-06-02 01:26:32 -0700673 LOGI("Setting pointer speed to %d.", speed);
674 mLocked.pointerSpeed = speed;
Jeff Brown474dcb52011-06-14 20:22:50 -0700675 } // release lock
Jeff Brown1a84fd12011-06-02 01:26:32 -0700676
Jeff Brown474dcb52011-06-14 20:22:50 -0700677 mInputManager->getReader()->requestRefreshConfiguration(
678 InputReaderConfiguration::CHANGE_POINTER_SPEED);
Jeff Brown1a84fd12011-06-02 01:26:32 -0700679}
680
Jeff Browne20c9e02010-10-11 14:20:19 -0700681bool NativeInputManager::isScreenOn() {
682 return android_server_PowerManagerService_isScreenOn();
683}
684
685bool NativeInputManager::isScreenBright() {
686 return android_server_PowerManagerService_isScreenBright();
687}
688
Jeff Brown0029c662011-03-30 02:25:18 -0700689bool NativeInputManager::filterInputEvent(const InputEvent* inputEvent, uint32_t policyFlags) {
690 jobject inputEventObj;
691
692 JNIEnv* env = jniEnv();
693 switch (inputEvent->getType()) {
694 case AINPUT_EVENT_TYPE_KEY:
695 inputEventObj = android_view_KeyEvent_fromNative(env,
696 static_cast<const KeyEvent*>(inputEvent));
697 break;
698 case AINPUT_EVENT_TYPE_MOTION:
699 inputEventObj = android_view_MotionEvent_obtainAsCopy(env,
700 static_cast<const MotionEvent*>(inputEvent));
701 break;
702 default:
703 return true; // dispatch the event normally
704 }
705
706 if (!inputEventObj) {
707 LOGE("Failed to obtain input event object for filterInputEvent.");
708 return true; // dispatch the event normally
709 }
710
711 // The callee is responsible for recycling the event.
712 jboolean pass = env->CallBooleanMethod(mCallbacksObj, gCallbacksClassInfo.filterInputEvent,
713 inputEventObj, policyFlags);
714 if (checkAndClearExceptionFromCallback(env, "filterInputEvent")) {
715 pass = true;
716 }
717 env->DeleteLocalRef(inputEventObj);
718 return pass;
719}
720
Jeff Brown1f245102010-11-18 20:53:46 -0800721void NativeInputManager::interceptKeyBeforeQueueing(const KeyEvent* keyEvent,
722 uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700723 // Policy:
724 // - Ignore untrusted events and pass them along.
725 // - Ask the window manager what to do with normal events and trusted injected events.
726 // - For normal events wake and brighten the screen if currently off or dim.
727 if ((policyFlags & POLICY_FLAG_TRUSTED)) {
Jeff Brown1f245102010-11-18 20:53:46 -0800728 nsecs_t when = keyEvent->getEventTime();
Jeff Brown3122e442010-10-11 23:32:49 -0700729 bool isScreenOn = this->isScreenOn();
730 bool isScreenBright = this->isScreenBright();
Jeff Browne20c9e02010-10-11 14:20:19 -0700731
Jeff Brown3122e442010-10-11 23:32:49 -0700732 JNIEnv* env = jniEnv();
Jeff Brown1f245102010-11-18 20:53:46 -0800733 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
734 jint wmActions;
735 if (keyEventObj) {
736 wmActions = env->CallIntMethod(mCallbacksObj,
737 gCallbacksClassInfo.interceptKeyBeforeQueueing,
738 keyEventObj, policyFlags, isScreenOn);
739 if (checkAndClearExceptionFromCallback(env, "interceptKeyBeforeQueueing")) {
740 wmActions = 0;
741 }
742 android_view_KeyEvent_recycle(env, keyEventObj);
743 env->DeleteLocalRef(keyEventObj);
744 } else {
745 LOGE("Failed to obtain key event object for interceptKeyBeforeQueueing.");
Jeff Brown3122e442010-10-11 23:32:49 -0700746 wmActions = 0;
Jeff Browne20c9e02010-10-11 14:20:19 -0700747 }
748
Jeff Brown1f245102010-11-18 20:53:46 -0800749 if (!(policyFlags & POLICY_FLAG_INJECTED)) {
Jeff Brown3122e442010-10-11 23:32:49 -0700750 if (!isScreenOn) {
751 policyFlags |= POLICY_FLAG_WOKE_HERE;
Jeff Brown3122e442010-10-11 23:32:49 -0700752 }
753
754 if (!isScreenBright) {
755 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
756 }
Jeff Browne20c9e02010-10-11 14:20:19 -0700757 }
758
Jeff Brown56194eb2011-03-02 19:23:13 -0800759 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Brown3122e442010-10-11 23:32:49 -0700760 } else {
Jeff Browne20c9e02010-10-11 14:20:19 -0700761 policyFlags |= POLICY_FLAG_PASS_TO_USER;
762 }
763}
764
Jeff Brown56194eb2011-03-02 19:23:13 -0800765void NativeInputManager::interceptMotionBeforeQueueing(nsecs_t when, uint32_t& policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700766 // Policy:
767 // - Ignore untrusted events and pass them along.
768 // - No special filtering for injected events required at this time.
769 // - Filter normal events based on screen state.
770 // - For normal events brighten (but do not wake) the screen if currently dim.
771 if ((policyFlags & POLICY_FLAG_TRUSTED) && !(policyFlags & POLICY_FLAG_INJECTED)) {
772 if (isScreenOn()) {
773 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700774
Jeff Brown3122e442010-10-11 23:32:49 -0700775 if (!isScreenBright()) {
776 policyFlags |= POLICY_FLAG_BRIGHT_HERE;
777 }
Jeff Brown56194eb2011-03-02 19:23:13 -0800778 } else {
779 JNIEnv* env = jniEnv();
780 jint wmActions = env->CallIntMethod(mCallbacksObj,
781 gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
782 policyFlags);
783 if (checkAndClearExceptionFromCallback(env,
784 "interceptMotionBeforeQueueingWhenScreenOff")) {
785 wmActions = 0;
786 }
787
788 policyFlags |= POLICY_FLAG_WOKE_HERE | POLICY_FLAG_BRIGHT_HERE;
789 handleInterceptActions(wmActions, when, /*byref*/ policyFlags);
Jeff Browne20c9e02010-10-11 14:20:19 -0700790 }
Jeff Brown3122e442010-10-11 23:32:49 -0700791 } else {
792 policyFlags |= POLICY_FLAG_PASS_TO_USER;
Jeff Browne20c9e02010-10-11 14:20:19 -0700793 }
794}
795
Jeff Brown56194eb2011-03-02 19:23:13 -0800796void NativeInputManager::handleInterceptActions(jint wmActions, nsecs_t when,
797 uint32_t& policyFlags) {
798 enum {
799 WM_ACTION_PASS_TO_USER = 1,
800 WM_ACTION_POKE_USER_ACTIVITY = 2,
801 WM_ACTION_GO_TO_SLEEP = 4,
802 };
803
804 if (wmActions & WM_ACTION_GO_TO_SLEEP) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800805#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800806 LOGD("handleInterceptActions: Going to sleep.");
807#endif
808 android_server_PowerManagerService_goToSleep(when);
809 }
810
811 if (wmActions & WM_ACTION_POKE_USER_ACTIVITY) {
Jeff Brown9267beb2011-03-07 20:11:22 -0800812#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800813 LOGD("handleInterceptActions: Poking user activity.");
814#endif
815 android_server_PowerManagerService_userActivity(when, POWER_MANAGER_BUTTON_EVENT);
816 }
817
818 if (wmActions & WM_ACTION_PASS_TO_USER) {
819 policyFlags |= POLICY_FLAG_PASS_TO_USER;
820 } else {
Jeff Brown9267beb2011-03-07 20:11:22 -0800821#if DEBUG_INPUT_DISPATCHER_POLICY
Jeff Brown56194eb2011-03-02 19:23:13 -0800822 LOGD("handleInterceptActions: Not passing key to user.");
823#endif
824 }
825}
826
Jeff Brown928e0542011-01-10 11:17:36 -0800827bool NativeInputManager::interceptKeyBeforeDispatching(
828 const sp<InputWindowHandle>& inputWindowHandle,
Jeff Browne20c9e02010-10-11 14:20:19 -0700829 const KeyEvent* keyEvent, uint32_t policyFlags) {
Jeff Brown3122e442010-10-11 23:32:49 -0700830 // Policy:
831 // - Ignore untrusted events and pass them along.
832 // - Filter normal events and trusted injected events through the window manager policy to
833 // handle the HOME key and the like.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800834 bool result = false;
Jeff Brown3122e442010-10-11 23:32:49 -0700835 if (policyFlags & POLICY_FLAG_TRUSTED) {
836 JNIEnv* env = jniEnv();
Jeff Brownd0097872010-06-30 14:41:59 -0700837
Jeff Brown928e0542011-01-10 11:17:36 -0800838 // Note: inputWindowHandle may be null.
839 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800840 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
841 if (keyEventObj) {
842 jboolean consumed = env->CallBooleanMethod(mCallbacksObj,
843 gCallbacksClassInfo.interceptKeyBeforeDispatching,
Jeff Brown928e0542011-01-10 11:17:36 -0800844 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brown1f245102010-11-18 20:53:46 -0800845 bool error = checkAndClearExceptionFromCallback(env, "interceptKeyBeforeDispatching");
846 android_view_KeyEvent_recycle(env, keyEventObj);
847 env->DeleteLocalRef(keyEventObj);
848 result = consumed && !error;
849 } else {
850 LOGE("Failed to obtain key event object for interceptKeyBeforeDispatching.");
Jeff Brown1f245102010-11-18 20:53:46 -0800851 }
Jeff Brown928e0542011-01-10 11:17:36 -0800852 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3122e442010-10-11 23:32:49 -0700853 }
Jeff Brown1f245102010-11-18 20:53:46 -0800854 return result;
Jeff Brownd0097872010-06-30 14:41:59 -0700855}
856
Jeff Brown928e0542011-01-10 11:17:36 -0800857bool NativeInputManager::dispatchUnhandledKey(const sp<InputWindowHandle>& inputWindowHandle,
Jeff Brown49ed71d2010-12-06 17:13:33 -0800858 const KeyEvent* keyEvent, uint32_t policyFlags, KeyEvent* outFallbackKeyEvent) {
Jeff Brown3915bb82010-11-05 15:02:16 -0700859 // Policy:
860 // - Ignore untrusted events and do not perform default handling.
Jeff Brown49ed71d2010-12-06 17:13:33 -0800861 bool result = false;
Jeff Brown3915bb82010-11-05 15:02:16 -0700862 if (policyFlags & POLICY_FLAG_TRUSTED) {
863 JNIEnv* env = jniEnv();
864
Jeff Brown928e0542011-01-10 11:17:36 -0800865 // Note: inputWindowHandle may be null.
866 jobject inputWindowHandleObj = getInputWindowHandleObjLocalRef(env, inputWindowHandle);
Jeff Brown1f245102010-11-18 20:53:46 -0800867 jobject keyEventObj = android_view_KeyEvent_fromNative(env, keyEvent);
868 if (keyEventObj) {
Jeff Brown49ed71d2010-12-06 17:13:33 -0800869 jobject fallbackKeyEventObj = env->CallObjectMethod(mCallbacksObj,
Jeff Brown1f245102010-11-18 20:53:46 -0800870 gCallbacksClassInfo.dispatchUnhandledKey,
Jeff Brown928e0542011-01-10 11:17:36 -0800871 inputWindowHandleObj, keyEventObj, policyFlags);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700872 if (checkAndClearExceptionFromCallback(env, "dispatchUnhandledKey")) {
873 fallbackKeyEventObj = NULL;
874 }
Jeff Brown1f245102010-11-18 20:53:46 -0800875 android_view_KeyEvent_recycle(env, keyEventObj);
876 env->DeleteLocalRef(keyEventObj);
Jeff Brown49ed71d2010-12-06 17:13:33 -0800877
878 if (fallbackKeyEventObj) {
879 // Note: outFallbackKeyEvent may be the same object as keyEvent.
880 if (!android_view_KeyEvent_toNative(env, fallbackKeyEventObj,
881 outFallbackKeyEvent)) {
882 result = true;
883 }
884 android_view_KeyEvent_recycle(env, fallbackKeyEventObj);
885 env->DeleteLocalRef(fallbackKeyEventObj);
886 }
Jeff Brown1f245102010-11-18 20:53:46 -0800887 } else {
888 LOGE("Failed to obtain key event object for dispatchUnhandledKey.");
Jeff Brown1f245102010-11-18 20:53:46 -0800889 }
Jeff Brown928e0542011-01-10 11:17:36 -0800890 env->DeleteLocalRef(inputWindowHandleObj);
Jeff Brown3915bb82010-11-05 15:02:16 -0700891 }
Jeff Brown1f245102010-11-18 20:53:46 -0800892 return result;
Jeff Brown3915bb82010-11-05 15:02:16 -0700893}
894
Jeff Brown01ce2e92010-09-26 22:20:12 -0700895void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType) {
896 android_server_PowerManagerService_userActivity(eventTime, eventType);
Jeff Brown349703e2010-06-22 01:27:15 -0700897}
898
Jeff Brown349703e2010-06-22 01:27:15 -0700899
Jeff Brownb88102f2010-09-08 11:49:43 -0700900bool NativeInputManager::checkInjectEventsPermissionNonReentrant(
901 int32_t injectorPid, int32_t injectorUid) {
902 JNIEnv* env = jniEnv();
903 jboolean result = env->CallBooleanMethod(mCallbacksObj,
904 gCallbacksClassInfo.checkInjectEventsPermission, injectorPid, injectorUid);
Jeff Brownda3d5a92011-03-29 15:11:34 -0700905 if (checkAndClearExceptionFromCallback(env, "checkInjectEventsPermission")) {
906 result = false;
907 }
Jeff Brown349703e2010-06-22 01:27:15 -0700908 return result;
909}
910
Jeff Brown2352b972011-04-12 22:39:53 -0700911void NativeInputManager::loadPointerResources(PointerResources* outResources) {
912 JNIEnv* env = jniEnv();
913
914 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_HOVER,
915 &outResources->spotHover);
916 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_TOUCH,
917 &outResources->spotTouch);
918 loadSystemIconAsSprite(env, mContextObj, POINTER_ICON_STYLE_SPOT_ANCHOR,
919 &outResources->spotAnchor);
920}
921
Jeff Brown83c09682010-12-23 17:50:18 -0800922
Jeff Brown9c3cda02010-06-15 01:31:58 -0700923// ----------------------------------------------------------------------------
924
925static sp<NativeInputManager> gNativeInputManager;
926
Jeff Brown46b9ac02010-04-22 18:58:52 -0700927static bool checkInputManagerUnitialized(JNIEnv* env) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700928 if (gNativeInputManager == NULL) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700929 LOGE("Input manager not initialized.");
930 jniThrowRuntimeException(env, "Input manager not initialized.");
931 return true;
932 }
933 return false;
934}
935
936static void android_server_InputManager_nativeInit(JNIEnv* env, jclass clazz,
Jeff Brown2352b972011-04-12 22:39:53 -0700937 jobject contextObj, jobject callbacksObj, jobject messageQueueObj) {
Jeff Brown9c3cda02010-06-15 01:31:58 -0700938 if (gNativeInputManager == NULL) {
Jeff Brown05dc66a2011-03-02 14:41:58 -0800939 sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj);
Jeff Brown2352b972011-04-12 22:39:53 -0700940 gNativeInputManager = new NativeInputManager(contextObj, callbacksObj, looper);
Jeff Brown9c3cda02010-06-15 01:31:58 -0700941 } else {
942 LOGE("Input manager already initialized.");
943 jniThrowRuntimeException(env, "Input manager already initialized.");
Jeff Brown46b9ac02010-04-22 18:58:52 -0700944 }
945}
946
947static void android_server_InputManager_nativeStart(JNIEnv* env, jclass clazz) {
948 if (checkInputManagerUnitialized(env)) {
949 return;
950 }
951
Jeff Brown9c3cda02010-06-15 01:31:58 -0700952 status_t result = gNativeInputManager->getInputManager()->start();
Jeff Brown46b9ac02010-04-22 18:58:52 -0700953 if (result) {
954 jniThrowRuntimeException(env, "Input manager could not be started.");
955 }
956}
957
958static void android_server_InputManager_nativeSetDisplaySize(JNIEnv* env, jclass clazz,
Jeff Brownbc68a592011-07-25 12:58:12 -0700959 jint displayId, jint width, jint height, jint externalWidth, jint externalHeight) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700960 if (checkInputManagerUnitialized(env)) {
961 return;
962 }
963
964 // XXX we could get this from the SurfaceFlinger directly instead of requiring it
965 // to be passed in like this, not sure which is better but leaving it like this
966 // keeps the window manager in direct control of when display transitions propagate down
967 // to the input dispatcher
Jeff Brownbc68a592011-07-25 12:58:12 -0700968 gNativeInputManager->setDisplaySize(displayId, width, height, externalWidth, externalHeight);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700969}
970
971static void android_server_InputManager_nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
972 jint displayId, jint orientation) {
973 if (checkInputManagerUnitialized(env)) {
974 return;
975 }
976
Jeff Brown9c3cda02010-06-15 01:31:58 -0700977 gNativeInputManager->setDisplayOrientation(displayId, orientation);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700978}
979
980static jint android_server_InputManager_nativeGetScanCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700981 jint deviceId, jint sourceMask, jint scanCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700982 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700983 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700984 }
985
Jeff Brownb88102f2010-09-08 11:49:43 -0700986 return gNativeInputManager->getInputManager()->getReader()->getScanCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700987 deviceId, uint32_t(sourceMask), scanCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700988}
989
990static jint android_server_InputManager_nativeGetKeyCodeState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -0700991 jint deviceId, jint sourceMask, jint keyCode) {
Jeff Brown46b9ac02010-04-22 18:58:52 -0700992 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -0700993 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -0700994 }
995
Jeff Brownb88102f2010-09-08 11:49:43 -0700996 return gNativeInputManager->getInputManager()->getReader()->getKeyCodeState(
Jeff Brown6d0fec22010-07-23 21:28:06 -0700997 deviceId, uint32_t(sourceMask), keyCode);
Jeff Brown46b9ac02010-04-22 18:58:52 -0700998}
999
1000static jint android_server_InputManager_nativeGetSwitchState(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001001 jint deviceId, jint sourceMask, jint sw) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001002 if (checkInputManagerUnitialized(env)) {
Jeff Brownc5ed5912010-07-14 18:48:53 -07001003 return AKEY_STATE_UNKNOWN;
Jeff Brown46b9ac02010-04-22 18:58:52 -07001004 }
1005
Jeff Brownb88102f2010-09-08 11:49:43 -07001006 return gNativeInputManager->getInputManager()->getReader()->getSwitchState(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001007 deviceId, uint32_t(sourceMask), sw);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001008}
1009
1010static jboolean android_server_InputManager_nativeHasKeys(JNIEnv* env, jclass clazz,
Jeff Brown6d0fec22010-07-23 21:28:06 -07001011 jint deviceId, jint sourceMask, jintArray keyCodes, jbooleanArray outFlags) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001012 if (checkInputManagerUnitialized(env)) {
1013 return JNI_FALSE;
1014 }
1015
1016 int32_t* codes = env->GetIntArrayElements(keyCodes, NULL);
1017 uint8_t* flags = env->GetBooleanArrayElements(outFlags, NULL);
1018 jsize numCodes = env->GetArrayLength(keyCodes);
1019 jboolean result;
Jeff Brown6d0fec22010-07-23 21:28:06 -07001020 if (numCodes == env->GetArrayLength(keyCodes)) {
Jeff Brownb88102f2010-09-08 11:49:43 -07001021 result = gNativeInputManager->getInputManager()->getReader()->hasKeys(
Jeff Brown6d0fec22010-07-23 21:28:06 -07001022 deviceId, uint32_t(sourceMask), numCodes, codes, flags);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001023 } else {
1024 result = JNI_FALSE;
1025 }
1026
1027 env->ReleaseBooleanArrayElements(outFlags, flags, 0);
1028 env->ReleaseIntArrayElements(keyCodes, codes, 0);
1029 return result;
1030}
1031
1032static void throwInputChannelNotInitialized(JNIEnv* env) {
1033 jniThrowException(env, "java/lang/IllegalStateException",
1034 "inputChannel is not initialized");
1035}
1036
1037static void android_server_InputManager_handleInputChannelDisposed(JNIEnv* env,
1038 jobject inputChannelObj, const sp<InputChannel>& inputChannel, void* data) {
1039 LOGW("Input channel object '%s' was disposed without first being unregistered with "
1040 "the input manager!", inputChannel->getName().string());
1041
Jeff Brown9c3cda02010-06-15 01:31:58 -07001042 if (gNativeInputManager != NULL) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001043 gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown9c3cda02010-06-15 01:31:58 -07001044 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001045}
1046
1047static void android_server_InputManager_nativeRegisterInputChannel(JNIEnv* env, jclass clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001048 jobject inputChannelObj, jobject inputWindowHandleObj, jboolean monitor) {
Jeff Brown46b9ac02010-04-22 18:58:52 -07001049 if (checkInputManagerUnitialized(env)) {
1050 return;
1051 }
1052
1053 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1054 inputChannelObj);
1055 if (inputChannel == NULL) {
1056 throwInputChannelNotInitialized(env);
1057 return;
1058 }
1059
Jeff Brown928e0542011-01-10 11:17:36 -08001060 sp<InputWindowHandle> inputWindowHandle =
1061 android_server_InputWindowHandle_getHandle(env, inputWindowHandleObj);
Jeff Brown7fbdc842010-06-17 20:52:56 -07001062
1063 status_t status = gNativeInputManager->registerInputChannel(
Jeff Brown928e0542011-01-10 11:17:36 -08001064 env, inputChannel, inputWindowHandle, monitor);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001065 if (status) {
1066 jniThrowRuntimeException(env, "Failed to register input channel. "
1067 "Check logs for details.");
1068 return;
1069 }
1070
Jeff Browna41ca772010-08-11 14:46:32 -07001071 if (! monitor) {
1072 android_view_InputChannel_setDisposeCallback(env, inputChannelObj,
1073 android_server_InputManager_handleInputChannelDisposed, NULL);
1074 }
Jeff Brown46b9ac02010-04-22 18:58:52 -07001075}
1076
1077static void android_server_InputManager_nativeUnregisterInputChannel(JNIEnv* env, jclass clazz,
1078 jobject inputChannelObj) {
1079 if (checkInputManagerUnitialized(env)) {
1080 return;
1081 }
1082
1083 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
1084 inputChannelObj);
1085 if (inputChannel == NULL) {
1086 throwInputChannelNotInitialized(env);
1087 return;
1088 }
1089
1090 android_view_InputChannel_setDisposeCallback(env, inputChannelObj, NULL, NULL);
1091
Jeff Brown7fbdc842010-06-17 20:52:56 -07001092 status_t status = gNativeInputManager->unregisterInputChannel(env, inputChannel);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001093 if (status) {
1094 jniThrowRuntimeException(env, "Failed to unregister input channel. "
1095 "Check logs for details.");
1096 }
1097}
1098
Jeff Brown0029c662011-03-30 02:25:18 -07001099static void android_server_InputManager_nativeSetInputFilterEnabled(JNIEnv* env, jclass clazz,
1100 jboolean enabled) {
1101 if (checkInputManagerUnitialized(env)) {
1102 return;
1103 }
1104
1105 gNativeInputManager->getInputManager()->getDispatcher()->setInputFilterEnabled(enabled);
1106}
1107
Jeff Brown6ec402b2010-07-28 15:48:59 -07001108static jint android_server_InputManager_nativeInjectInputEvent(JNIEnv* env, jclass clazz,
1109 jobject inputEventObj, jint injectorPid, jint injectorUid,
Jeff Brown0029c662011-03-30 02:25:18 -07001110 jint syncMode, jint timeoutMillis, jint policyFlags) {
Jeff Brown7fbdc842010-06-17 20:52:56 -07001111 if (checkInputManagerUnitialized(env)) {
1112 return INPUT_EVENT_INJECTION_FAILED;
1113 }
1114
Jeff Brown6ec402b2010-07-28 15:48:59 -07001115 if (env->IsInstanceOf(inputEventObj, gKeyEventClassInfo.clazz)) {
1116 KeyEvent keyEvent;
Jeff Brown1f245102010-11-18 20:53:46 -08001117 status_t status = android_view_KeyEvent_toNative(env, inputEventObj, & keyEvent);
1118 if (status) {
1119 jniThrowRuntimeException(env, "Could not read contents of KeyEvent object.");
1120 return INPUT_EVENT_INJECTION_FAILED;
1121 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001122
Jeff Brownb88102f2010-09-08 11:49:43 -07001123 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001124 & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1125 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001126 } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) {
Jeff Brown2ed24622011-03-14 19:39:54 -07001127 const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj);
1128 if (!motionEvent) {
Jeff Brown1f245102010-11-18 20:53:46 -08001129 jniThrowRuntimeException(env, "Could not read contents of MotionEvent object.");
1130 return INPUT_EVENT_INJECTION_FAILED;
1131 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001132
Jeff Brownb88102f2010-09-08 11:49:43 -07001133 return gNativeInputManager->getInputManager()->getDispatcher()->injectInputEvent(
Jeff Brown0029c662011-03-30 02:25:18 -07001134 motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis,
1135 uint32_t(policyFlags));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001136 } else {
1137 jniThrowRuntimeException(env, "Invalid input event type.");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001138 return INPUT_EVENT_INJECTION_FAILED;
1139 }
Jeff Brown7fbdc842010-06-17 20:52:56 -07001140}
1141
Jeff Brown349703e2010-06-22 01:27:15 -07001142static void android_server_InputManager_nativeSetInputWindows(JNIEnv* env, jclass clazz,
Jeff Brown9302c872011-07-13 22:51:29 -07001143 jobjectArray windowHandleObjArray) {
Jeff Brown349703e2010-06-22 01:27:15 -07001144 if (checkInputManagerUnitialized(env)) {
1145 return;
1146 }
1147
Jeff Brown9302c872011-07-13 22:51:29 -07001148 gNativeInputManager->setInputWindows(env, windowHandleObjArray);
Jeff Brown349703e2010-06-22 01:27:15 -07001149}
1150
1151static void android_server_InputManager_nativeSetFocusedApplication(JNIEnv* env, jclass clazz,
Jeff Brown9302c872011-07-13 22:51:29 -07001152 jobject applicationHandleObj) {
Jeff Brown349703e2010-06-22 01:27:15 -07001153 if (checkInputManagerUnitialized(env)) {
1154 return;
1155 }
1156
Jeff Brown9302c872011-07-13 22:51:29 -07001157 gNativeInputManager->setFocusedApplication(env, applicationHandleObj);
Jeff Brown349703e2010-06-22 01:27:15 -07001158}
1159
1160static void android_server_InputManager_nativeSetInputDispatchMode(JNIEnv* env,
1161 jclass clazz, jboolean enabled, jboolean frozen) {
1162 if (checkInputManagerUnitialized(env)) {
1163 return;
1164 }
1165
1166 gNativeInputManager->setInputDispatchMode(enabled, frozen);
1167}
1168
Jeff Brown05dc66a2011-03-02 14:41:58 -08001169static void android_server_InputManager_nativeSetSystemUiVisibility(JNIEnv* env,
1170 jclass clazz, jint visibility) {
1171 if (checkInputManagerUnitialized(env)) {
1172 return;
1173 }
1174
1175 gNativeInputManager->setSystemUiVisibility(visibility);
1176}
1177
Jeff Brown8d608662010-08-30 03:02:23 -07001178static jobject android_server_InputManager_nativeGetInputDevice(JNIEnv* env,
1179 jclass clazz, jint deviceId) {
1180 if (checkInputManagerUnitialized(env)) {
1181 return NULL;
1182 }
1183
1184 InputDeviceInfo deviceInfo;
Jeff Brownb88102f2010-09-08 11:49:43 -07001185 status_t status = gNativeInputManager->getInputManager()->getReader()->getInputDeviceInfo(
Jeff Brown8d608662010-08-30 03:02:23 -07001186 deviceId, & deviceInfo);
1187 if (status) {
1188 return NULL;
1189 }
1190
1191 jobject deviceObj = env->NewObject(gInputDeviceClassInfo.clazz, gInputDeviceClassInfo.ctor);
1192 if (! deviceObj) {
1193 return NULL;
1194 }
1195
1196 jstring deviceNameObj = env->NewStringUTF(deviceInfo.getName().string());
1197 if (! deviceNameObj) {
1198 return NULL;
1199 }
1200
1201 env->SetIntField(deviceObj, gInputDeviceClassInfo.mId, deviceInfo.getId());
1202 env->SetObjectField(deviceObj, gInputDeviceClassInfo.mName, deviceNameObj);
1203 env->SetIntField(deviceObj, gInputDeviceClassInfo.mSources, deviceInfo.getSources());
1204 env->SetIntField(deviceObj, gInputDeviceClassInfo.mKeyboardType, deviceInfo.getKeyboardType());
1205
Jeff Brownefd32662011-03-08 15:13:06 -08001206 const Vector<InputDeviceInfo::MotionRange>& ranges = deviceInfo.getMotionRanges();
Jeff Brown8d608662010-08-30 03:02:23 -07001207 for (size_t i = 0; i < ranges.size(); i++) {
Jeff Brownefd32662011-03-08 15:13:06 -08001208 const InputDeviceInfo::MotionRange& range = ranges.itemAt(i);
Jeff Brown8d608662010-08-30 03:02:23 -07001209 env->CallVoidMethod(deviceObj, gInputDeviceClassInfo.addMotionRange,
Jeff Brownefd32662011-03-08 15:13:06 -08001210 range.axis, range.source, range.min, range.max, range.flat, range.fuzz);
Jeff Brown8d608662010-08-30 03:02:23 -07001211 if (env->ExceptionCheck()) {
1212 return NULL;
1213 }
1214 }
1215
1216 return deviceObj;
1217}
1218
1219static jintArray android_server_InputManager_nativeGetInputDeviceIds(JNIEnv* env,
1220 jclass clazz) {
1221 if (checkInputManagerUnitialized(env)) {
1222 return NULL;
1223 }
1224
1225 Vector<int> deviceIds;
Jeff Brownb88102f2010-09-08 11:49:43 -07001226 gNativeInputManager->getInputManager()->getReader()->getInputDeviceIds(deviceIds);
Jeff Brown8d608662010-08-30 03:02:23 -07001227
1228 jintArray deviceIdsObj = env->NewIntArray(deviceIds.size());
1229 if (! deviceIdsObj) {
1230 return NULL;
1231 }
1232
1233 env->SetIntArrayRegion(deviceIdsObj, 0, deviceIds.size(), deviceIds.array());
1234 return deviceIdsObj;
1235}
1236
Jeff Brown57c59372010-09-21 18:22:55 -07001237static void android_server_InputManager_nativeGetInputConfiguration(JNIEnv* env,
1238 jclass clazz, jobject configObj) {
1239 if (checkInputManagerUnitialized(env)) {
1240 return;
1241 }
1242
1243 InputConfiguration config;
1244 gNativeInputManager->getInputManager()->getReader()->getInputConfiguration(& config);
1245
1246 env->SetIntField(configObj, gConfigurationClassInfo.touchscreen, config.touchScreen);
1247 env->SetIntField(configObj, gConfigurationClassInfo.keyboard, config.keyboard);
1248 env->SetIntField(configObj, gConfigurationClassInfo.navigation, config.navigation);
1249}
1250
Jeff Browne6504122010-09-27 14:52:15 -07001251static jboolean android_server_InputManager_nativeTransferTouchFocus(JNIEnv* env,
1252 jclass clazz, jobject fromChannelObj, jobject toChannelObj) {
1253 if (checkInputManagerUnitialized(env)) {
1254 return false;
1255 }
1256
1257 sp<InputChannel> fromChannel =
1258 android_view_InputChannel_getInputChannel(env, fromChannelObj);
1259 sp<InputChannel> toChannel =
1260 android_view_InputChannel_getInputChannel(env, toChannelObj);
1261
1262 if (fromChannel == NULL || toChannel == NULL) {
1263 return false;
1264 }
1265
1266 return gNativeInputManager->getInputManager()->getDispatcher()->
1267 transferTouchFocus(fromChannel, toChannel);
1268}
1269
Jeff Brown1a84fd12011-06-02 01:26:32 -07001270static void android_server_InputManager_nativeSetPointerSpeed(JNIEnv* env,
1271 jclass clazz, jint speed) {
1272 if (checkInputManagerUnitialized(env)) {
1273 return;
1274 }
1275
1276 gNativeInputManager->setPointerSpeed(speed);
1277}
1278
Jeff Browne33348b2010-07-15 23:54:05 -07001279static jstring android_server_InputManager_nativeDump(JNIEnv* env, jclass clazz) {
1280 if (checkInputManagerUnitialized(env)) {
1281 return NULL;
1282 }
1283
Jeff Brownb88102f2010-09-08 11:49:43 -07001284 String8 dump;
1285 gNativeInputManager->dump(dump);
Jeff Browne33348b2010-07-15 23:54:05 -07001286 return env->NewStringUTF(dump.string());
1287}
1288
Jeff Brown89ef0722011-08-10 16:25:21 -07001289static void android_server_InputManager_nativeMonitor(JNIEnv* env, jclass clazz) {
1290 if (checkInputManagerUnitialized(env)) {
1291 return;
1292 }
1293
1294 gNativeInputManager->getInputManager()->getReader()->monitor();
1295 gNativeInputManager->getInputManager()->getDispatcher()->monitor();
1296}
1297
Jeff Brown9c3cda02010-06-15 01:31:58 -07001298// ----------------------------------------------------------------------------
1299
Jeff Brown46b9ac02010-04-22 18:58:52 -07001300static JNINativeMethod gInputManagerMethods[] = {
1301 /* name, signature, funcPtr */
Jeff Brown2352b972011-04-12 22:39:53 -07001302 { "nativeInit", "(Landroid/content/Context;"
1303 "Lcom/android/server/wm/InputManager$Callbacks;Landroid/os/MessageQueue;)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001304 (void*) android_server_InputManager_nativeInit },
1305 { "nativeStart", "()V",
1306 (void*) android_server_InputManager_nativeStart },
Jeff Brownbc68a592011-07-25 12:58:12 -07001307 { "nativeSetDisplaySize", "(IIIII)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001308 (void*) android_server_InputManager_nativeSetDisplaySize },
1309 { "nativeSetDisplayOrientation", "(II)V",
1310 (void*) android_server_InputManager_nativeSetDisplayOrientation },
1311 { "nativeGetScanCodeState", "(III)I",
1312 (void*) android_server_InputManager_nativeGetScanCodeState },
1313 { "nativeGetKeyCodeState", "(III)I",
1314 (void*) android_server_InputManager_nativeGetKeyCodeState },
1315 { "nativeGetSwitchState", "(III)I",
1316 (void*) android_server_InputManager_nativeGetSwitchState },
Jeff Brown6d0fec22010-07-23 21:28:06 -07001317 { "nativeHasKeys", "(II[I[Z)Z",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001318 (void*) android_server_InputManager_nativeHasKeys },
Jeff Brown928e0542011-01-10 11:17:36 -08001319 { "nativeRegisterInputChannel",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001320 "(Landroid/view/InputChannel;Lcom/android/server/wm/InputWindowHandle;Z)V",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001321 (void*) android_server_InputManager_nativeRegisterInputChannel },
1322 { "nativeUnregisterInputChannel", "(Landroid/view/InputChannel;)V",
Jeff Brown7fbdc842010-06-17 20:52:56 -07001323 (void*) android_server_InputManager_nativeUnregisterInputChannel },
Jeff Brown0029c662011-03-30 02:25:18 -07001324 { "nativeSetInputFilterEnabled", "(Z)V",
1325 (void*) android_server_InputManager_nativeSetInputFilterEnabled },
1326 { "nativeInjectInputEvent", "(Landroid/view/InputEvent;IIIII)I",
Jeff Brown6ec402b2010-07-28 15:48:59 -07001327 (void*) android_server_InputManager_nativeInjectInputEvent },
Jeff Brown9302c872011-07-13 22:51:29 -07001328 { "nativeSetInputWindows", "([Lcom/android/server/wm/InputWindowHandle;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001329 (void*) android_server_InputManager_nativeSetInputWindows },
Jeff Brown9302c872011-07-13 22:51:29 -07001330 { "nativeSetFocusedApplication", "(Lcom/android/server/wm/InputApplicationHandle;)V",
Jeff Brown349703e2010-06-22 01:27:15 -07001331 (void*) android_server_InputManager_nativeSetFocusedApplication },
1332 { "nativeSetInputDispatchMode", "(ZZ)V",
1333 (void*) android_server_InputManager_nativeSetInputDispatchMode },
Jeff Brown05dc66a2011-03-02 14:41:58 -08001334 { "nativeSetSystemUiVisibility", "(I)V",
1335 (void*) android_server_InputManager_nativeSetSystemUiVisibility },
Jeff Brown8d608662010-08-30 03:02:23 -07001336 { "nativeGetInputDevice", "(I)Landroid/view/InputDevice;",
1337 (void*) android_server_InputManager_nativeGetInputDevice },
1338 { "nativeGetInputDeviceIds", "()[I",
1339 (void*) android_server_InputManager_nativeGetInputDeviceIds },
Jeff Brown57c59372010-09-21 18:22:55 -07001340 { "nativeGetInputConfiguration", "(Landroid/content/res/Configuration;)V",
1341 (void*) android_server_InputManager_nativeGetInputConfiguration },
Jeff Browne6504122010-09-27 14:52:15 -07001342 { "nativeTransferTouchFocus", "(Landroid/view/InputChannel;Landroid/view/InputChannel;)Z",
1343 (void*) android_server_InputManager_nativeTransferTouchFocus },
Jeff Brown1a84fd12011-06-02 01:26:32 -07001344 { "nativeSetPointerSpeed", "(I)V",
1345 (void*) android_server_InputManager_nativeSetPointerSpeed },
Jeff Browne33348b2010-07-15 23:54:05 -07001346 { "nativeDump", "()Ljava/lang/String;",
1347 (void*) android_server_InputManager_nativeDump },
Jeff Brown89ef0722011-08-10 16:25:21 -07001348 { "nativeMonitor", "()V",
1349 (void*) android_server_InputManager_nativeMonitor },
Jeff Brown46b9ac02010-04-22 18:58:52 -07001350};
1351
1352#define FIND_CLASS(var, className) \
1353 var = env->FindClass(className); \
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001354 LOG_FATAL_IF(! var, "Unable to find class " className);
Jeff Brown46b9ac02010-04-22 18:58:52 -07001355
1356#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \
1357 var = env->GetMethodID(clazz, methodName, methodDescriptor); \
1358 LOG_FATAL_IF(! var, "Unable to find method " methodName);
1359
1360#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
1361 var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
1362 LOG_FATAL_IF(! var, "Unable to find field " fieldName);
1363
1364int register_android_server_InputManager(JNIEnv* env) {
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001365 int res = jniRegisterNativeMethods(env, "com/android/server/wm/InputManager",
Jeff Brown46b9ac02010-04-22 18:58:52 -07001366 gInputManagerMethods, NELEM(gInputManagerMethods));
1367 LOG_FATAL_IF(res < 0, "Unable to register native methods.");
1368
Jeff Brown9c3cda02010-06-15 01:31:58 -07001369 // Callbacks
Jeff Brown46b9ac02010-04-22 18:58:52 -07001370
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001371 jclass clazz;
1372 FIND_CLASS(clazz, "com/android/server/wm/InputManager$Callbacks");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001373
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001374 GET_METHOD_ID(gCallbacksClassInfo.notifyConfigurationChanged, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001375 "notifyConfigurationChanged", "(J)V");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001376
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001377 GET_METHOD_ID(gCallbacksClassInfo.notifyLidSwitchChanged, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001378 "notifyLidSwitchChanged", "(JZ)V");
1379
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001380 GET_METHOD_ID(gCallbacksClassInfo.notifyInputChannelBroken, clazz,
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001381 "notifyInputChannelBroken", "(Lcom/android/server/wm/InputWindowHandle;)V");
Jeff Brown7fbdc842010-06-17 20:52:56 -07001382
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001383 GET_METHOD_ID(gCallbacksClassInfo.notifyANR, clazz,
Jeff Brown928e0542011-01-10 11:17:36 -08001384 "notifyANR",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001385 "(Lcom/android/server/wm/InputApplicationHandle;Lcom/android/server/wm/InputWindowHandle;)J");
Jeff Brown349703e2010-06-22 01:27:15 -07001386
Jeff Brown0029c662011-03-30 02:25:18 -07001387 GET_METHOD_ID(gCallbacksClassInfo.filterInputEvent, clazz,
1388 "filterInputEvent", "(Landroid/view/InputEvent;I)Z");
1389
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001390 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeQueueing, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001391 "interceptKeyBeforeQueueing", "(Landroid/view/KeyEvent;IZ)I");
Jeff Brown349703e2010-06-22 01:27:15 -07001392
Jeff Brown56194eb2011-03-02 19:23:13 -08001393 GET_METHOD_ID(gCallbacksClassInfo.interceptMotionBeforeQueueingWhenScreenOff,
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001394 clazz,
Jeff Brown56194eb2011-03-02 19:23:13 -08001395 "interceptMotionBeforeQueueingWhenScreenOff", "(I)I");
1396
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001397 GET_METHOD_ID(gCallbacksClassInfo.interceptKeyBeforeDispatching, clazz,
Jeff Brown1f245102010-11-18 20:53:46 -08001398 "interceptKeyBeforeDispatching",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001399 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Z");
Jeff Brown349703e2010-06-22 01:27:15 -07001400
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001401 GET_METHOD_ID(gCallbacksClassInfo.dispatchUnhandledKey, clazz,
Jeff Brown49ed71d2010-12-06 17:13:33 -08001402 "dispatchUnhandledKey",
Dianne Hackborna924dc0d2011-02-17 14:22:17 -08001403 "(Lcom/android/server/wm/InputWindowHandle;Landroid/view/KeyEvent;I)Landroid/view/KeyEvent;");
Jeff Brown3915bb82010-11-05 15:02:16 -07001404
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001405 GET_METHOD_ID(gCallbacksClassInfo.checkInjectEventsPermission, clazz,
Jeff Brown349703e2010-06-22 01:27:15 -07001406 "checkInjectEventsPermission", "(II)Z");
Jeff Brown46b9ac02010-04-22 18:58:52 -07001407
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001408 GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, clazz,
Jeff Brownfe508922011-01-18 15:10:10 -08001409 "getVirtualKeyQuietTimeMillis", "()I");
1410
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001411 GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, clazz,
Jeff Brown46b9ac02010-04-22 18:58:52 -07001412 "getExcludedDeviceNames", "()[Ljava/lang/String;");
1413
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001414 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatTimeout, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001415 "getKeyRepeatTimeout", "()I");
1416
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001417 GET_METHOD_ID(gCallbacksClassInfo.getKeyRepeatDelay, clazz,
Jeff Browna4547672011-03-02 21:38:11 -08001418 "getKeyRepeatDelay", "()I");
1419
Jeff Brown774ed9d2011-06-07 17:48:39 -07001420 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapTimeout, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001421 "getHoverTapTimeout", "()I");
1422
Jeff Brown774ed9d2011-06-07 17:48:39 -07001423 GET_METHOD_ID(gCallbacksClassInfo.getHoverTapSlop, clazz,
Jeff Brownbb3fcba0c2011-06-06 19:23:05 -07001424 "getHoverTapSlop", "()I");
Jeff Brown214eaf42011-05-26 19:17:02 -07001425
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001426 GET_METHOD_ID(gCallbacksClassInfo.getDoubleTapTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001427 "getDoubleTapTimeout", "()I");
1428
Dianne Hackbornf3b57de2011-06-03 12:13:24 -07001429 GET_METHOD_ID(gCallbacksClassInfo.getLongPressTimeout, clazz,
Jeff Brown214eaf42011-05-26 19:17:02 -07001430 "getLongPressTimeout", "()I");
1431
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001432 GET_METHOD_ID(gCallbacksClassInfo.getMaxEventsPerSecond, clazz,
Jeff Brownae9fc032010-08-18 15:51:08 -07001433 "getMaxEventsPerSecond", "()I");
1434
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001435 GET_METHOD_ID(gCallbacksClassInfo.getPointerLayer, clazz,
Jeff Brown83c09682010-12-23 17:50:18 -08001436 "getPointerLayer", "()I");
1437
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001438 GET_METHOD_ID(gCallbacksClassInfo.getPointerIcon, clazz,
Jeff Brown2352b972011-04-12 22:39:53 -07001439 "getPointerIcon", "()Landroid/view/PointerIcon;");
Jeff Brownb4ff35d2011-01-02 16:37:43 -08001440
Jeff Brown6ec402b2010-07-28 15:48:59 -07001441 // KeyEvent
1442
1443 FIND_CLASS(gKeyEventClassInfo.clazz, "android/view/KeyEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001444 gKeyEventClassInfo.clazz = jclass(env->NewGlobalRef(gKeyEventClassInfo.clazz));
1445
Jeff Brown6ec402b2010-07-28 15:48:59 -07001446
Jeff Brown8d608662010-08-30 03:02:23 -07001447 // MotionEvent
Jeff Brown6ec402b2010-07-28 15:48:59 -07001448
1449 FIND_CLASS(gMotionEventClassInfo.clazz, "android/view/MotionEvent");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001450 gMotionEventClassInfo.clazz = jclass(env->NewGlobalRef(gMotionEventClassInfo.clazz));
Jeff Brown6ec402b2010-07-28 15:48:59 -07001451
Jeff Brown8d608662010-08-30 03:02:23 -07001452 // InputDevice
1453
1454 FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001455 gInputDeviceClassInfo.clazz = jclass(env->NewGlobalRef(gInputDeviceClassInfo.clazz));
Jeff Brown8d608662010-08-30 03:02:23 -07001456
1457 GET_METHOD_ID(gInputDeviceClassInfo.ctor, gInputDeviceClassInfo.clazz,
1458 "<init>", "()V");
1459
1460 GET_METHOD_ID(gInputDeviceClassInfo.addMotionRange, gInputDeviceClassInfo.clazz,
Jeff Brownefd32662011-03-08 15:13:06 -08001461 "addMotionRange", "(IIFFFF)V");
Jeff Brown8d608662010-08-30 03:02:23 -07001462
1463 GET_FIELD_ID(gInputDeviceClassInfo.mId, gInputDeviceClassInfo.clazz,
1464 "mId", "I");
1465
1466 GET_FIELD_ID(gInputDeviceClassInfo.mName, gInputDeviceClassInfo.clazz,
1467 "mName", "Ljava/lang/String;");
1468
1469 GET_FIELD_ID(gInputDeviceClassInfo.mSources, gInputDeviceClassInfo.clazz,
1470 "mSources", "I");
1471
1472 GET_FIELD_ID(gInputDeviceClassInfo.mKeyboardType, gInputDeviceClassInfo.clazz,
1473 "mKeyboardType", "I");
1474
Jeff Brown57c59372010-09-21 18:22:55 -07001475 // Configuration
1476
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001477 FIND_CLASS(clazz, "android/content/res/Configuration");
Jeff Brown57c59372010-09-21 18:22:55 -07001478
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001479 GET_FIELD_ID(gConfigurationClassInfo.touchscreen, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001480 "touchscreen", "I");
1481
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001482 GET_FIELD_ID(gConfigurationClassInfo.keyboard, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001483 "keyboard", "I");
1484
Carl Shapiro17cc33a2011-03-05 20:53:16 -08001485 GET_FIELD_ID(gConfigurationClassInfo.navigation, clazz,
Jeff Brown57c59372010-09-21 18:22:55 -07001486 "navigation", "I");
1487
Jeff Brown46b9ac02010-04-22 18:58:52 -07001488 return 0;
1489}
1490
Jeff Brown46b9ac02010-04-22 18:58:52 -07001491} /* namespace android */