android_view_InputEventReceiver.cpp revision 62ce65d6edbc2c34c63b0e2f2fef9cb08e28c783
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2011 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "InputEventReceiver" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 191ebccf531d1049853b3b0630035434619682c016Dianne Hackborn//#define LOG_NDEBUG 0 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Log debug messages about the dispatch cycle. 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_DISPATCH_CYCLE 0 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <android_runtime/AndroidRuntime.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Looper.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Vector.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <input/InputTransport.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_os_MessageQueue.h" 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_view_InputChannel.h" 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_view_KeyEvent.h" 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "android_view_MotionEvent.h" 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <ScopedLocalRef.h> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 4175288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn 4275288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackbornstatic struct { 4375288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn jclass clazz; 4475288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn 4575288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn jmethodID dispatchInputEvent; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jmethodID dispatchBatchedInputEventPending; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} gInputEventReceiverClassInfo; 4875288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn 4975288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn 5075288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackbornclass NativeInputEventReceiver : public LooperCallback { 5175288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackbornpublic: 5275288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn NativeInputEventReceiver(JNIEnv* env, 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject receiverWeak, const sp<InputChannel>& inputChannel, 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const sp<MessageQueue>& messageQueue); 5575288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn 5675288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn status_t initialize(); 5775288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn void dispose(); 5875288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn status_t finishInputEvent(uint32_t seq, bool handled); 5975288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn status_t consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime, 6075288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn bool* outConsumedBatch); 6175288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn 6275288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackbornprotected: 6375288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn virtual ~NativeInputEventReceiver(); 6475288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct Finish { 6775288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn uint32_t seq; 6875288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn bool handled; 6975288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn }; 7075288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject mReceiverWeakGlobal; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputConsumer mInputConsumer; 73a334e7c72408c4e2805f2427a35d841a60adefc4Wink Saville sp<MessageQueue> mMessageQueue; 74cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn PreallocatedInputEventFactory mInputEventFactory; 75cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn bool mBatchedInputEventPending; 76cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn int mFdEvents; 77cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn Vector<Finish> mFinishQueue; 78cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn 79cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn void setFdEvents(int events); 80cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn 819867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown const char* getInputChannelName() { 829867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown return mInputConsumer.getChannel()->getName().string(); 839867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown } 849867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown 859867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown virtual int handleEvent(int receiveFd, int events, void* data); 869867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown}; 879867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown 889867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown 89e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff BrownNativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env, 90a334e7c72408c4e2805f2427a35d841a60adefc4Wink Saville jobject receiverWeak, const sp<InputChannel>& inputChannel, 91e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown const sp<MessageQueue>& messageQueue) : 92e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), 93a334e7c72408c4e2805f2427a35d841a60adefc4Wink Saville mInputConsumer(inputChannel), mMessageQueue(messageQueue), 94a334e7c72408c4e2805f2427a35d841a60adefc4Wink Saville mBatchedInputEventPending(false), mFdEvents(0) { 95e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown#if DEBUG_DISPATCH_CYCLE 96a334e7c72408c4e2805f2427a35d841a60adefc4Wink Saville ALOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName()); 97a334e7c72408c4e2805f2427a35d841a60adefc4Wink Saville#endif 98a334e7c72408c4e2805f2427a35d841a60adefc4Wink Saville} 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectNativeInputEventReceiver::~NativeInputEventReceiver() { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNIEnv* env = AndroidRuntime::getJNIEnv(); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->DeleteGlobalRef(mReceiverWeakGlobal); 1039867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown} 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brownstatus_t NativeInputEventReceiver::initialize() { 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFdEvents(ALOOPER_EVENT_INPUT); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1102405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrickvoid NativeInputEventReceiver::dispose() { 1112405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick#if DEBUG_DISPATCH_CYCLE 1122405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName()); 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 114a2ad65692481510496e367b593facf778f49249bRomain Guy 115a2ad65692481510496e367b593facf778f49249bRomain Guy setFdEvents(0); 1167895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn} 1177895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) { 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_DISPATCH_CYCLE 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGD("channel '%s' ~ Finished input event.", getInputChannelName()); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1232405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick status_t status = mInputConsumer.sendFinishedSignal(seq, handled); 1242405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick if (status) { 1252405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick if (status == WOULD_BLOCK) { 1262405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick#if DEBUG_DISPATCH_CYCLE 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGD("channel '%s' ~ Could not send finished signal immediately. " 1289867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown "Enqueued for later.", getInputChannelName()); 1292405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick#endif 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Finish finish; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project finish.seq = seq; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project finish.handled = handled; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFinishQueue.add(finish); 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFinishQueue.size() == 1) { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFdEvents(ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return OK; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGW("Failed to send finished signal on channel '%s'. status=%d", 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getInputChannelName(), status); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return status; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid NativeInputEventReceiver::setFdEvents(int events) { 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFdEvents != events) { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFdEvents = events; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int fd = mInputConsumer.getChannel()->getFd(); 149cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn if (events) { 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessageQueue->getLooper()->removeFd(fd); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) { 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_DISPATCH_CYCLE 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // This error typically occurs when the publisher has closed the input channel 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // as part of removing a window or finishing an IME session, in which case 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the consumer will soon be disposed as well. 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGD("channel '%s' ~ Publisher closed input channel or an error occurred. " 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "events=0x%x", getInputChannelName(), events); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; // remove the callback 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (events & ALOOPER_EVENT_INPUT) { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNIEnv* env = AndroidRuntime::getJNIEnv(); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return status == OK || status == NO_MEMORY ? 1 : 0; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (events & ALOOPER_EVENT_OUTPUT) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i = 0; i < mFinishQueue.size(); i++) { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const Finish& finish = mFinishQueue.itemAt(i); 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status) { 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFinishQueue.removeItemsAt(0, i); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status == WOULD_BLOCK) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_DISPATCH_CYCLE 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGD("channel '%s' ~ Sent %u queued finish events; %u left.", 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getInputChannelName(), i, mFinishQueue.size()); 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; // keep the callback, try again later 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGW("Failed to send finished signal on channel '%s'. status=%d", 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getInputChannelName(), status); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != DEAD_OBJECT) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project JNIEnv* env = AndroidRuntime::getJNIEnv(); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 message; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project message.appendFormat("Failed to finish input event. status=%d", status); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowRuntimeException(env, message.string()); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMessageQueue->raiseAndClearException(env, "finishInputEvent"); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; // remove the callback 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_DISPATCH_CYCLE 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGD("channel '%s' ~ Sent %u queued finish events; none left.", 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getInputChannelName(), mFinishQueue.size()); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFinishQueue.clear(); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project setFdEvents(ALOOPER_EVENT_INPUT); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "events=0x%x", getInputChannelName(), events); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 1; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_DISPATCH_CYCLE 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s, frameTime=%lld.", 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getInputChannelName(), consumeBatches ? "true" : "false", frameTime); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (consumeBatches) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatchedInputEventPending = false; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (outConsumedBatch) { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *outConsumedBatch = false; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ScopedLocalRef<jobject> receiverObj(env, NULL); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool skipCallbacks = false; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (;;) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project uint32_t seq; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InputEvent* inputEvent; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t status = mInputConsumer.consume(&mInputEventFactory, 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project consumeBatches, frameTime, &seq, &inputEvent); 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status) { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status == WOULD_BLOCK) { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!skipCallbacks && !mBatchedInputEventPending 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mInputConsumer.hasPendingBatch()) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // There is a pending batch. Come back later. 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!receiverObj.get()) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal)); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!receiverObj.get()) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGW("channel '%s' ~ Receiver object was finalized " 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "without being disposed.", getInputChannelName()); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return DEAD_OBJECT; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mBatchedInputEventPending = true; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_DISPATCH_CYCLE 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGD("channel '%s' ~ Dispatching batched input event pending notification.", 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getInputChannelName()); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(receiverObj.get(), 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gInputEventReceiverClassInfo.dispatchBatchedInputEventPending); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionCheck()) { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGE("Exception dispatching batched input events."); 2617895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn mBatchedInputEventPending = false; // try again later 2627895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn } 263955d8d69ea6caabce1461dc25b339b9bf9dc61a6Dianne Hackborn } 2647895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn return OK; 2657895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn } 2667895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn ALOGE("channel '%s' ~ Failed to consume input event. status=%d", 2677895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn getInputChannelName(), status); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return status; 2699867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown } 2709867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown assert(inputEvent); 2719867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown 2729867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown if (!skipCallbacks) { 2739867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown if (!receiverObj.get()) { 2749867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal)); 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!receiverObj.get()) { 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGW("channel '%s' ~ Receiver object was finalized " 2779867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown "without being disposed.", getInputChannelName()); 2787895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn return DEAD_OBJECT; 2797895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn } 2807895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn } 2817895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn 2827895bc2e6309427937ab060031bfee5c99879d59Dianne Hackborn jobject inputEventObj; 2839867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown switch (inputEvent->getType()) { 2849867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown case AINPUT_EVENT_TYPE_KEY: 2859867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown#if DEBUG_DISPATCH_CYCLE 2869867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown ALOGD("channel '%s' ~ Received key event.", getInputChannelName()); 2879867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown#endif 2889867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown inputEventObj = android_view_KeyEvent_fromNative(env, 2899867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown static_cast<KeyEvent*>(inputEvent)); 2909867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown break; 2919867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown 2929867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown case AINPUT_EVENT_TYPE_MOTION: { 2939867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown#if DEBUG_DISPATCH_CYCLE 2949867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown ALOGD("channel '%s' ~ Received motion event.", getInputChannelName()); 2959867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown#endif 2969867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown MotionEvent* motionEvent = static_cast<MotionEvent*>(inputEvent); 2979867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown if ((motionEvent->getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) { 2989867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown *outConsumedBatch = true; 2999867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown } 300cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent); 3019867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown break; 3029867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown } 3039867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown 3049867ed7aa98f5a719db4b50c39a290bc0ef38123Jeff Brown default: 305fc9ff4c834c5b3a3c4b024b89375d6c329092791Jeff Brown assert(false); // InputConsumer should prevent this from ever happening 3062405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick inputEventObj = NULL; 3072405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick } 3082405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick 3092405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick if (inputEventObj) { 3102405c278ef51ac527bca6d76a0b9d4804f9aab17Brad Fitzpatrick#if DEBUG_DISPATCH_CYCLE 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName()); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->CallVoidMethod(receiverObj.get(), 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (env->ExceptionCheck()) { 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ALOGE("Exception dispatching input event."); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skipCallbacks = true; 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project env->DeleteLocalRef(inputEventObj); 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 321a334e7c72408c4e2805f2427a35d841a60adefc4Wink Saville ALOGW("channel '%s' ~ Failed to obtain event object.", getInputChannelName()); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skipCallbacks = true; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (skipCallbacks) { 327cb3ed1dc287ddb9beb7c9186713426f5fba263c3Dianne Hackborn mInputConsumer.sendFinishedSignal(seq, false); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jobject inputChannelObj, jobject messageQueueObj) { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inputChannelObj); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inputChannel == NULL) { 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowRuntimeException(env, "InputChannel is not initialized."); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (messageQueue == NULL) { 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowRuntimeException(env, "MessageQueue is not initialized."); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env, 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project receiverWeak, inputChannel, messageQueue); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t status = receiver->initialize(); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status) { 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 message; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project message.appendFormat("Failed to initialize input event receiver. status=%d", status); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowRuntimeException(env, message.string()); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return reinterpret_cast<jint>(receiver.get()); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void nativeDispose(JNIEnv* env, jclass clazz, jint receiverPtr) { 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<NativeInputEventReceiver> receiver = 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); 36575288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn receiver->dispose(); 36675288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn receiver->decStrong(gInputEventReceiverClassInfo.clazz); // drop reference held by the object 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jint receiverPtr, 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jint seq, jboolean handled) { 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<NativeInputEventReceiver> receiver = 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); 37375288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn status_t status = receiver->finishInputEvent(seq, handled); 37475288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn if (status && status != DEAD_OBJECT) { 37575288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn String8 message; 37675288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn message.appendFormat("Failed to finish input event. status=%d", status); 37775288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn jniThrowRuntimeException(env, message.string()); 37875288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn } 37975288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn} 38075288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic bool nativeConsumeBatchedInputEvents(JNIEnv* env, jclass clazz, jint receiverPtr, 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jlong frameTimeNanos) { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<NativeInputEventReceiver> receiver = 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool consumedBatch; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t status = receiver->consumeEvents(env, true /*consumeBatches*/, frameTimeNanos, 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project &consumedBatch); 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status && status != DEAD_OBJECT && !env->ExceptionCheck()) { 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 message; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project message.appendFormat("Failed to consume batched input event. status=%d", status); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jniThrowRuntimeException(env, message.string()); 39275288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn return false; 39375288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn } 39475288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn return consumedBatch; 39575288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn} 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* name, signature, funcPtr */ 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeInit", 40175288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn "(Ljava/lang/ref/WeakReference;Landroid/view/InputChannel;Landroid/os/MessageQueue;)I", 402d0eb55360fb94faa632cf65f246260827dc4a177Denver Coneybeare (void*)nativeInit }, 40375288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn { "nativeDispose", "(I)V", 40475288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn (void*)nativeDispose }, 40575288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn { "nativeFinishInputEvent", "(IIZ)V", 40675288fa1a4ee4886959af7243995d8afd9c3c905Dianne Hackborn (void*)nativeFinishInputEvent }, 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "nativeConsumeBatchedInputEvents", "(IJ)Z", 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)nativeConsumeBatchedInputEvents }, 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define FIND_CLASS(var, className) \ 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project var = env->FindClass(className); \ 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(! var, "Unable to find class " className); \ 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project var = jclass(env->NewGlobalRef(var)); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_FATAL_IF(! var, "Unable to find method " methodName); 419e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown 4209840c07667bb0363c93fb8459e6c08f7e30d5df1Jeff Brownint register_android_view_InputEventReceiver(JNIEnv* env) { 4219840c07667bb0363c93fb8459e6c08f7e30d5df1Jeff Brown int res = jniRegisterNativeMethods(env, "android/view/InputEventReceiver", 422e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown gMethods, NELEM(gMethods)); 423e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown LOG_FATAL_IF(res < 0, "Unable to register native methods."); 424e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown 425e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown FIND_CLASS(gInputEventReceiverClassInfo.clazz, "android/view/InputEventReceiver"); 426e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown 427e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown GET_METHOD_ID(gInputEventReceiverClassInfo.dispatchInputEvent, 428e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown gInputEventReceiverClassInfo.clazz, 429e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown "dispatchInputEvent", "(ILandroid/view/InputEvent;)V"); 430e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown GET_METHOD_ID(gInputEventReceiverClassInfo.dispatchBatchedInputEventPending, 431e799cb78b4be61d3882e71c6812fa62c9a83fd5dJeff Brown gInputEventReceiverClassInfo.clazz, 4329840c07667bb0363c93fb8459e6c08f7e30d5df1Jeff Brown "dispatchBatchedInputEventPending", "()V"); 4339840c07667bb0363c93fb8459e6c08f7e30d5df1Jeff Brown return 0; 4349840c07667bb0363c93fb8459e6c08f7e30d5df1Jeff Brown} 4359840c07667bb0363c93fb8459e6c08f7e30d5df1Jeff Brown 4369840c07667bb0363c93fb8459e6c08f7e30d5df1Jeff Brown} // namespace android 4379840c07667bb0363c93fb8459e6c08f7e30d5df1Jeff Brown