android_view_InputEventReceiver.cpp revision 5baa3a62a97544669fba6d65a11c07f252e654dd
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> 3032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include <utils/threads.h> 3132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include <ui/InputTransport.h> 3232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include "android_os_MessageQueue.h" 3332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include "android_view_InputChannel.h" 3432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include "android_view_KeyEvent.h" 3532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#include "android_view_MotionEvent.h" 3632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 3732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownnamespace android { 3832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 3932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatic struct { 4032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jclass clazz; 4132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 4232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jmethodID dispatchInputEvent; 4332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} gInputEventReceiverClassInfo; 4432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 4532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 4632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownclass NativeInputEventReceiver : public RefBase { 4732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownpublic: 4832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown NativeInputEventReceiver(JNIEnv* env, 4932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jobject receiverObj, const sp<InputChannel>& inputChannel, 5032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown const sp<Looper>& looper); 5132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 5232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status_t initialize(); 5332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status_t finishInputEvent(bool handled); 5432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown static int handleReceiveCallback(int receiveFd, int events, void* data); 5532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 5632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownprotected: 5732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown virtual ~NativeInputEventReceiver(); 5832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 5932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownprivate: 6032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jobject mReceiverObjGlobal; 6132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown InputConsumer mInputConsumer; 6232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<Looper> mLooper; 6332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown bool mEventInProgress; 6432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown PreallocatedInputEventFactory mInputEventFactory; 6532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 6632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown const char* getInputChannelName() { 6732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return mInputConsumer.getChannel()->getName().string(); 6832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 6932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown}; 7032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 7132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 7232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff BrownNativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env, 7332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jobject receiverObj, const sp<InputChannel>& inputChannel, const sp<Looper>& looper) : 7432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown mReceiverObjGlobal(env->NewGlobalRef(receiverObj)), 7532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown mInputConsumer(inputChannel), mLooper(looper), mEventInProgress(false) { 7632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 775baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName()); 7832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 7932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 8032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 8132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff BrownNativeInputEventReceiver::~NativeInputEventReceiver() { 8232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 835baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName()); 8432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 8532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 8632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown mLooper->removeFd(mInputConsumer.getChannel()->getReceivePipeFd()); 8732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (mEventInProgress) { 8832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown mInputConsumer.sendFinishedSignal(false); // ignoring result 8932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 9032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 9132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 9232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown env->DeleteGlobalRef(mReceiverObjGlobal); 9332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 9432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 9532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatus_t NativeInputEventReceiver::initialize() { 9632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status_t result = mInputConsumer.initialize(); 9732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (result) { 9832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGW("Failed to initialize input consumer for input channel '%s', status=%d", 9932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown getInputChannelName(), result); 10032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return result; 10132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 10232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 10332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown int32_t receiveFd = mInputConsumer.getChannel()->getReceivePipeFd(); 10432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown mLooper->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, handleReceiveCallback, this); 10532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return OK; 10632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 10732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 10832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatus_t NativeInputEventReceiver::finishInputEvent(bool handled) { 10932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (mEventInProgress) { 11032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 1115baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("channel '%s' ~ Finished input event.", getInputChannelName()); 11232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 11332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown mEventInProgress = false; 11432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 11532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status_t status = mInputConsumer.sendFinishedSignal(handled); 11632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (status) { 11732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGW("Failed to send finished signal on channel '%s'. status=%d", 11832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown getInputChannelName(), status); 11932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 12032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return status; 12132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } else { 12232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGW("Ignoring attempt to finish input event while no event is in progress."); 12332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return OK; 12432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 12532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 12632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 12732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownint NativeInputEventReceiver::handleReceiveCallback(int receiveFd, int events, void* data) { 12832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<NativeInputEventReceiver> r = static_cast<NativeInputEventReceiver*>(data); 12932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 13032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) { 13132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGE("channel '%s' ~ Publisher closed input channel or an error occurred. " 13232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown "events=0x%x", r->getInputChannelName(), events); 13332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; // remove the callback 13432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 13532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 13632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (!(events & ALOOPER_EVENT_INPUT)) { 13732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " 13832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown "events=0x%x", r->getInputChannelName(), events); 13932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 1; 14032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 14132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 14232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status_t status = r->mInputConsumer.receiveDispatchSignal(); 14332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (status) { 14432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGE("channel '%s' ~ Failed to receive dispatch signal. status=%d", 14532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->getInputChannelName(), status); 14632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; // remove the callback 14732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 14832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 14932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (r->mEventInProgress) { 15032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGW("channel '%s' ~ Publisher sent spurious dispatch signal.", 15132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->getInputChannelName()); 15232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 1; 15332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 15432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 15532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown InputEvent* inputEvent; 15632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status = r->mInputConsumer.consume(&r->mInputEventFactory, &inputEvent); 15732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (status) { 15832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGW("channel '%s' ~ Failed to consume input event. status=%d", 15932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->getInputChannelName(), status); 16032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->mInputConsumer.sendFinishedSignal(false); 16132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 1; 16232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 16332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 16432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 16532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jobject inputEventObj; 16632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown switch (inputEvent->getType()) { 16732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown case AINPUT_EVENT_TYPE_KEY: 16832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 1695baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("channel '%s' ~ Received key event.", 17032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->getInputChannelName()); 17132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 17232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown inputEventObj = android_view_KeyEvent_fromNative(env, 17332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown static_cast<KeyEvent*>(inputEvent)); 17432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown break; 17532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 17632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown case AINPUT_EVENT_TYPE_MOTION: 17732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 1785baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("channel '%s' ~ Received motion event.", 17932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->getInputChannelName()); 18032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 18132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown inputEventObj = android_view_MotionEvent_obtainAsCopy(env, 18232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown static_cast<MotionEvent*>(inputEvent)); 18332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown break; 18432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 18532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown default: 18632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown assert(false); // InputConsumer should prevent this from ever happening 18732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown inputEventObj = NULL; 18832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 18932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 19032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (!inputEventObj) { 19132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGW("channel '%s' ~ Failed to obtain event object.", 19232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->getInputChannelName()); 19332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->mInputConsumer.sendFinishedSignal(false); 19432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 1; 19532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 19632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 19732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->mEventInProgress = true; 19832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 19932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 2005baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("channel '%s' ~ Invoking input handler.", r->getInputChannelName()); 20132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 20232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown env->CallVoidMethod(r->mReceiverObjGlobal, 20332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown gInputEventReceiverClassInfo.dispatchInputEvent, inputEventObj); 20432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#if DEBUG_DISPATCH_CYCLE 2055baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("channel '%s' ~ Returned from input handler.", r->getInputChannelName()); 20632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#endif 20732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 20832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (env->ExceptionCheck()) { 20932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGE("channel '%s' ~ An exception occurred while dispatching an event.", 21032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->getInputChannelName()); 21132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOGE_EX(env); 21232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown env->ExceptionClear(); 21332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 21432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (r->mEventInProgress) { 21532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->mInputConsumer.sendFinishedSignal(false); 21632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown r->mEventInProgress = false; 21732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 21832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 21932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 22032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown env->DeleteLocalRef(inputEventObj); 22132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 1; 22232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 22332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 22432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 22532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatic jint nativeInit(JNIEnv* env, jclass clazz, jobject receiverObj, 22632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jobject inputChannelObj, jobject messageQueueObj) { 22732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, 22832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown inputChannelObj); 22932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (inputChannel == NULL) { 23032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jniThrowRuntimeException(env, "InputChannel is not initialized."); 23132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; 23232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 23332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 23432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<Looper> looper = android_os_MessageQueue_getLooper(env, messageQueueObj); 23532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (looper == NULL) { 23632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jniThrowRuntimeException(env, "MessageQueue is not initialized."); 23732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; 23832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 23932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 24032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env, 24132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown receiverObj, inputChannel, looper); 24232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status_t status = receiver->initialize(); 24332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (status) { 24432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown String8 message; 24532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown message.appendFormat("Failed to initialize input event receiver. status=%d", status); 24632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jniThrowRuntimeException(env, message.string()); 24732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; 24832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 24932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 25032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object 25132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return reinterpret_cast<jint>(receiver.get()); 25232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 25332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 25432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatic void nativeDispose(JNIEnv* env, jclass clazz, jint receiverPtr) { 25532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<NativeInputEventReceiver> receiver = 25632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); 25732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown receiver->decStrong(gInputEventReceiverClassInfo.clazz); // drop reference held by the object 25832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 25932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 26032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatic void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jint receiverPtr, jboolean handled) { 26132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown sp<NativeInputEventReceiver> receiver = 26232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); 26332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown status_t status = receiver->finishInputEvent(handled); 26432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown if (status) { 26532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown String8 message; 26632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown message.appendFormat("Failed to finish input event. status=%d", status); 26732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown jniThrowRuntimeException(env, message.string()); 26832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown } 26932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 27032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 27132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 27232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownstatic JNINativeMethod gMethods[] = { 27332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown /* name, signature, funcPtr */ 27432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown { "nativeInit", 27532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown "(Landroid/view/InputEventReceiver;Landroid/view/InputChannel;Landroid/os/MessageQueue;)I", 27632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown (void*)nativeInit }, 27732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown { "nativeDispose", 27832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown "(I)V", 27932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown (void*)nativeDispose }, 28032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown { "nativeFinishInputEvent", "(IZ)V", 28132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown (void*)nativeFinishInputEvent } 28232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown}; 28332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 28432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#define FIND_CLASS(var, className) \ 28532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown var = env->FindClass(className); \ 28632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); \ 28732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown var = jclass(env->NewGlobalRef(var)); 28832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 28932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 29032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 29132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOG_FATAL_IF(! var, "Unable to find method " methodName); 29232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 29332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brownint register_android_view_InputEventReceiver(JNIEnv* env) { 29432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown int res = jniRegisterNativeMethods(env, "android/view/InputEventReceiver", 29532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown gMethods, NELEM(gMethods)); 29632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown LOG_FATAL_IF(res < 0, "Unable to register native methods."); 29732cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 29832cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown FIND_CLASS(gInputEventReceiverClassInfo.clazz, "android/view/InputEventReceiver"); 29932cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 30032cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown GET_METHOD_ID(gInputEventReceiverClassInfo.dispatchInputEvent, 30132cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown gInputEventReceiverClassInfo.clazz, 30232cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown "dispatchInputEvent", "(Landroid/view/InputEvent;)V"); 30332cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown return 0; 30432cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} 30532cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown 30632cbc3855c2a971aa5a801fd339fb6a37db91a1aJeff Brown} // namespace android 307