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#include "JNIHelp.h" 22c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 23c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <android_runtime/AndroidRuntime.h> 24c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <utils/Log.h> 25c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <utils/Looper.h> 26c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <utils/threads.h> 27c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include <utils/KeyedVector.h> 289d3b1a424c5c61e24e9659d15fb353026a00d925Jeff Brown#include <input/InputTransport.h> 29c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include "android_os_MessageQueue.h" 30c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include "android_view_InputChannel.h" 31c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include "android_view_KeyEvent.h" 32c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown#include "android_view_MotionEvent.h" 33c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 34a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown#include <ScopedLocalRef.h> 35a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown 36987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe#include "core_jni_helpers.h" 37987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 38c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownnamespace android { 39c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 40ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe// Log debug messages about the dispatch cycle. 41ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampestatic const bool kDebugDispatchCycle = false; 42ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 43c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatic struct { 44c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jclass clazz; 45c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 46c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jmethodID dispatchInputEventFinished; 47c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} gInputEventSenderClassInfo; 48c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 49c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 50c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownclass NativeInputEventSender : public LooperCallback { 51c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownpublic: 52c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown NativeInputEventSender(JNIEnv* env, 53a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown jobject senderWeak, const sp<InputChannel>& inputChannel, 54c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown const sp<MessageQueue>& messageQueue); 55c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 56c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t initialize(); 57c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown void dispose(); 58c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t sendKeyEvent(uint32_t seq, const KeyEvent* event); 59c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t sendMotionEvent(uint32_t seq, const MotionEvent* event); 60c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 61c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownprotected: 62c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown virtual ~NativeInputEventSender(); 63c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 64c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownprivate: 65a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown jobject mSenderWeakGlobal; 66c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown InputPublisher mInputPublisher; 67c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<MessageQueue> mMessageQueue; 68c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown KeyedVector<uint32_t, uint32_t> mPublishedSeqMap; 69c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t mNextPublishedSeq; 70c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 71c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown const char* getInputChannelName() { 72c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return mInputPublisher.getChannel()->getName().string(); 73c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 74c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 75c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown virtual int handleEvent(int receiveFd, int events, void* data); 76c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t receiveFinishedSignals(JNIEnv* env); 77c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown}; 78c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 79c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 80c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff BrownNativeInputEventSender::NativeInputEventSender(JNIEnv* env, 81a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown jobject senderWeak, const sp<InputChannel>& inputChannel, 82c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown const sp<MessageQueue>& messageQueue) : 83a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown mSenderWeakGlobal(env->NewGlobalRef(senderWeak)), 84c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mInputPublisher(inputChannel), mMessageQueue(messageQueue), 8510f9b0997e0bde39fa153060db022a3982b78399Michael Wright mNextPublishedSeq(1) { 86ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe if (kDebugDispatchCycle) { 87ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe ALOGD("channel '%s' ~ Initializing input event sender.", getInputChannelName()); 88ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe } 89c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 90c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 91c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff BrownNativeInputEventSender::~NativeInputEventSender() { 92c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 93a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown env->DeleteGlobalRef(mSenderWeakGlobal); 94c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 95c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 96c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatus_t NativeInputEventSender::initialize() { 97c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown int receiveFd = mInputPublisher.getChannel()->getFd(); 98c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mMessageQueue->getLooper()->addFd(receiveFd, 0, ALOOPER_EVENT_INPUT, this, NULL); 99c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return OK; 100c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 101c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 102c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownvoid NativeInputEventSender::dispose() { 103ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe if (kDebugDispatchCycle) { 104ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe ALOGD("channel '%s' ~ Disposing input event sender.", getInputChannelName()); 105ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe } 106c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 107c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mMessageQueue->getLooper()->removeFd(mInputPublisher.getChannel()->getFd()); 108c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 109c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 110c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatus_t NativeInputEventSender::sendKeyEvent(uint32_t seq, const KeyEvent* event) { 111ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe if (kDebugDispatchCycle) { 112ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe ALOGD("channel '%s' ~ Sending key event, seq=%u.", getInputChannelName(), seq); 113ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe } 114c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 115c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t publishedSeq = mNextPublishedSeq++; 116c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = mInputPublisher.publishKeyEvent(publishedSeq, 117c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getDeviceId(), event->getSource(), event->getAction(), event->getFlags(), 118c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getKeyCode(), event->getScanCode(), event->getMetaState(), 119c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getRepeatCount(), event->getDownTime(), event->getEventTime()); 120c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status) { 121c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGW("Failed to send key event on channel '%s'. status=%d", 122c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown getInputChannelName(), status); 123c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return status; 124c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 125c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mPublishedSeqMap.add(publishedSeq, seq); 126c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return OK; 127c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 128c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 129c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatus_t NativeInputEventSender::sendMotionEvent(uint32_t seq, const MotionEvent* event) { 130ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe if (kDebugDispatchCycle) { 131ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe ALOGD("channel '%s' ~ Sending motion event, seq=%u.", getInputChannelName(), seq); 132ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe } 133c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 134c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t publishedSeq; 135c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown for (size_t i = 0; i <= event->getHistorySize(); i++) { 136c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown publishedSeq = mNextPublishedSeq++; 137c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = mInputPublisher.publishMotionEvent(publishedSeq, 1385bd69e6e6164c59a0423edd0d5243fc8c07e6af3Michael Wright event->getDeviceId(), event->getSource(), 1395bd69e6e6164c59a0423edd0d5243fc8c07e6af3Michael Wright event->getAction(), event->getActionButton(), event->getFlags(), 140c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getEdgeFlags(), event->getMetaState(), event->getButtonState(), 141c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getXOffset(), event->getYOffset(), 142c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getXPrecision(), event->getYPrecision(), 143c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getDownTime(), event->getHistoricalEventTime(i), 144c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getPointerCount(), event->getPointerProperties(), 145c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown event->getHistoricalRawPointerCoords(0, i)); 146c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status) { 147c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGW("Failed to send motion event sample on channel '%s'. status=%d", 148c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown getInputChannelName(), status); 149c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return status; 150c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 151c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 152c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mPublishedSeqMap.add(publishedSeq, seq); 153c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return OK; 154c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 155c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 156c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownint NativeInputEventSender::handleEvent(int receiveFd, int events, void* data) { 157c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) { 15844e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown // This error typically occurs when the consumer has closed the input channel 15944e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown // as part of finishing an IME session, in which case the publisher will 16044e13ef1a1aee36b4ce667670345de8ce4e6bb7bJeff Brown // soon be disposed as well. 161ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe if (kDebugDispatchCycle) { 162ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe ALOGD("channel '%s' ~ Consumer closed input channel or an error occurred. " 163ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe "events=0x%x", getInputChannelName(), events); 164ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe } 165ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe 166c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 0; // remove the callback 167c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 168c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 169c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (!(events & ALOOPER_EVENT_INPUT)) { 170c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. " 171c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown "events=0x%x", getInputChannelName(), events); 172c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 1; 173c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 174c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 175c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown JNIEnv* env = AndroidRuntime::getJNIEnv(); 176c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = receiveFinishedSignals(env); 177c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); 178c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return status == OK || status == NO_MEMORY ? 1 : 0; 179c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 180c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 181c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownstatus_t NativeInputEventSender::receiveFinishedSignals(JNIEnv* env) { 182ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe if (kDebugDispatchCycle) { 183ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe ALOGD("channel '%s' ~ Receiving finished signals.", getInputChannelName()); 184ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe } 185c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 186a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown ScopedLocalRef<jobject> senderObj(env, NULL); 187c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown bool skipCallbacks = false; 188c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown for (;;) { 189c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t publishedSeq; 190c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown bool handled; 191c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = mInputPublisher.receiveFinishedSignal(&publishedSeq, &handled); 192c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status) { 193c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status == WOULD_BLOCK) { 194c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return OK; 195c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 196c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGE("channel '%s' ~ Failed to consume finished signals. status=%d", 197c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown getInputChannelName(), status); 198c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return status; 199c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 200c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 201c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ssize_t index = mPublishedSeqMap.indexOfKey(publishedSeq); 202c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (index >= 0) { 203c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown uint32_t seq = mPublishedSeqMap.valueAt(index); 204c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown mPublishedSeqMap.removeItemsAt(index); 205c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 206ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe if (kDebugDispatchCycle) { 207ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe ALOGD("channel '%s' ~ Received finished signal, seq=%u, handled=%s, " 20846c82b4cd241a447834ed2f5a6be16777b7a990bBernhard Rosenkränzer "pendingEvents=%zu.", 209ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe getInputChannelName(), seq, handled ? "true" : "false", 210ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe mPublishedSeqMap.size()); 211ed6b9dff563c5e22f040ff37e12c0d771e0478aeAndreas Gampe } 212c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 213c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (!skipCallbacks) { 214a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown if (!senderObj.get()) { 215a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown senderObj.reset(jniGetReferent(env, mSenderWeakGlobal)); 216a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown if (!senderObj.get()) { 217a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown ALOGW("channel '%s' ~ Sender object was finalized " 218a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown "without being disposed.", getInputChannelName()); 219a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown return DEAD_OBJECT; 220a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown } 221a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown } 222a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown 223a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown env->CallVoidMethod(senderObj.get(), 224c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown gInputEventSenderClassInfo.dispatchInputEventFinished, 225c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jint(seq), jboolean(handled)); 226c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (env->ExceptionCheck()) { 227c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown ALOGE("Exception dispatching finished signal."); 228c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown skipCallbacks = true; 229c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 230c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 231c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 232c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 233c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 234c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 235c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 236a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic jlong nativeInit(JNIEnv* env, jclass clazz, jobject senderWeak, 237c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jobject inputChannelObj, jobject messageQueueObj) { 238c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env, 239c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown inputChannelObj); 240c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (inputChannel == NULL) { 241c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jniThrowRuntimeException(env, "InputChannel is not initialized."); 242c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 0; 243c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 244c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 245c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); 246c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (messageQueue == NULL) { 247c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jniThrowRuntimeException(env, "MessageQueue is not initialized."); 248c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 0; 249c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 250c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 251c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<NativeInputEventSender> sender = new NativeInputEventSender(env, 252a4ca8ea0ad14c509d1ced46482e83c1b8a518982Jeff Brown senderWeak, inputChannel, messageQueue); 253c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = sender->initialize(); 254c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown if (status) { 255c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown String8 message; 256c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown message.appendFormat("Failed to initialize input event sender. status=%d", status); 257c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jniThrowRuntimeException(env, message.string()); 258c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return 0; 259c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown } 260c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 261c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sender->incStrong(gInputEventSenderClassInfo.clazz); // retain a reference for the object 262a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat return reinterpret_cast<jlong>(sender.get()); 263c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 264c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 265a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic void nativeDispose(JNIEnv* env, jclass clazz, jlong senderPtr) { 266c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<NativeInputEventSender> sender = 267c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown reinterpret_cast<NativeInputEventSender*>(senderPtr); 268c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sender->dispose(); 269c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sender->decStrong(gInputEventSenderClassInfo.clazz); // drop reference held by the object 270c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 271c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 272a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic jboolean nativeSendKeyEvent(JNIEnv* env, jclass clazz, jlong senderPtr, 273c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jint seq, jobject eventObj) { 274c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<NativeInputEventSender> sender = 275c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown reinterpret_cast<NativeInputEventSender*>(senderPtr); 276c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown KeyEvent event; 277c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown android_view_KeyEvent_toNative(env, eventObj, &event); 278c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = sender->sendKeyEvent(seq, &event); 279c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return !status; 280c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 281c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 282a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhatstatic jboolean nativeSendMotionEvent(JNIEnv* env, jclass clazz, jlong senderPtr, 283c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown jint seq, jobject eventObj) { 284c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown sp<NativeInputEventSender> sender = 285c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown reinterpret_cast<NativeInputEventSender*>(senderPtr); 286c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown MotionEvent* event = android_view_MotionEvent_getNativePtr(env, eventObj); 287c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown status_t status = sender->sendMotionEvent(seq, event); 288c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown return !status; 289c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 290c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 291c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 29276f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod gMethods[] = { 293c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown /* name, signature, funcPtr */ 294c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown { "nativeInit", 295a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat "(Ljava/lang/ref/WeakReference;Landroid/view/InputChannel;Landroid/os/MessageQueue;)J", 296c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown (void*)nativeInit }, 297a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeDispose", "(J)V", 298c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown (void*)nativeDispose }, 299a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeSendKeyEvent", "(JILandroid/view/KeyEvent;)Z", 300c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown (void*)nativeSendKeyEvent }, 301a931d5218cfee89c7629ffa6cde324fa966449f9Ashok Bhat { "nativeSendMotionEvent", "(JILandroid/view/MotionEvent;)Z", 302c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown (void*)nativeSendMotionEvent }, 303c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown}; 304c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 305c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brownint register_android_view_InputEventSender(JNIEnv* env) { 306987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe int res = RegisterMethodsOrDie(env, "android/view/InputEventSender", gMethods, NELEM(gMethods)); 307987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe 308987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe jclass clazz = FindClassOrDie(env, "android/view/InputEventSender"); 309987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gInputEventSenderClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); 310c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 311987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe gInputEventSenderClassInfo.dispatchInputEventFinished = GetMethodIDOrDie( 312987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe env, gInputEventSenderClassInfo.clazz, "dispatchInputEventFinished", "(IZ)V"); 313c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 314987f79f60bb1f0a4bcd3ef22e57301c743f0b94fAndreas Gampe return res; 315c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} 316c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown 317c28867a1d67121ce5963de135e3ae2b1dbd9a33dJeff Brown} // namespace android 318