blob: 52c84a4f2cc6929462a0bd5587c43503bfb6fad0 [file] [log] [blame]
Jeff Brown32cbc38552011-12-01 14:01:49 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "InputEventReceiver"
18
19//#define LOG_NDEBUG 0
20
Steven Moreland2279b252017-07-19 09:50:45 -070021#include <nativehelper/JNIHelp.h>
Jeff Brown32cbc38552011-12-01 14:01:49 -080022
23#include <android_runtime/AndroidRuntime.h>
24#include <utils/Log.h>
25#include <utils/Looper.h>
Jeff Brown56513492013-05-21 20:37:51 -070026#include <utils/Vector.h>
Jeff Brown32cbc38552011-12-01 14:01:49 -080027#include <utils/threads.h>
Jeff Brown9d3b1a42013-07-01 19:07:15 -070028#include <input/InputTransport.h>
Jeff Brown32cbc38552011-12-01 14:01:49 -080029#include "android_os_MessageQueue.h"
30#include "android_view_InputChannel.h"
31#include "android_view_KeyEvent.h"
32#include "android_view_MotionEvent.h"
33
Steven Moreland2279b252017-07-19 09:50:45 -070034#include <nativehelper/ScopedLocalRef.h>
Jeff Browna4ca8ea2013-04-02 18:01:38 -070035
Andreas Gampe987f79f2014-11-18 17:29:46 -080036#include "core_jni_helpers.h"
37
Jeff Brown32cbc38552011-12-01 14:01:49 -080038namespace android {
39
Andreas Gampeed6b9df2014-11-20 22:02:20 -080040static const bool kDebugDispatchCycle = false;
41
Jeff Brown32cbc38552011-12-01 14:01:49 -080042static struct {
43 jclass clazz;
44
45 jmethodID dispatchInputEvent;
Jeff Brown072ec962012-02-07 14:46:57 -080046 jmethodID dispatchBatchedInputEventPending;
Jeff Brown32cbc38552011-12-01 14:01:49 -080047} gInputEventReceiverClassInfo;
48
49
Jeff Brown80a1de12012-05-31 16:23:11 -070050class NativeInputEventReceiver : public LooperCallback {
Jeff Brown32cbc38552011-12-01 14:01:49 -080051public:
52 NativeInputEventReceiver(JNIEnv* env,
Jeff Browna4ca8ea2013-04-02 18:01:38 -070053 jobject receiverWeak, const sp<InputChannel>& inputChannel,
Jeff Brown603b4452012-04-06 17:39:41 -070054 const sp<MessageQueue>& messageQueue);
Jeff Brown32cbc38552011-12-01 14:01:49 -080055
56 status_t initialize();
Jeff Brown80a1de12012-05-31 16:23:11 -070057 void dispose();
Jeff Brown072ec962012-02-07 14:46:57 -080058 status_t finishInputEvent(uint32_t seq, bool handled);
Michael Wright62ce65d2013-10-25 14:50:36 -070059 status_t consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime,
60 bool* outConsumedBatch);
Jeff Brown32cbc38552011-12-01 14:01:49 -080061
62protected:
63 virtual ~NativeInputEventReceiver();
64
65private:
Jeff Brown56513492013-05-21 20:37:51 -070066 struct Finish {
67 uint32_t seq;
68 bool handled;
69 };
70
Jeff Browna4ca8ea2013-04-02 18:01:38 -070071 jobject mReceiverWeakGlobal;
Jeff Brown32cbc38552011-12-01 14:01:49 -080072 InputConsumer mInputConsumer;
Jeff Brown603b4452012-04-06 17:39:41 -070073 sp<MessageQueue> mMessageQueue;
Jeff Brown32cbc38552011-12-01 14:01:49 -080074 PreallocatedInputEventFactory mInputEventFactory;
Jeff Brown072ec962012-02-07 14:46:57 -080075 bool mBatchedInputEventPending;
Jeff Brown56513492013-05-21 20:37:51 -070076 int mFdEvents;
77 Vector<Finish> mFinishQueue;
78
79 void setFdEvents(int events);
Jeff Brown32cbc38552011-12-01 14:01:49 -080080
81 const char* getInputChannelName() {
Siarhei Vishniakou8e960d72017-11-22 19:12:22 -080082 return mInputConsumer.getChannel()->getName().c_str();
Jeff Brown32cbc38552011-12-01 14:01:49 -080083 }
Jeff Brown3bdcdd82012-04-10 20:36:07 -070084
Jeff Brown80a1de12012-05-31 16:23:11 -070085 virtual int handleEvent(int receiveFd, int events, void* data);
Jeff Brown32cbc38552011-12-01 14:01:49 -080086};
87
88
89NativeInputEventReceiver::NativeInputEventReceiver(JNIEnv* env,
Jeff Browna4ca8ea2013-04-02 18:01:38 -070090 jobject receiverWeak, const sp<InputChannel>& inputChannel,
Jeff Brown603b4452012-04-06 17:39:41 -070091 const sp<MessageQueue>& messageQueue) :
Jeff Browna4ca8ea2013-04-02 18:01:38 -070092 mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
Jeff Brown603b4452012-04-06 17:39:41 -070093 mInputConsumer(inputChannel), mMessageQueue(messageQueue),
Jeff Brown56513492013-05-21 20:37:51 -070094 mBatchedInputEventPending(false), mFdEvents(0) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -080095 if (kDebugDispatchCycle) {
96 ALOGD("channel '%s' ~ Initializing input event receiver.", getInputChannelName());
97 }
Jeff Brown32cbc38552011-12-01 14:01:49 -080098}
99
100NativeInputEventReceiver::~NativeInputEventReceiver() {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800101 JNIEnv* env = AndroidRuntime::getJNIEnv();
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700102 env->DeleteGlobalRef(mReceiverWeakGlobal);
Jeff Brown32cbc38552011-12-01 14:01:49 -0800103}
104
105status_t NativeInputEventReceiver::initialize() {
Jeff Brown56513492013-05-21 20:37:51 -0700106 setFdEvents(ALOOPER_EVENT_INPUT);
Jeff Brown32cbc38552011-12-01 14:01:49 -0800107 return OK;
108}
109
Jeff Brown80a1de12012-05-31 16:23:11 -0700110void NativeInputEventReceiver::dispose() {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800111 if (kDebugDispatchCycle) {
112 ALOGD("channel '%s' ~ Disposing input event receiver.", getInputChannelName());
113 }
Jeff Brown80a1de12012-05-31 16:23:11 -0700114
Jeff Brown56513492013-05-21 20:37:51 -0700115 setFdEvents(0);
Jeff Brown80a1de12012-05-31 16:23:11 -0700116}
117
Jeff Brown072ec962012-02-07 14:46:57 -0800118status_t NativeInputEventReceiver::finishInputEvent(uint32_t seq, bool handled) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800119 if (kDebugDispatchCycle) {
120 ALOGD("channel '%s' ~ Finished input event.", getInputChannelName());
121 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800122
Jeff Brown072ec962012-02-07 14:46:57 -0800123 status_t status = mInputConsumer.sendFinishedSignal(seq, handled);
124 if (status) {
Jeff Brown56513492013-05-21 20:37:51 -0700125 if (status == WOULD_BLOCK) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800126 if (kDebugDispatchCycle) {
127 ALOGD("channel '%s' ~ Could not send finished signal immediately. "
128 "Enqueued for later.", getInputChannelName());
129 }
Jeff Brown56513492013-05-21 20:37:51 -0700130 Finish finish;
131 finish.seq = seq;
132 finish.handled = handled;
133 mFinishQueue.add(finish);
134 if (mFinishQueue.size() == 1) {
135 setFdEvents(ALOOPER_EVENT_INPUT | ALOOPER_EVENT_OUTPUT);
136 }
137 return OK;
138 }
Jeff Brown072ec962012-02-07 14:46:57 -0800139 ALOGW("Failed to send finished signal on channel '%s'. status=%d",
140 getInputChannelName(), status);
Jeff Brown32cbc38552011-12-01 14:01:49 -0800141 }
Jeff Brown072ec962012-02-07 14:46:57 -0800142 return status;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800143}
144
Jeff Brown56513492013-05-21 20:37:51 -0700145void NativeInputEventReceiver::setFdEvents(int events) {
146 if (mFdEvents != events) {
147 mFdEvents = events;
148 int fd = mInputConsumer.getChannel()->getFd();
149 if (events) {
150 mMessageQueue->getLooper()->addFd(fd, 0, events, this, NULL);
151 } else {
152 mMessageQueue->getLooper()->removeFd(fd);
153 }
154 }
155}
156
Jeff Brown80a1de12012-05-31 16:23:11 -0700157int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800158 if (events & (ALOOPER_EVENT_ERROR | ALOOPER_EVENT_HANGUP)) {
Jeff Brown44e13ef2013-03-27 12:34:30 -0700159 // This error typically occurs when the publisher has closed the input channel
160 // as part of removing a window or finishing an IME session, in which case
161 // the consumer will soon be disposed as well.
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800162 if (kDebugDispatchCycle) {
163 ALOGD("channel '%s' ~ Publisher closed input channel or an error occurred. "
164 "events=0x%x", getInputChannelName(), events);
165 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800166 return 0; // remove the callback
167 }
168
Jeff Brown56513492013-05-21 20:37:51 -0700169 if (events & ALOOPER_EVENT_INPUT) {
170 JNIEnv* env = AndroidRuntime::getJNIEnv();
Michael Wright62ce65d2013-10-25 14:50:36 -0700171 status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL);
Jeff Brown56513492013-05-21 20:37:51 -0700172 mMessageQueue->raiseAndClearException(env, "handleReceiveCallback");
173 return status == OK || status == NO_MEMORY ? 1 : 0;
174 }
175
176 if (events & ALOOPER_EVENT_OUTPUT) {
177 for (size_t i = 0; i < mFinishQueue.size(); i++) {
178 const Finish& finish = mFinishQueue.itemAt(i);
179 status_t status = mInputConsumer.sendFinishedSignal(finish.seq, finish.handled);
180 if (status) {
181 mFinishQueue.removeItemsAt(0, i);
182
183 if (status == WOULD_BLOCK) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800184 if (kDebugDispatchCycle) {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +0100185 ALOGD("channel '%s' ~ Sent %zu queued finish events; %zu left.",
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800186 getInputChannelName(), i, mFinishQueue.size());
187 }
Jeff Brown56513492013-05-21 20:37:51 -0700188 return 1; // keep the callback, try again later
189 }
190
191 ALOGW("Failed to send finished signal on channel '%s'. status=%d",
192 getInputChannelName(), status);
193 if (status != DEAD_OBJECT) {
194 JNIEnv* env = AndroidRuntime::getJNIEnv();
195 String8 message;
196 message.appendFormat("Failed to finish input event. status=%d", status);
197 jniThrowRuntimeException(env, message.string());
198 mMessageQueue->raiseAndClearException(env, "finishInputEvent");
199 }
200 return 0; // remove the callback
201 }
202 }
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800203 if (kDebugDispatchCycle) {
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +0100204 ALOGD("channel '%s' ~ Sent %zu queued finish events; none left.",
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800205 getInputChannelName(), mFinishQueue.size());
206 }
Jeff Brown56513492013-05-21 20:37:51 -0700207 mFinishQueue.clear();
208 setFdEvents(ALOOPER_EVENT_INPUT);
Jeff Brown32cbc38552011-12-01 14:01:49 -0800209 return 1;
210 }
211
Jeff Brown56513492013-05-21 20:37:51 -0700212 ALOGW("channel '%s' ~ Received spurious callback for unhandled poll event. "
213 "events=0x%x", getInputChannelName(), events);
214 return 1;
Jeff Brown072ec962012-02-07 14:46:57 -0800215}
Jeff Brown32cbc38552011-12-01 14:01:49 -0800216
Jeff Brown771526c2012-04-27 15:13:25 -0700217status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env,
Michael Wright62ce65d2013-10-25 14:50:36 -0700218 bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800219 if (kDebugDispatchCycle) {
220 ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s, frameTime=%lld.",
Bernhard Rosenkränzer46c82b42014-11-30 11:04:10 +0100221 getInputChannelName(), consumeBatches ? "true" : "false", (long long)frameTime);
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800222 }
Jeff Brown072ec962012-02-07 14:46:57 -0800223
224 if (consumeBatches) {
225 mBatchedInputEventPending = false;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800226 }
Michael Wright62ce65d2013-10-25 14:50:36 -0700227 if (outConsumedBatch) {
228 *outConsumedBatch = false;
229 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800230
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700231 ScopedLocalRef<jobject> receiverObj(env, NULL);
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700232 bool skipCallbacks = false;
Jeff Brown072ec962012-02-07 14:46:57 -0800233 for (;;) {
234 uint32_t seq;
235 InputEvent* inputEvent;
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700236 int32_t displayId;
Jeff Brown072ec962012-02-07 14:46:57 -0800237 status_t status = mInputConsumer.consume(&mInputEventFactory,
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700238 consumeBatches, frameTime, &seq, &inputEvent, &displayId);
Jeff Brown072ec962012-02-07 14:46:57 -0800239 if (status) {
240 if (status == WOULD_BLOCK) {
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700241 if (!skipCallbacks && !mBatchedInputEventPending
242 && mInputConsumer.hasPendingBatch()) {
Jeff Brown072ec962012-02-07 14:46:57 -0800243 // There is a pending batch. Come back later.
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700244 if (!receiverObj.get()) {
245 receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
246 if (!receiverObj.get()) {
247 ALOGW("channel '%s' ~ Receiver object was finalized "
248 "without being disposed.", getInputChannelName());
249 return DEAD_OBJECT;
250 }
251 }
252
Jeff Brown072ec962012-02-07 14:46:57 -0800253 mBatchedInputEventPending = true;
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800254 if (kDebugDispatchCycle) {
255 ALOGD("channel '%s' ~ Dispatching batched input event pending notification.",
256 getInputChannelName());
257 }
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700258 env->CallVoidMethod(receiverObj.get(),
Jeff Brown072ec962012-02-07 14:46:57 -0800259 gInputEventReceiverClassInfo.dispatchBatchedInputEventPending);
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700260 if (env->ExceptionCheck()) {
261 ALOGE("Exception dispatching batched input events.");
Jeff Brown072ec962012-02-07 14:46:57 -0800262 mBatchedInputEventPending = false; // try again later
263 }
264 }
265 return OK;
266 }
267 ALOGE("channel '%s' ~ Failed to consume input event. status=%d",
268 getInputChannelName(), status);
269 return status;
270 }
271 assert(inputEvent);
272
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700273 if (!skipCallbacks) {
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700274 if (!receiverObj.get()) {
275 receiverObj.reset(jniGetReferent(env, mReceiverWeakGlobal));
276 if (!receiverObj.get()) {
277 ALOGW("channel '%s' ~ Receiver object was finalized "
278 "without being disposed.", getInputChannelName());
279 return DEAD_OBJECT;
280 }
281 }
282
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700283 jobject inputEventObj;
284 switch (inputEvent->getType()) {
285 case AINPUT_EVENT_TYPE_KEY:
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800286 if (kDebugDispatchCycle) {
287 ALOGD("channel '%s' ~ Received key event.", getInputChannelName());
288 }
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700289 inputEventObj = android_view_KeyEvent_fromNative(env,
290 static_cast<KeyEvent*>(inputEvent));
291 break;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800292
Michael Wright62ce65d2013-10-25 14:50:36 -0700293 case AINPUT_EVENT_TYPE_MOTION: {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800294 if (kDebugDispatchCycle) {
295 ALOGD("channel '%s' ~ Received motion event.", getInputChannelName());
296 }
Michael Wright62ce65d2013-10-25 14:50:36 -0700297 MotionEvent* motionEvent = static_cast<MotionEvent*>(inputEvent);
298 if ((motionEvent->getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) {
299 *outConsumedBatch = true;
300 }
301 inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent);
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700302 break;
Michael Wright62ce65d2013-10-25 14:50:36 -0700303 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800304
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700305 default:
306 assert(false); // InputConsumer should prevent this from ever happening
307 inputEventObj = NULL;
308 }
309
310 if (inputEventObj) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800311 if (kDebugDispatchCycle) {
312 ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName());
313 }
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700314 env->CallVoidMethod(receiverObj.get(),
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700315 gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj,
316 displayId);
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700317 if (env->ExceptionCheck()) {
318 ALOGE("Exception dispatching input event.");
319 skipCallbacks = true;
320 }
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700321 env->DeleteLocalRef(inputEventObj);
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700322 } else {
323 ALOGW("channel '%s' ~ Failed to obtain event object.", getInputChannelName());
324 skipCallbacks = true;
325 }
Jeff Brown072ec962012-02-07 14:46:57 -0800326 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800327
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700328 if (skipCallbacks) {
Jeff Brown072ec962012-02-07 14:46:57 -0800329 mInputConsumer.sendFinishedSignal(seq, false);
Jeff Brown32cbc38552011-12-01 14:01:49 -0800330 }
331 }
Jeff Brown32cbc38552011-12-01 14:01:49 -0800332}
333
334
Ashok Bhata931d5212014-01-08 14:04:51 +0000335static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
Jeff Brown32cbc38552011-12-01 14:01:49 -0800336 jobject inputChannelObj, jobject messageQueueObj) {
337 sp<InputChannel> inputChannel = android_view_InputChannel_getInputChannel(env,
338 inputChannelObj);
339 if (inputChannel == NULL) {
340 jniThrowRuntimeException(env, "InputChannel is not initialized.");
341 return 0;
342 }
343
Jeff Brown603b4452012-04-06 17:39:41 -0700344 sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
345 if (messageQueue == NULL) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800346 jniThrowRuntimeException(env, "MessageQueue is not initialized.");
347 return 0;
348 }
349
350 sp<NativeInputEventReceiver> receiver = new NativeInputEventReceiver(env,
Jeff Browna4ca8ea2013-04-02 18:01:38 -0700351 receiverWeak, inputChannel, messageQueue);
Jeff Brown32cbc38552011-12-01 14:01:49 -0800352 status_t status = receiver->initialize();
353 if (status) {
354 String8 message;
355 message.appendFormat("Failed to initialize input event receiver. status=%d", status);
356 jniThrowRuntimeException(env, message.string());
357 return 0;
358 }
359
360 receiver->incStrong(gInputEventReceiverClassInfo.clazz); // retain a reference for the object
Ashok Bhata931d5212014-01-08 14:04:51 +0000361 return reinterpret_cast<jlong>(receiver.get());
Jeff Brown32cbc38552011-12-01 14:01:49 -0800362}
363
Ashok Bhata931d5212014-01-08 14:04:51 +0000364static void nativeDispose(JNIEnv* env, jclass clazz, jlong receiverPtr) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800365 sp<NativeInputEventReceiver> receiver =
366 reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
Jeff Brown80a1de12012-05-31 16:23:11 -0700367 receiver->dispose();
Jeff Brown32cbc38552011-12-01 14:01:49 -0800368 receiver->decStrong(gInputEventReceiverClassInfo.clazz); // drop reference held by the object
369}
370
Ashok Bhata931d5212014-01-08 14:04:51 +0000371static void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jlong receiverPtr,
Jeff Brown072ec962012-02-07 14:46:57 -0800372 jint seq, jboolean handled) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800373 sp<NativeInputEventReceiver> receiver =
374 reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
Jeff Brown072ec962012-02-07 14:46:57 -0800375 status_t status = receiver->finishInputEvent(seq, handled);
Jeff Brown9806a232012-02-17 10:28:09 -0800376 if (status && status != DEAD_OBJECT) {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800377 String8 message;
378 message.appendFormat("Failed to finish input event. status=%d", status);
379 jniThrowRuntimeException(env, message.string());
380 }
381}
382
Ashok Bhata931d5212014-01-08 14:04:51 +0000383static jboolean nativeConsumeBatchedInputEvents(JNIEnv* env, jclass clazz, jlong receiverPtr,
Jeff Brown771526c2012-04-27 15:13:25 -0700384 jlong frameTimeNanos) {
Jeff Brown072ec962012-02-07 14:46:57 -0800385 sp<NativeInputEventReceiver> receiver =
386 reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
Michael Wright62ce65d2013-10-25 14:50:36 -0700387 bool consumedBatch;
388 status_t status = receiver->consumeEvents(env, true /*consumeBatches*/, frameTimeNanos,
389 &consumedBatch);
Jeff Brown3bdcdd82012-04-10 20:36:07 -0700390 if (status && status != DEAD_OBJECT && !env->ExceptionCheck()) {
Jeff Brown072ec962012-02-07 14:46:57 -0800391 String8 message;
392 message.appendFormat("Failed to consume batched input event. status=%d", status);
393 jniThrowRuntimeException(env, message.string());
Ashok Bhata931d5212014-01-08 14:04:51 +0000394 return JNI_FALSE;
Jeff Brown072ec962012-02-07 14:46:57 -0800395 }
Ashok Bhata931d5212014-01-08 14:04:51 +0000396 return consumedBatch ? JNI_TRUE : JNI_FALSE;
Jeff Brown072ec962012-02-07 14:46:57 -0800397}
398
Jeff Brown32cbc38552011-12-01 14:01:49 -0800399
Daniel Micay76f6a862015-09-19 17:31:01 -0400400static const JNINativeMethod gMethods[] = {
Jeff Brown32cbc38552011-12-01 14:01:49 -0800401 /* name, signature, funcPtr */
402 { "nativeInit",
Ashok Bhata931d5212014-01-08 14:04:51 +0000403 "(Ljava/lang/ref/WeakReference;Landroid/view/InputChannel;Landroid/os/MessageQueue;)J",
Jeff Brown32cbc38552011-12-01 14:01:49 -0800404 (void*)nativeInit },
Ashok Bhata931d5212014-01-08 14:04:51 +0000405 { "nativeDispose", "(J)V",
Jeff Brown32cbc38552011-12-01 14:01:49 -0800406 (void*)nativeDispose },
Ashok Bhata931d5212014-01-08 14:04:51 +0000407 { "nativeFinishInputEvent", "(JIZ)V",
Jeff Brown072ec962012-02-07 14:46:57 -0800408 (void*)nativeFinishInputEvent },
Ashok Bhata931d5212014-01-08 14:04:51 +0000409 { "nativeConsumeBatchedInputEvents", "(JJ)Z",
Jeff Brown072ec962012-02-07 14:46:57 -0800410 (void*)nativeConsumeBatchedInputEvents },
Jeff Brown32cbc38552011-12-01 14:01:49 -0800411};
412
Jeff Brown32cbc38552011-12-01 14:01:49 -0800413int register_android_view_InputEventReceiver(JNIEnv* env) {
Andreas Gampe987f79f2014-11-18 17:29:46 -0800414 int res = RegisterMethodsOrDie(env, "android/view/InputEventReceiver",
Jeff Brown32cbc38552011-12-01 14:01:49 -0800415 gMethods, NELEM(gMethods));
Jeff Brown32cbc38552011-12-01 14:01:49 -0800416
Andreas Gampe987f79f2014-11-18 17:29:46 -0800417 jclass clazz = FindClassOrDie(env, "android/view/InputEventReceiver");
418 gInputEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
Jeff Brown32cbc38552011-12-01 14:01:49 -0800419
Andreas Gampe987f79f2014-11-18 17:29:46 -0800420 gInputEventReceiverClassInfo.dispatchInputEvent = GetMethodIDOrDie(env,
Jeff Brown32cbc38552011-12-01 14:01:49 -0800421 gInputEventReceiverClassInfo.clazz,
Tarandeep Singhe1cfcf42017-07-10 18:50:00 -0700422 "dispatchInputEvent", "(ILandroid/view/InputEvent;I)V");
Andreas Gampe987f79f2014-11-18 17:29:46 -0800423 gInputEventReceiverClassInfo.dispatchBatchedInputEventPending = GetMethodIDOrDie(env,
424 gInputEventReceiverClassInfo.clazz, "dispatchBatchedInputEventPending", "()V");
425
426 return res;
Jeff Brown32cbc38552011-12-01 14:01:49 -0800427}
428
429} // namespace android