diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java index 25dda5b2e0bb6..2884d2279bfd2 100644 --- a/core/java/android/view/InputEventReceiver.java +++ b/core/java/android/view/InputEventReceiver.java @@ -170,6 +170,16 @@ public abstract class InputEventReceiver { public void onDragEvent(boolean isExiting, float x, float y) { } + /** + * Called when the display for the window associated with the input channel has entered or + * exited touch mode. + * + * @param isInTouchMode {@code true} if the display showing the window associated with the + * input channel entered touch mode. + */ + public void onTouchModeChanged(boolean isInTouchMode) { + } + /** * Called when a batched input event is pending. * diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index a699f912806d0..7b79b3844a864 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -54,6 +54,7 @@ static struct { jmethodID onPointerCaptureEvent; jmethodID onDragEvent; jmethodID onBatchedInputEventPending; + jmethodID onTouchModeChanged; } gInputEventReceiverClassInfo; // Add prefix to the beginning of each line in 'str' @@ -424,6 +425,18 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, finishInputEvent(seq, true /* handled */); continue; } + case AINPUT_EVENT_TYPE_TOUCH_MODE: { + const TouchModeEvent* touchModeEvent = static_cast(inputEvent); + if (kDebugDispatchCycle) { + ALOGD("channel '%s' ~ Received touch mode event: isInTouchMode=%s", + getInputChannelName().c_str(), toString(touchModeEvent->isInTouchMode())); + } + env->CallVoidMethod(receiverObj.get(), + gInputEventReceiverClassInfo.onTouchModeChanged, + jboolean(touchModeEvent->isInTouchMode())); + finishInputEvent(seq, true /* handled */); + continue; + } default: assert(false); // InputConsumer should prevent this from ever happening