Loading core/jni/android_view_InputEventReceiver.cpp +82 −11 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <android_runtime/AndroidRuntime.h> #include <utils/Log.h> #include <utils/Looper.h> #include <utils/Vector.h> #include <utils/threads.h> #include <androidfw/InputTransport.h> #include "android_os_MessageQueue.h" Loading Loading @@ -61,11 +62,20 @@ protected: virtual ~NativeInputEventReceiver(); private: struct Finish { uint32_t seq; bool handled; }; jobject mReceiverWeakGlobal; InputConsumer mInputConsumer; sp<MessageQueue> mMessageQueue; PreallocatedInputEventFactory mInputEventFactory; bool mBatchedInputEventPending; int mFdEvents; Vector<Finish> mFinishQueue; void setFdEvents(int events); const char* getInputChannelName() { return mInputConsumer.getChannel()->getName().string(); Loading @@ -80,7 +90,7 @@ NativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env, const sp<MessageQueue>& messageQueue) : mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mInputConsumer(inputChannel), mMessageQueue(messageQueue), mBatchedInputEventPending(false) { mBatchedInputEventPending(false), mFdEvents(0) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName()); #endif Loading @@ -92,8 +102,7 @@ NativeInputEventReceiver::~NativeInputEventReceiver() { } status_t NativeInputEventReceiver::initialize() { int receiveFd = mInputConsumer.getChannel()->getFd(); mMessageQueue->getLooper()->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, this, NULL); setFdEvents(ALOOPER_EVENT_INPUT); return OK; } Loading @@ -102,7 +111,7 @@ void NativeInputEventReceiver::dispose() { ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName()); #endif mMessageQueue->getLooper()->removeFd(mInputConsumer.getChannel()->getFd()); setFdEvents(0); } status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) { Loading @@ -112,12 +121,38 @@ status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) status_t status = mInputConsumer.sendFinishedSignal(seq, handled); if (status) { if (status == WOULD_BLOCK) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Could not send finished signal immediately. " "Enqueued for later.", getInputChannelName()); #endif Finish finish; finish.seq = seq; finish.handled = handled; mFinishQueue.add(finish); if (mFinishQueue.size() == 1) { setFdEvents(ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT); } return OK; } ALOGW("Failed to send finished signal on channel '%s'. status=%d", getInputChannelName(), status); } return status; } void NativeInputEventReceiver::setFdEvents(int events) { if (mFdEvents != events) { mFdEvents = events; int fd = mInputConsumer.getChannel()->getFd(); if (events) { mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL); } else { mMessageQueue->getLooper()->removeFd(fd); } } } int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) { if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) { #if DEBUG_DISPATCH_CYCLE Loading @@ -130,18 +165,54 @@ int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) return 0; // remove the callback } if (!(events & ALOOPER_EVENT_INPUT)) { ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " "events=0x%x", getInputChannelName(), events); return 1; } if (events & ALOOPER_EVENT_INPUT) { JNIEnv* env = AndroidRuntime::getJNIEnv(); status_t status = consumeEvents(env, false /*consumeBatches*/, -1); mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); return status == OK || status == NO_MEMORY ? 1 : 0; } if (events & ALOOPER_EVENT_OUTPUT) { for (size_t i = 0; i < mFinishQueue.size(); i++) { const Finish& finish = mFinishQueue.itemAt(i); status_t status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled); if (status) { mFinishQueue.removeItemsAt(0, i); if (status == WOULD_BLOCK) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Sent %u queued finish events; %u left.", getInputChannelName(), i, mFinishQueue.size()); #endif return 1; // keep the callback, try again later } ALOGW("Failed to send finished signal on channel '%s'. status=%d", getInputChannelName(), status); if (status != DEAD_OBJECT) { JNIEnv* env = AndroidRuntime::getJNIEnv(); String8 message; message.appendFormat("Failed to finish input event. status=%d", status); jniThrowRuntimeException(env, message.string()); mMessageQueue->raiseAndClearException(env, "finishInputEvent"); } return 0; // remove the callback } } #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Sent %u queued finish events; none left.", getInputChannelName(), mFinishQueue.size()); #endif mFinishQueue.clear(); setFdEvents(ALOOPER_EVENT_INPUT); return 1; } ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " "events=0x%x", getInputChannelName(), events); return 1; } status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime) { #if DEBUG_DISPATCH_CYCLE Loading Loading
core/jni/android_view_InputEventReceiver.cpp +82 −11 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <android_runtime/AndroidRuntime.h> #include <utils/Log.h> #include <utils/Looper.h> #include <utils/Vector.h> #include <utils/threads.h> #include <androidfw/InputTransport.h> #include "android_os_MessageQueue.h" Loading Loading @@ -61,11 +62,20 @@ protected: virtual ~NativeInputEventReceiver(); private: struct Finish { uint32_t seq; bool handled; }; jobject mReceiverWeakGlobal; InputConsumer mInputConsumer; sp<MessageQueue> mMessageQueue; PreallocatedInputEventFactory mInputEventFactory; bool mBatchedInputEventPending; int mFdEvents; Vector<Finish> mFinishQueue; void setFdEvents(int events); const char* getInputChannelName() { return mInputConsumer.getChannel()->getName().string(); Loading @@ -80,7 +90,7 @@ NativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env, const sp<MessageQueue>& messageQueue) : mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mInputConsumer(inputChannel), mMessageQueue(messageQueue), mBatchedInputEventPending(false) { mBatchedInputEventPending(false), mFdEvents(0) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName()); #endif Loading @@ -92,8 +102,7 @@ NativeInputEventReceiver::~NativeInputEventReceiver() { } status_t NativeInputEventReceiver::initialize() { int receiveFd = mInputConsumer.getChannel()->getFd(); mMessageQueue->getLooper()->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, this, NULL); setFdEvents(ALOOPER_EVENT_INPUT); return OK; } Loading @@ -102,7 +111,7 @@ void NativeInputEventReceiver::dispose() { ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName()); #endif mMessageQueue->getLooper()->removeFd(mInputConsumer.getChannel()->getFd()); setFdEvents(0); } status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) { Loading @@ -112,12 +121,38 @@ status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) status_t status = mInputConsumer.sendFinishedSignal(seq, handled); if (status) { if (status == WOULD_BLOCK) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Could not send finished signal immediately. " "Enqueued for later.", getInputChannelName()); #endif Finish finish; finish.seq = seq; finish.handled = handled; mFinishQueue.add(finish); if (mFinishQueue.size() == 1) { setFdEvents(ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT); } return OK; } ALOGW("Failed to send finished signal on channel '%s'. status=%d", getInputChannelName(), status); } return status; } void NativeInputEventReceiver::setFdEvents(int events) { if (mFdEvents != events) { mFdEvents = events; int fd = mInputConsumer.getChannel()->getFd(); if (events) { mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL); } else { mMessageQueue->getLooper()->removeFd(fd); } } } int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) { if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) { #if DEBUG_DISPATCH_CYCLE Loading @@ -130,18 +165,54 @@ int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) return 0; // remove the callback } if (!(events & ALOOPER_EVENT_INPUT)) { ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " "events=0x%x", getInputChannelName(), events); return 1; } if (events & ALOOPER_EVENT_INPUT) { JNIEnv* env = AndroidRuntime::getJNIEnv(); status_t status = consumeEvents(env, false /*consumeBatches*/, -1); mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); return status == OK || status == NO_MEMORY ? 1 : 0; } if (events & ALOOPER_EVENT_OUTPUT) { for (size_t i = 0; i < mFinishQueue.size(); i++) { const Finish& finish = mFinishQueue.itemAt(i); status_t status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled); if (status) { mFinishQueue.removeItemsAt(0, i); if (status == WOULD_BLOCK) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Sent %u queued finish events; %u left.", getInputChannelName(), i, mFinishQueue.size()); #endif return 1; // keep the callback, try again later } ALOGW("Failed to send finished signal on channel '%s'. status=%d", getInputChannelName(), status); if (status != DEAD_OBJECT) { JNIEnv* env = AndroidRuntime::getJNIEnv(); String8 message; message.appendFormat("Failed to finish input event. status=%d", status); jniThrowRuntimeException(env, message.string()); mMessageQueue->raiseAndClearException(env, "finishInputEvent"); } return 0; // remove the callback } } #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Sent %u queued finish events; none left.", getInputChannelName(), mFinishQueue.size()); #endif mFinishQueue.clear(); setFdEvents(ALOOPER_EVENT_INPUT); return 1; } ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " "events=0x%x", getInputChannelName(), events); return 1; } status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime) { #if DEBUG_DISPATCH_CYCLE Loading