1a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright/* 2a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * Copyright (C) 2013 The Android Open Source Project 3a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * 4a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * Licensed under the Apache License, Version 2.0 (the "License"); 5a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * you may not use this file except in compliance with the License. 6a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * You may obtain a copy of the License at 7a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * 8a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * http://www.apache.org/licenses/LICENSE-2.0 9a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * 10a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * Unless required by applicable law or agreed to in writing, software 11a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * distributed under the License is distributed on an "AS IS" BASIS, 12a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * See the License for the specific language governing permissions and 14a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright * limitations under the License. 15a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright */ 16a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 17a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#define LOG_TAG "InputQueue" 18a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 19a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include <fcntl.h> 20a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include <string.h> 21a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include <unistd.h> 22a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 23a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include <android/input.h> 24a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include <android_runtime/AndroidRuntime.h> 25a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include <android_runtime/android_view_InputQueue.h> 269d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brown#include <input/Input.h> 27a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include <utils/Looper.h> 28a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include <utils/TypeHelpers.h> 29a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include <ScopedLocalRef.h> 30a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 31a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include "JNIHelp.h" 32a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include "android_os_MessageQueue.h" 33a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include "android_view_KeyEvent.h" 34a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright#include "android_view_MotionEvent.h" 35a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 36987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe#include "core_jni_helpers.h" 37987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 38a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightnamespace android { 39a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 40a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightstatic struct { 41a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright jmethodID finishInputEvent; 42a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} gInputQueueClassInfo; 43a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 44a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightenum { 45a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright MSG_FINISH_INPUT = 1, 46a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright}; 47a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 48a44dd26a75e24cc021802288fb81f4761e47be6bMichael WrightInputQueue::InputQueue(jobject inputQueueObj, const sp<Looper>& looper, 49a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright int dispatchReadFd, int dispatchWriteFd) : 50a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mDispatchReadFd(dispatchReadFd), mDispatchWriteFd(dispatchWriteFd), 51a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mDispatchLooper(looper), mHandler(new WeakMessageHandler(this)) { 52a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright JNIEnv* env = AndroidRuntime::getJNIEnv(); 53a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mInputQueueWeakGlobal = env->NewGlobalRef(inputQueueObj); 54a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 55a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 56a44dd26a75e24cc021802288fb81f4761e47be6bMichael WrightInputQueue::~InputQueue() { 57a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mDispatchLooper->removeMessages(mHandler); 58a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright JNIEnv* env = AndroidRuntime::getJNIEnv(); 59a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright env->DeleteGlobalRef(mInputQueueWeakGlobal); 60a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright close(mDispatchReadFd); 61a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright close(mDispatchWriteFd); 62a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 63a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 64a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightvoid InputQueue::attachLooper(Looper* looper, int ident, 65a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright ALooper_callbackFunc callback, void* data) { 66a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright Mutex::Autolock _l(mLock); 67a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright for (size_t i = 0; i < mAppLoopers.size(); i++) { 68a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (looper == mAppLoopers[i]) { 69a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return; 70a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 71a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 72a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mAppLoopers.push(looper); 73a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright looper->addFd(mDispatchReadFd, ident, ALOOPER_EVENT_INPUT, callback, data); 74a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 75a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 76a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightvoid InputQueue::detachLooper() { 77a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright Mutex::Autolock _l(mLock); 78a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright detachLooperLocked(); 79a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 80a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 81a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightvoid InputQueue::detachLooperLocked() { 82a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright for (size_t i = 0; i < mAppLoopers.size(); i++) { 83a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mAppLoopers[i]->removeFd(mDispatchReadFd); 84a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 85a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mAppLoopers.clear(); 86a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 87a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 88a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightbool InputQueue::hasEvents() { 89a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright Mutex::Autolock _l(mLock); 90a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return mPendingEvents.size() > 0; 91a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 92a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 93a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightstatus_t InputQueue::getEvent(InputEvent** outEvent) { 94a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright Mutex::Autolock _l(mLock); 95a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright *outEvent = NULL; 96a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (!mPendingEvents.isEmpty()) { 97a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright *outEvent = mPendingEvents[0]; 98a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mPendingEvents.removeAt(0); 99a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 100a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 101a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (mPendingEvents.isEmpty()) { 102a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright char byteread[16]; 103a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright ssize_t nRead; 104a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright do { 105a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright nRead = TEMP_FAILURE_RETRY(read(mDispatchReadFd, &byteread, sizeof(byteread))); 106a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (nRead < 0 && errno != EAGAIN) { 107a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright ALOGW("Failed to read from native dispatch pipe: %s", strerror(errno)); 108a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 109a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } while (nRead > 0); 110a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 111a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 112a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return *outEvent != NULL ? OK : WOULD_BLOCK; 113a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 114a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 115a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightbool InputQueue::preDispatchEvent(InputEvent* e) { 116a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (e->getType() == AINPUT_EVENT_TYPE_KEY) { 117a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright KeyEvent* keyEvent = static_cast<KeyEvent*>(e); 118a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (keyEvent->getFlags() & AKEY_EVENT_FLAG_PREDISPATCH) { 119a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright finishEvent(e, false); 120a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return true; 121a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 122a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 123a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return false; 124a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 125a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 126a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightvoid InputQueue::finishEvent(InputEvent* event, bool handled) { 127a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright Mutex::Autolock _l(mLock); 128a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mFinishedEvents.push(key_value_pair_t<InputEvent*, bool>(event, handled)); 129a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (mFinishedEvents.size() == 1) { 130a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mDispatchLooper->sendMessage(this, Message(MSG_FINISH_INPUT)); 131a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 132a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 133a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 134a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightvoid InputQueue::handleMessage(const Message& message) { 135a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright switch(message.what) { 136a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright case MSG_FINISH_INPUT: 137a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright JNIEnv* env = AndroidRuntime::getJNIEnv(); 138a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright ScopedLocalRef<jobject> inputQueueObj(env, jniGetReferent(env, mInputQueueWeakGlobal)); 139a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (!inputQueueObj.get()) { 140a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright ALOGW("InputQueue was finalized without being disposed"); 141a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return; 142a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 143a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright while (true) { 144a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright InputEvent* event; 145a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright bool handled; 146a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright { 147a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright Mutex::Autolock _l(mLock); 148a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (mFinishedEvents.isEmpty()) { 149a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright break; 150a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 151a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright event = mFinishedEvents[0].getKey(); 152a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright handled = mFinishedEvents[0].getValue(); 153a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mFinishedEvents.removeAt(0); 154a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 155a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright env->CallVoidMethod(inputQueueObj.get(), gInputQueueClassInfo.finishInputEvent, 156a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat reinterpret_cast<jlong>(event), handled); 157a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright recycleInputEvent(event); 158a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 159a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright break; 160a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 161a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 162a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 163a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightvoid InputQueue::recycleInputEvent(InputEvent* event) { 164a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mPooledInputEventFactory.recycle(event); 165a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 166a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 167a44dd26a75e24cc021802288fb81f4761e47be6bMichael WrightKeyEvent* InputQueue::createKeyEvent() { 168a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return mPooledInputEventFactory.createKeyEvent(); 169a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 170a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 171a44dd26a75e24cc021802288fb81f4761e47be6bMichael WrightMotionEvent* InputQueue::createMotionEvent() { 172a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return mPooledInputEventFactory.createMotionEvent(); 173a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 174a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 175a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightvoid InputQueue::enqueueEvent(InputEvent* event) { 176a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright Mutex::Autolock _l(mLock); 177a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright mPendingEvents.push(event); 178a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (mPendingEvents.size() == 1) { 179a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright char dummy = 0; 180a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright int res = TEMP_FAILURE_RETRY(write(mDispatchWriteFd, &dummy, sizeof(dummy))); 181a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (res < 0 && errno != EAGAIN) { 182a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright ALOGW("Failed writing to dispatch fd: %s", strerror(errno)); 183a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 184a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 185a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 186a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 187a44dd26a75e24cc021802288fb81f4761e47be6bMichael WrightInputQueue* InputQueue::createQueue(jobject inputQueueObj, const sp<Looper>& looper) { 188a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright int pipeFds[2]; 189a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (pipe(pipeFds)) { 190a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright ALOGW("Could not create native input dispatching pipe: %s", strerror(errno)); 191a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return NULL; 192a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 193a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright fcntl(pipeFds[0], F_SETFL, O_NONBLOCK); 194a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright fcntl(pipeFds[1], F_SETFL, O_NONBLOCK); 195a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return new InputQueue(inputQueueObj, looper, pipeFds[0], pipeFds[1]); 196a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 197a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 198a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic jlong nativeInit(JNIEnv* env, jobject clazz, jobject queueWeak, jobject jMsgQueue) { 199a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, jMsgQueue); 200a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (messageQueue == NULL) { 201a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright jniThrowRuntimeException(env, "MessageQueue is not initialized."); 202a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return 0; 203a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 204a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright sp<InputQueue> queue = InputQueue::createQueue(queueWeak, messageQueue->getLooper()); 205a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (!queue.get()) { 206a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright jniThrowRuntimeException(env, "InputQueue failed to initialize"); 207a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return 0; 208a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 209a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright queue->incStrong(&gInputQueueClassInfo); 210a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat return reinterpret_cast<jlong>(queue.get()); 211a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 212a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 213a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic void nativeDispose(JNIEnv* env, jobject clazz, jlong ptr) { 214a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright sp<InputQueue> queue = reinterpret_cast<InputQueue*>(ptr); 215a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright queue->detachLooper(); 216a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright queue->decStrong(&gInputQueueClassInfo); 217a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 218a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 219a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic jlong nativeSendKeyEvent(JNIEnv* env, jobject clazz, jlong ptr, jobject eventObj, 220a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright jboolean predispatch) { 221a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright InputQueue* queue = reinterpret_cast<InputQueue*>(ptr); 222a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright KeyEvent* event = queue->createKeyEvent(); 223a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright status_t status = android_view_KeyEvent_toNative(env, eventObj, event); 224a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (status) { 225a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright queue->recycleInputEvent(event); 226a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright jniThrowRuntimeException(env, "Could not read contents of KeyEvent object."); 227a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return -1; 228a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 229a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 230a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (predispatch) { 231a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright event->setFlags(event->getFlags() | AKEY_EVENT_FLAG_PREDISPATCH); 232a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 233a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 234a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright queue->enqueueEvent(event); 235a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat return reinterpret_cast<jlong>(event); 236a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 237a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 238a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic jlong nativeSendMotionEvent(JNIEnv* env, jobject clazz, jlong ptr, jobject eventObj) { 239a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright sp<InputQueue> queue = reinterpret_cast<InputQueue*>(ptr); 240a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright MotionEvent* originalEvent = android_view_MotionEvent_getNativePtr(env, eventObj); 241a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright if (!originalEvent) { 242a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright jniThrowRuntimeException(env, "Could not obtain MotionEvent pointer."); 243a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright return -1; 244a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright } 245a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright MotionEvent* event = queue->createMotionEvent(); 246a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright event->copyFrom(originalEvent, true /* keepHistory */); 247a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright queue->enqueueEvent(event); 248a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat return reinterpret_cast<jlong>(event); 249a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 250a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 251a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightstatic const JNINativeMethod g_methods[] = { 252a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;)J", 253a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright (void*) nativeInit }, 254a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeDispose", "(J)V", (void*) nativeDispose }, 255a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeSendKeyEvent", "(JLandroid/view/KeyEvent;Z)J", (void*) nativeSendKeyEvent }, 256a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeSendMotionEvent", "(JLandroid/view/MotionEvent;)J", (void*) nativeSendMotionEvent }, 257a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright}; 258a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 259a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightstatic const char* const kInputQueuePathName = "android/view/InputQueue"; 260a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 261a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wrightint register_android_view_InputQueue(JNIEnv* env) 262a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright{ 263987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe jclass clazz = FindClassOrDie(env, kInputQueuePathName); 264987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gInputQueueClassInfo.finishInputEvent = GetMethodIDOrDie(env, clazz, "finishInputEvent", 265987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe "(JZ)V"); 266a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 267987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe return RegisterMethodsOrDie(env, kInputQueuePathName, g_methods, NELEM(g_methods)); 268a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} 269a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright 270a44dd26a75e24cc021802288fb81f4761e47be6bMichael Wright} // namespace android 271