diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/view/InputEventReceiver.java | 9 | ||||
-rw-r--r-- | core/java/android/view/ViewRootImpl.java | 8 | ||||
-rw-r--r-- | core/jni/android_view_InputEventReceiver.cpp | 30 |
3 files changed, 34 insertions, 13 deletions
diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java index f5ee7ed..25972e7 100644 --- a/core/java/android/view/InputEventReceiver.java +++ b/core/java/android/view/InputEventReceiver.java @@ -48,7 +48,7 @@ public abstract class InputEventReceiver { InputChannel inputChannel, MessageQueue messageQueue); private static native void nativeDispose(int receiverPtr); private static native void nativeFinishInputEvent(int receiverPtr, int seq, boolean handled); - private static native void nativeConsumeBatchedInputEvents(int receiverPtr, + private static native boolean nativeConsumeBatchedInputEvents(int receiverPtr, long frameTimeNanos); /** @@ -165,14 +165,17 @@ public abstract class InputEventReceiver { * * @param frameTimeNanos The time in the {@link System#nanoTime()} time base * when the current display frame started rendering, or -1 if unknown. + * + * @return Whether a batch was consumed */ - public final void consumeBatchedInputEvents(long frameTimeNanos) { + public final boolean consumeBatchedInputEvents(long frameTimeNanos) { if (mReceiverPtr == 0) { Log.w(TAG, "Attempted to consume batched input events but the input event " + "receiver has already been disposed."); } else { - nativeConsumeBatchedInputEvents(mReceiverPtr, frameTimeNanos); + return nativeConsumeBatchedInputEvents(mReceiverPtr, frameTimeNanos); } + return false; } // Called from native code. diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index ab93084..637af6f 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -5635,7 +5635,13 @@ public final class ViewRootImpl implements ViewParent, if (mConsumeBatchedInputScheduled) { mConsumeBatchedInputScheduled = false; if (mInputEventReceiver != null) { - mInputEventReceiver.consumeBatchedInputEvents(frameTimeNanos); + if (mInputEventReceiver.consumeBatchedInputEvents(frameTimeNanos)) { + // If we consumed a batch here, we want to go ahead and schedule the + // consumption of batched input events on the next frame. Otherwise, we would + // wait until we have more input events pending and might get starved by other + // things occurring in the process. + scheduleConsumeBatchedInput(); + } } doProcessInputEvents(); } diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index b254de7..92a3e62 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -56,7 +56,8 @@ public: status_t initialize(); void dispose(); status_t finishInputEvent(uint32_t seq, bool handled); - status_t consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime); + status_t consumeEvents(JNIEnv* env, bool consumeBatches, nsecs_t frameTime, + bool* outConsumedBatch); protected: virtual ~NativeInputEventReceiver(); @@ -167,7 +168,7 @@ int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) if (events & ALOOPER_EVENT_INPUT) { JNIEnv* env = AndroidRuntime::getJNIEnv(); - status_t status = consumeEvents(env, false /*consumeBatches*/, -1); + status_t status = consumeEvents(env, false /*consumeBatches*/, -1, NULL); mMessageQueue->raiseAndClearException(env, "handleReceiveCallback"); return status == OK || status == NO_MEMORY ? 1 : 0; } @@ -214,7 +215,7 @@ int NativeInputEventReceiver::handleEvent(int receiveFd, int events, void* data) } status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, - bool consumeBatches, nsecs_t frameTime) { + bool consumeBatches, nsecs_t frameTime, bool* outConsumedBatch) { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Consuming input events, consumeBatches=%s, frameTime=%lld.", getInputChannelName(), consumeBatches ? "true" : "false", frameTime); @@ -223,6 +224,9 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, if (consumeBatches) { mBatchedInputEventPending = false; } + if (outConsumedBatch) { + *outConsumedBatch = false; + } ScopedLocalRef<jobject> receiverObj(env, NULL); bool skipCallbacks = false; @@ -285,13 +289,17 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, static_cast<KeyEvent*>(inputEvent)); break; - case AINPUT_EVENT_TYPE_MOTION: + case AINPUT_EVENT_TYPE_MOTION: { #if DEBUG_DISPATCH_CYCLE ALOGD("channel '%s' ~ Received motion event.", getInputChannelName()); #endif - inputEventObj = android_view_MotionEvent_obtainAsCopy(env, - static_cast<MotionEvent*>(inputEvent)); + MotionEvent* motionEvent = static_cast<MotionEvent*>(inputEvent); + if ((motionEvent->getAction() & AMOTION_EVENT_ACTION_MOVE) && outConsumedBatch) { + *outConsumedBatch = true; + } + inputEventObj = android_view_MotionEvent_obtainAsCopy(env, motionEvent); break; + } default: assert(false); // InputConsumer should prevent this from ever happening @@ -370,16 +378,20 @@ static void nativeFinishInputEvent(JNIEnv* env, jclass clazz, jint receiverPtr, } } -static void nativeConsumeBatchedInputEvents(JNIEnv* env, jclass clazz, jint receiverPtr, +static bool nativeConsumeBatchedInputEvents(JNIEnv* env, jclass clazz, jint receiverPtr, jlong frameTimeNanos) { sp<NativeInputEventReceiver> receiver = reinterpret_cast<NativeInputEventReceiver*>(receiverPtr); - status_t status = receiver->consumeEvents(env, true /*consumeBatches*/, frameTimeNanos); + bool consumedBatch; + status_t status = receiver->consumeEvents(env, true /*consumeBatches*/, frameTimeNanos, + &consumedBatch); if (status && status != DEAD_OBJECT && !env->ExceptionCheck()) { String8 message; message.appendFormat("Failed to consume batched input event. status=%d", status); jniThrowRuntimeException(env, message.string()); + return false; } + return consumedBatch; } @@ -392,7 +404,7 @@ static JNINativeMethod gMethods[] = { (void*)nativeDispose }, { "nativeFinishInputEvent", "(IIZ)V", (void*)nativeFinishInputEvent }, - { "nativeConsumeBatchedInputEvents", "(IJ)V", + { "nativeConsumeBatchedInputEvents", "(IJ)Z", (void*)nativeConsumeBatchedInputEvents }, }; |