1c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown/* 2c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * Copyright (C) 2013 The Android Open Source Project 3c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * 4c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 5c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * you may not use this file except in compliance with the License. 6c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * You may obtain a copy of the License at 7c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * 8c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 9c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * 10c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * Unless required by applicable law or agreed to in writing, software 11c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 12c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * See the License for the specific language governing permissions and 14c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown * limitations under the License. 15c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown */ 16c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 17c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#define LOG_TAG "InputEventSender" 18c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 19c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown//#define LOG_NDEBUG 0 20c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 21c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown// Log debug messages about the dispatch cycle. 22c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#define DEBUG_DISPATCH_CYCLE 0 23c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 24c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 25c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include "JNIHelp.h" 26c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 27c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <android_runtime/AndroidRuntime.h> 28c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <utils/Log.h> 29c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <utils/Looper.h> 30c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <utils/threads.h> 31c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <utils/KeyedVector.h> 329d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brown#include <input/InputTransport.h> 33c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include "android_os_MessageQueue.h" 34c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include "android_view_InputChannel.h" 35c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include "android_view_KeyEvent.h" 36c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include "android_view_MotionEvent.h" 37c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 38a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown#include <ScopedLocalRef.h> 39a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown 40c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownnamespace android { 41c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 42c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatic struct { 43c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jclass clazz; 44c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 45c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jmethodID dispatchInputEventFinished; 46c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} gInputEventSenderClassInfo; 47c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 48c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 49c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownclass NativeInputEventSender : public LooperCallback { 50c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownpublic: 51c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown NativeInputEventSender(JNIEnv* env, 52a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown jobject senderWeak, const sp<InputChannel>& inputChannel, 53c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown const sp<MessageQueue>& messageQueue); 54c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 55c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t initialize(); 56c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown void dispose(); 57c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t sendKeyEvent(uint32_t seq, const KeyEvent* event); 58c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t sendMotionEvent(uint32_t seq, const MotionEvent* event); 59c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 60c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownprotected: 61c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown virtual ~NativeInputEventSender(); 62c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 63c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownprivate: 64a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown jobject mSenderWeakGlobal; 65c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown InputPublisher mInputPublisher; 66c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<MessageQueue> mMessageQueue; 67c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown KeyedVector<uint32_t, uint32_t> mPublishedSeqMap; 68c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t mNextPublishedSeq; 69c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 70c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown const char* getInputChannelName() { 71c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return mInputPublisher.getChannel()->getName().string(); 72c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 73c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 74c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown virtual int handleEvent(int receiveFd, int events, void* data); 75c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t receiveFinishedSignals(JNIEnv* env); 76c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown}; 77c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 78c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 79c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff BrownNativeInputEventSender::NativeInputEventSender(JNIEnv* env, 80a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown jobject senderWeak, const sp<InputChannel>& inputChannel, 81c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown const sp<MessageQueue>& messageQueue) : 82a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown mSenderWeakGlobal(env->NewGlobalRef(senderWeak)), 83c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mInputPublisher(inputChannel), mMessageQueue(messageQueue), 8410f9b0997e0bde39fa153060db022a3982b78399Michael Wright mNextPublishedSeq(1) { 85c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#if DEBUG_DISPATCH_CYCLE 86c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGD("channel '%s' ~ Initializing input event sender.", getInputChannelName()); 87c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#endif 88c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 89c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 90c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff BrownNativeInputEventSender::~NativeInputEventSender() { 91c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 92a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown env->DeleteGlobalRef(mSenderWeakGlobal); 93c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 94c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 95c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatus_t NativeInputEventSender::initialize() { 96c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown int receiveFd = mInputPublisher.getChannel()->getFd(); 97c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mMessageQueue->getLooper()->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, this, NULL); 98c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return OK; 99c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 100c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 101c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownvoid NativeInputEventSender::dispose() { 102c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#if DEBUG_DISPATCH_CYCLE 103c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGD("channel '%s' ~ Disposing input event sender.", getInputChannelName()); 104c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#endif 105c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 106c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mMessageQueue->getLooper()->removeFd(mInputPublisher.getChannel()->getFd()); 107c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 108c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 109c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatus_t NativeInputEventSender::sendKeyEvent(uint32_t seq, const KeyEvent* event) { 110c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#if DEBUG_DISPATCH_CYCLE 111c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGD("channel '%s' ~ Sending key event, seq=%u.", getInputChannelName(), seq); 112c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#endif 113c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 114c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t publishedSeq = mNextPublishedSeq++; 115c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = mInputPublisher.publishKeyEvent(publishedSeq, 116c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getDeviceId(), event->getSource(), event->getAction(), event->getFlags(), 117c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getKeyCode(), event->getScanCode(), event->getMetaState(), 118c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getRepeatCount(), event->getDownTime(), event->getEventTime()); 119c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status) { 120c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGW("Failed to send key event on channel '%s'. status=%d", 121c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown getInputChannelName(), status); 122c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return status; 123c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 124c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mPublishedSeqMap.add(publishedSeq, seq); 125c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return OK; 126c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 127c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 128c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatus_t NativeInputEventSender::sendMotionEvent(uint32_t seq, const MotionEvent* event) { 129c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#if DEBUG_DISPATCH_CYCLE 130c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGD("channel '%s' ~ Sending motion event, seq=%u.", getInputChannelName(), seq); 131c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#endif 132c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 133c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t publishedSeq; 134c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown for (size_t i = 0; i <= event->getHistorySize(); i++) { 135c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown publishedSeq = mNextPublishedSeq++; 136c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = mInputPublisher.publishMotionEvent(publishedSeq, 137c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getDeviceId(), event->getSource(), event->getAction(), event->getFlags(), 138c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getEdgeFlags(), event->getMetaState(), event->getButtonState(), 139c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getXOffset(), event->getYOffset(), 140c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getXPrecision(), event->getYPrecision(), 141c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getDownTime(), event->getHistoricalEventTime(i), 142c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getPointerCount(), event->getPointerProperties(), 143c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getHistoricalRawPointerCoords(0, i)); 144c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status) { 145c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGW("Failed to send motion event sample on channel '%s'. status=%d", 146c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown getInputChannelName(), status); 147c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return status; 148c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 149c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 150c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mPublishedSeqMap.add(publishedSeq, seq); 151c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return OK; 152c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 153c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 154c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownint NativeInputEventSender::handleEvent(int receiveFd, int events, void* data) { 155c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) { 15644e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown#if DEBUG_DISPATCH_CYCLE 15744e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown // This error typically occurs when the consumer has closed the input channel 15844e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown // as part of finishing an IME session, in which case the publisher will 15944e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown // soon be disposed as well. 16044e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown ALOGD("channel '%s' ~ Consumer closed input channel or an error occurred. " 161c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown "events=0x%x", getInputChannelName(), events); 16244e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown#endif 163c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 0; // remove the callback 164c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 165c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 166c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (!(events & ALOOPER_EVENT_INPUT)) { 167c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " 168c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown "events=0x%x", getInputChannelName(), events); 169c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 1; 170c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 171c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 172c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 173c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = receiveFinishedSignals(env); 174c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); 175c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return status == OK || status == NO_MEMORY ? 1 : 0; 176c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 177c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 178c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatus_t NativeInputEventSender::receiveFinishedSignals(JNIEnv* env) { 179c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#if DEBUG_DISPATCH_CYCLE 180c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGD("channel '%s' ~ Receiving finished signals.", getInputChannelName()); 181c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#endif 182c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 183a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown ScopedLocalRef<jobject> senderObj(env, NULL); 184c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown bool skipCallbacks = false; 185c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown for (;;) { 186c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t publishedSeq; 187c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown bool handled; 188c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = mInputPublisher.receiveFinishedSignal(&publishedSeq, &handled); 189c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status) { 190c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status == WOULD_BLOCK) { 191c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return OK; 192c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 193c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGE("channel '%s' ~ Failed to consume finished signals. status=%d", 194c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown getInputChannelName(), status); 195c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return status; 196c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 197c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 198c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ssize_t index = mPublishedSeqMap.indexOfKey(publishedSeq); 199c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (index >= 0) { 200c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t seq = mPublishedSeqMap.valueAt(index); 201c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mPublishedSeqMap.removeItemsAt(index); 202c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 203c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#if DEBUG_DISPATCH_CYCLE 204c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGD("channel '%s' ~ Received finished signal, seq=%u, handled=%s, " 205c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown "pendingEvents=%u.", 206c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown getInputChannelName(), seq, handled ? "true" : "false", 207c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mPublishedSeqMap.size()); 208c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#endif 209c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 210c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (!skipCallbacks) { 211a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown if (!senderObj.get()) { 212a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown senderObj.reset(jniGetReferent(env, mSenderWeakGlobal)); 213a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown if (!senderObj.get()) { 214a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown ALOGW("channel '%s' ~ Sender object was finalized " 215a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown "without being disposed.", getInputChannelName()); 216a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown return DEAD_OBJECT; 217a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown } 218a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown } 219a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown 220a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown env->CallVoidMethod(senderObj.get(), 221c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown gInputEventSenderClassInfo.dispatchInputEventFinished, 222c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jint(seq), jboolean(handled)); 223c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (env->ExceptionCheck()) { 224c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGE("Exception dispatching finished signal."); 225c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown skipCallbacks = true; 226c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 227c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 228c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 229c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 230c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 231c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 232c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 233a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic jlong nativeInit(JNIEnv* env, jclass clazz, jobject senderWeak, 234c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jobject inputChannelObj, jobject messageQueueObj) { 235c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, 236c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown inputChannelObj); 237c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (inputChannel == NULL) { 238c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jniThrowRuntimeException(env, "InputChannel is not initialized."); 239c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 0; 240c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 241c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 242c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); 243c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (messageQueue == NULL) { 244c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jniThrowRuntimeException(env, "MessageQueue is not initialized."); 245c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 0; 246c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 247c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 248c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<NativeInputEventSender> sender = new NativeInputEventSender(env, 249a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown senderWeak, inputChannel, messageQueue); 250c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = sender->initialize(); 251c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status) { 252c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown String8 message; 253c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown message.appendFormat("Failed to initialize input event sender. status=%d", status); 254c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jniThrowRuntimeException(env, message.string()); 255c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 0; 256c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 257c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 258c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sender->incStrong(gInputEventSenderClassInfo.clazz); // retain a reference for the object 259a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat return reinterpret_cast<jlong>(sender.get()); 260c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 261c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 262a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic void nativeDispose(JNIEnv* env, jclass clazz, jlong senderPtr) { 263c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<NativeInputEventSender> sender = 264c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown reinterpret_cast<NativeInputEventSender*>(senderPtr); 265c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sender->dispose(); 266c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sender->decStrong(gInputEventSenderClassInfo.clazz); // drop reference held by the object 267c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 268c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 269a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic jboolean nativeSendKeyEvent(JNIEnv* env, jclass clazz, jlong senderPtr, 270c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jint seq, jobject eventObj) { 271c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<NativeInputEventSender> sender = 272c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown reinterpret_cast<NativeInputEventSender*>(senderPtr); 273c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown KeyEvent event; 274c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown android_view_KeyEvent_toNative(env, eventObj, &event); 275c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = sender->sendKeyEvent(seq, &event); 276c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return !status; 277c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 278c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 279a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic jboolean nativeSendMotionEvent(JNIEnv* env, jclass clazz, jlong senderPtr, 280c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jint seq, jobject eventObj) { 281c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<NativeInputEventSender> sender = 282c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown reinterpret_cast<NativeInputEventSender*>(senderPtr); 283c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown MotionEvent* event = android_view_MotionEvent_getNativePtr(env, eventObj); 284c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = sender->sendMotionEvent(seq, event); 285c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return !status; 286c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 287c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 288c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 289c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatic JNINativeMethod gMethods[] = { 290c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown /* name, signature, funcPtr */ 291c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown { "nativeInit", 292a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat "(Ljava/lang/ref/WeakReference;Landroid/view/InputChannel;Landroid/os/MessageQueue;)J", 293c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown (void*)nativeInit }, 294a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeDispose", "(J)V", 295c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown (void*)nativeDispose }, 296a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeSendKeyEvent", "(JILandroid/view/KeyEvent;)Z", 297c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown (void*)nativeSendKeyEvent }, 298a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeSendMotionEvent", "(JILandroid/view/MotionEvent;)Z", 299c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown (void*)nativeSendMotionEvent }, 300c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown}; 301c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 302c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#define FIND_CLASS(var, className) \ 303c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown var = env->FindClass(className); \ 304c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown LOG_FATAL_IF(! var, "Unable to find class " className); \ 305c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown var = jclass(env->NewGlobalRef(var)); 306c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 307c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 308c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 309c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown LOG_FATAL_IF(! var, "Unable to find method " methodName); 310c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 311c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownint register_android_view_InputEventSender(JNIEnv* env) { 312c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown int res = jniRegisterNativeMethods(env, "android/view/InputEventSender", 313c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown gMethods, NELEM(gMethods)); 314c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown LOG_FATAL_IF(res < 0, "Unable to register native methods."); 315c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 316c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown FIND_CLASS(gInputEventSenderClassInfo.clazz, "android/view/InputEventSender"); 317c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 318c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown GET_METHOD_ID(gInputEventSenderClassInfo.dispatchInputEventFinished, 319c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown gInputEventSenderClassInfo.clazz, 320c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown "dispatchInputEventFinished", "(IZ)V"); 321c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 0; 322c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 323c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 324c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} // namespace android 325