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