132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown/* 232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * Copyright (C) 2011 The Android Open Source Project 332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * 432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * you may not use this file except in compliance with the License. 632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * You may obtain a copy of the License at 732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * 832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * 1032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * Unless required by applicable law or agreed to in writing, software 1132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * See the License for the specific language governing permissions and 1432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown * limitations under the License. 1532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown */ 1632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 1732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#define LOG_TAG "InputEventReceiver" 1832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 1932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown//#define LOG_NDEBUG 0 2032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 2132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown// Log debug messages about the dispatch cycle. 2232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#define DEBUG_DISPATCH_CYCLE 0 2332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 2432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 2532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include "JNIHelp.h" 2632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 2732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include <android_runtime/AndroidRuntime.h> 2832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include <utils/Log.h> 2932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include <utils/Looper.h> 3056513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown#include <utils/Vector.h> 3132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include <utils/threads.h> 329d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brown#include <input/InputTransport.h> 3332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include "android_os_MessageQueue.h" 3432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include "android_view_InputChannel.h" 3532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include "android_view_KeyEvent.h" 3632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include "android_view_MotionEvent.h" 3732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 38a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown#include <ScopedLocalRef.h> 39a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown 4032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownnamespace android { 4132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 4232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatic struct { 4332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jclass clazz; 4432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 4532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jmethodID dispatchInputEvent; 46072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown jmethodID dispatchBatchedInputEventPending; 4732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} gInputEventReceiverClassInfo; 4832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 4932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 5080a1de1007ddc62e1af2a4746008f499145aeaabJeff Brownclass NativeInputEventReceiver : public LooperCallback { 5132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownpublic: 5232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown NativeInputEventReceiver(JNIEnv* env, 53a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown jobject receiverWeak, const sp<InputChannel>& inputChannel, 54603b44589682db3ff33ade172facb0c5e309f1beJeff Brown const sp<MessageQueue>& messageQueue); 5532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 5632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status_t initialize(); 5780a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown void dispose(); 58072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown status_t finishInputEvent(uint32_t seq, bool handled); 5962ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright status_t consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime, 6062ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright bool* outConsumedBatch); 6132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 6232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownprotected: 6332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown virtual ~NativeInputEventReceiver(); 6432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 6532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownprivate: 6656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown struct Finish { 6756513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown uint32_t seq; 6856513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown bool handled; 6956513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown }; 7056513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown 71a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown jobject mReceiverWeakGlobal; 7232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown InputConsumer mInputConsumer; 73603b44589682db3ff33ade172facb0c5e309f1beJeff Brown sp<MessageQueue> mMessageQueue; 7432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown PreallocatedInputEventFactory mInputEventFactory; 75072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown bool mBatchedInputEventPending; 7656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown int mFdEvents; 7756513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown Vector<Finish> mFinishQueue; 7856513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown 7956513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown void setFdEvents(int events); 8032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 8132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown const char* getInputChannelName() { 8232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return mInputConsumer.getChannel()->getName().string(); 8332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 843bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown 8580a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown virtual int handleEvent(int receiveFd, int events, void* data); 8632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown}; 8732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 8832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 8932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff BrownNativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env, 90a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown jobject receiverWeak, const sp<InputChannel>& inputChannel, 91603b44589682db3ff33ade172facb0c5e309f1beJeff Brown const sp<MessageQueue>& messageQueue) : 92a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), 93603b44589682db3ff33ade172facb0c5e309f1beJeff Brown mInputConsumer(inputChannel), mMessageQueue(messageQueue), 9456513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown mBatchedInputEventPending(false), mFdEvents(0) { 9532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 965baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName()); 9732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 9832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 9932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 10032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff BrownNativeInputEventReceiver::~NativeInputEventReceiver() { 10132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 102a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown env->DeleteGlobalRef(mReceiverWeakGlobal); 10332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 10432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 10532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatus_t NativeInputEventReceiver::initialize() { 10656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown setFdEvents(ALOOPER_EVENT_INPUT); 10732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return OK; 10832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 10932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 11080a1de1007ddc62e1af2a4746008f499145aeaabJeff Brownvoid NativeInputEventReceiver::dispose() { 11180a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown#if DEBUG_DISPATCH_CYCLE 11280a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName()); 11380a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown#endif 11480a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown 11556513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown setFdEvents(0); 11680a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown} 11780a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown 118072ec96a4900d4616574733646ee46311cb5d2cbJeff Brownstatus_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) { 11932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 120072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown ALOGD("channel '%s' ~ Finished input event.", getInputChannelName()); 12132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 12232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 123072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown status_t status = mInputConsumer.sendFinishedSignal(seq, handled); 124072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown if (status) { 12556513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown if (status == WOULD_BLOCK) { 12656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown#if DEBUG_DISPATCH_CYCLE 12756513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown ALOGD("channel '%s' ~ Could not send finished signal immediately. " 12856513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown "Enqueued for later.", getInputChannelName()); 12956513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown#endif 13056513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown Finish finish; 13156513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown finish.seq = seq; 13256513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown finish.handled = handled; 13356513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown mFinishQueue.add(finish); 13456513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown if (mFinishQueue.size() == 1) { 13556513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown setFdEvents(ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT); 13656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } 13756513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown return OK; 13856513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } 139072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown ALOGW("Failed to send finished signal on channel '%s'. status=%d", 140072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown getInputChannelName(), status); 14132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 142072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown return status; 14332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 14432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 14556513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brownvoid NativeInputEventReceiver::setFdEvents(int events) { 14656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown if (mFdEvents != events) { 14756513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown mFdEvents = events; 14856513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown int fd = mInputConsumer.getChannel()->getFd(); 14956513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown if (events) { 15056513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL); 15156513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } else { 15256513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown mMessageQueue->getLooper()->removeFd(fd); 15356513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } 15456513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } 15556513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown} 15656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown 15780a1de1007ddc62e1af2a4746008f499145aeaabJeff Brownint NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) { 15832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) { 15944e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown#if DEBUG_DISPATCH_CYCLE 16044e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown // This error typically occurs when the publisher has closed the input channel 16144e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown // as part of removing a window or finishing an IME session, in which case 16244e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown // the consumer will soon be disposed as well. 16344e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown ALOGD("channel '%s' ~ Publisher closed input channel or an error occurred. " 16480a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown "events=0x%x", getInputChannelName(), events); 16544e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown#endif 16632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; // remove the callback 16732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 16832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 16956513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown if (events & ALOOPER_EVENT_INPUT) { 17056513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 17162ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL); 17256513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); 17356513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown return status == OK || status == NO_MEMORY ? 1 : 0; 17456513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } 17556513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown 17656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown if (events & ALOOPER_EVENT_OUTPUT) { 17756513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown for (size_t i = 0; i < mFinishQueue.size(); i++) { 17856513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown const Finish& finish = mFinishQueue.itemAt(i); 17956513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown status_t status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled); 18056513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown if (status) { 18156513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown mFinishQueue.removeItemsAt(0, i); 18256513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown 18356513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown if (status == WOULD_BLOCK) { 18456513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown#if DEBUG_DISPATCH_CYCLE 18556513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown ALOGD("channel '%s' ~ Sent %u queued finish events; %u left.", 18656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown getInputChannelName(), i, mFinishQueue.size()); 18756513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown#endif 18856513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown return 1; // keep the callback, try again later 18956513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } 19056513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown 19156513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown ALOGW("Failed to send finished signal on channel '%s'. status=%d", 19256513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown getInputChannelName(), status); 19356513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown if (status != DEAD_OBJECT) { 19456513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 19556513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown String8 message; 19656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown message.appendFormat("Failed to finish input event. status=%d", status); 19756513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown jniThrowRuntimeException(env, message.string()); 19856513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown mMessageQueue->raiseAndClearException(env, "finishInputEvent"); 19956513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } 20056513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown return 0; // remove the callback 20156513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } 20256513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown } 20356513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown#if DEBUG_DISPATCH_CYCLE 20456513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown ALOGD("channel '%s' ~ Sent %u queued finish events; none left.", 20556513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown getInputChannelName(), mFinishQueue.size()); 20656513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown#endif 20756513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown mFinishQueue.clear(); 20856513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown setFdEvents(ALOOPER_EVENT_INPUT); 20932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 1; 21032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 21132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 21256513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " 21356513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown "events=0x%x", getInputChannelName(), events); 21456513492ea6d4a72584cbc01979f7b3fa3c2807fJeff Brown return 1; 215072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown} 21632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 217771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brownstatus_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, 21862ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) { 219072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#if DEBUG_DISPATCH_CYCLE 220771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s, frameTime=%lld.", 221771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown getInputChannelName(), consumeBatches ? "true" : "false", frameTime); 222072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#endif 223072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown 224072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown if (consumeBatches) { 225072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown mBatchedInputEventPending = false; 22632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 22762ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright if (outConsumedBatch) { 22862ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright *outConsumedBatch = false; 22962ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright } 23032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 231a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown ScopedLocalRef<jobject> receiverObj(env, NULL); 2323bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown bool skipCallbacks = false; 233072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown for (;;) { 234072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown uint32_t seq; 235072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown InputEvent* inputEvent; 236072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown status_t status = mInputConsumer.consume(&mInputEventFactory, 237771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown consumeBatches, frameTime, &seq, &inputEvent); 238072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown if (status) { 239072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown if (status == WOULD_BLOCK) { 2403bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown if (!skipCallbacks && !mBatchedInputEventPending 2413bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown && mInputConsumer.hasPendingBatch()) { 242072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown // There is a pending batch. Come back later. 243a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown if (!receiverObj.get()) { 244a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal)); 245a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown if (!receiverObj.get()) { 246a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown ALOGW("channel '%s' ~ Receiver object was finalized " 247a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown "without being disposed.", getInputChannelName()); 248a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown return DEAD_OBJECT; 249a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown } 250a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown } 251a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown 252072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown mBatchedInputEventPending = true; 25332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 254072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown ALOGD("channel '%s' ~ Dispatching batched input event pending notification.", 255072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown getInputChannelName()); 25632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 257a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown env->CallVoidMethod(receiverObj.get(), 258072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown gInputEventReceiverClassInfo.dispatchBatchedInputEventPending); 2593bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown if (env->ExceptionCheck()) { 2603bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown ALOGE("Exception dispatching batched input events."); 261072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown mBatchedInputEventPending = false; // try again later 262072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown } 263072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown } 264072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown return OK; 265072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown } 266072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown ALOGE("channel '%s' ~ Failed to consume input event. status=%d", 267072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown getInputChannelName(), status); 268072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown return status; 269072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown } 270072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown assert(inputEvent); 27132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 2723bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown if (!skipCallbacks) { 273a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown if (!receiverObj.get()) { 274a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal)); 275a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown if (!receiverObj.get()) { 276a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown ALOGW("channel '%s' ~ Receiver object was finalized " 277a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown "without being disposed.", getInputChannelName()); 278a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown return DEAD_OBJECT; 279a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown } 280a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown } 281a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown 2823bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown jobject inputEventObj; 2833bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown switch (inputEvent->getType()) { 2843bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown case AINPUT_EVENT_TYPE_KEY: 28532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 2863bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown ALOGD("channel '%s' ~ Received key event.", getInputChannelName()); 28732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 2883bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown inputEventObj = android_view_KeyEvent_fromNative(env, 2893bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown static_cast<KeyEvent*>(inputEvent)); 2903bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown break; 29132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 29262ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright case AINPUT_EVENT_TYPE_MOTION: { 293072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#if DEBUG_DISPATCH_CYCLE 2943bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown ALOGD("channel '%s' ~ Received motion event.", getInputChannelName()); 295072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown#endif 29662ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright MotionEvent* motionEvent = static_cast<MotionEvent*>(inputEvent); 29762ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright if ((motionEvent->getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) { 29862ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright *outConsumedBatch = true; 29962ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright } 30062ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent); 3013bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown break; 30262ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright } 30332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 3043bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown default: 3053bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown assert(false); // InputConsumer should prevent this from ever happening 3063bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown inputEventObj = NULL; 3073bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown } 30832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 3093bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown if (inputEventObj) { 31032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 3113bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName()); 31232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 313a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown env->CallVoidMethod(receiverObj.get(), 3143bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj); 3153bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown if (env->ExceptionCheck()) { 3163bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown ALOGE("Exception dispatching input event."); 3173bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown skipCallbacks = true; 3183bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown } 319a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown env->DeleteLocalRef(inputEventObj); 3203bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown } else { 3213bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown ALOGW("channel '%s' ~ Failed to obtain event object.", getInputChannelName()); 3223bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown skipCallbacks = true; 3233bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown } 3243bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown } 32532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 3263bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown if (skipCallbacks) { 327072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown mInputConsumer.sendFinishedSignal(seq, false); 32832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 32932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 33032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 33132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 33232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 333a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brownstatic jint nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, 33432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jobject inputChannelObj, jobject messageQueueObj) { 33532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, 33632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown inputChannelObj); 33732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (inputChannel == NULL) { 33832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jniThrowRuntimeException(env, "InputChannel is not initialized."); 33932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; 34032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 34132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 342603b44589682db3ff33ade172facb0c5e309f1beJeff Brown sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); 343603b44589682db3ff33ade172facb0c5e309f1beJeff Brown if (messageQueue == NULL) { 34432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jniThrowRuntimeException(env, "MessageQueue is not initialized."); 34532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; 34632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 34732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 34832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env, 349a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown receiverWeak, inputChannel, messageQueue); 35032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status_t status = receiver->initialize(); 35132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (status) { 35232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown String8 message; 35332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown message.appendFormat("Failed to initialize input event receiver. status=%d", status); 35432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jniThrowRuntimeException(env, message.string()); 35532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; 35632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 35732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 35832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object 35932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return reinterpret_cast<jint>(receiver.get()); 36032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 36132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 36232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatic void nativeDispose(JNIEnv* env, jclass clazz, jint receiverPtr) { 36332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<NativeInputEventReceiver> receiver = 36432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); 36580a1de1007ddc62e1af2a4746008f499145aeaabJeff Brown receiver->dispose(); 36632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown receiver->decStrong(gInputEventReceiverClassInfo.clazz); // drop reference held by the object 36732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 36832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 369072ec96a4900d4616574733646ee46311cb5d2cbJeff Brownstatic void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jint receiverPtr, 370072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown jint seq, jboolean handled) { 37132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<NativeInputEventReceiver> receiver = 37232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); 373072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown status_t status = receiver->finishInputEvent(seq, handled); 3749806a2307f3e47e847ad5e62e302eab36d3eb3e4Jeff Brown if (status && status != DEAD_OBJECT) { 37532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown String8 message; 37632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown message.appendFormat("Failed to finish input event. status=%d", status); 37732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jniThrowRuntimeException(env, message.string()); 37832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 37932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 38032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 38162ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wrightstatic bool nativeConsumeBatchedInputEvents(JNIEnv* env, jclass clazz, jint receiverPtr, 382771526c88f5cc4b56a41cb12aa06a28d377a07d5Jeff Brown jlong frameTimeNanos) { 383072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown sp<NativeInputEventReceiver> receiver = 384072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); 38562ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright bool consumedBatch; 38662ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright status_t status = receiver->consumeEvents(env, true /*consumeBatches*/, frameTimeNanos, 38762ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright &consumedBatch); 3883bdcdd8531781569d501e7023c22e25e2bae0dd1Jeff Brown if (status && status != DEAD_OBJECT && !env->ExceptionCheck()) { 389072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown String8 message; 390072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown message.appendFormat("Failed to consume batched input event. status=%d", status); 391072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown jniThrowRuntimeException(env, message.string()); 39262ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright return false; 393072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown } 39462ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright return consumedBatch; 395072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown} 396072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown 39732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 39832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatic JNINativeMethod gMethods[] = { 39932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown /* name, signature, funcPtr */ 40032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown { "nativeInit", 401a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown "(Ljava/lang/ref/WeakReference;Landroid/view/InputChannel;Landroid/os/MessageQueue;)I", 40232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown (void*)nativeInit }, 403072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown { "nativeDispose", "(I)V", 40432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown (void*)nativeDispose }, 405072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown { "nativeFinishInputEvent", "(IIZ)V", 406072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown (void*)nativeFinishInputEvent }, 40762ce65d6edbc2c34c63b0e2f2fef9cb08e28c783Michael Wright { "nativeConsumeBatchedInputEvents", "(IJ)Z", 408072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown (void*)nativeConsumeBatchedInputEvents }, 40932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown}; 41032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 41132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#define FIND_CLASS(var, className) \ 41232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown var = env->FindClass(className); \ 41332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); \ 41432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown var = jclass(env->NewGlobalRef(var)); 41532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 41632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 41732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 41832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOG_FATAL_IF(! var, "Unable to find method " methodName); 41932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 42032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownint register_android_view_InputEventReceiver(JNIEnv* env) { 42132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown int res = jniRegisterNativeMethods(env, "android/view/InputEventReceiver", 42232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown gMethods, NELEM(gMethods)); 42332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOG_FATAL_IF(res < 0, "Unable to register native methods."); 42432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 42532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown FIND_CLASS(gInputEventReceiverClassInfo.clazz, "android/view/InputEventReceiver"); 42632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 42732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown GET_METHOD_ID(gInputEventReceiverClassInfo.dispatchInputEvent, 42832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown gInputEventReceiverClassInfo.clazz, 429072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown "dispatchInputEvent", "(ILandroid/view/InputEvent;)V"); 430072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown GET_METHOD_ID(gInputEventReceiverClassInfo.dispatchBatchedInputEventPending, 431072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown gInputEventReceiverClassInfo.clazz, 432072ec96a4900d4616574733646ee46311cb5d2cbJeff Brown "dispatchBatchedInputEventPending", "()V"); 43332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; 43432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 43532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 43632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} // namespace android 437