diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index 752b662e050dc..5378eb555f399 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -1725,7 +1725,7 @@ Landroid/view/InputDevice;->addMotionRange(IIFFFFF)V Landroid/view/InputDevice;->(IIILjava/lang/String;IILjava/lang/String;ZIILandroid/view/KeyCharacterMap;ZZZ)V Landroid/view/InputDevice;->isExternal()Z Landroid/view/InputEventReceiver;->dispatchBatchedInputEventPending()V -Landroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;I)V +Landroid/view/InputEventReceiver;->dispatchInputEvent(ILandroid/view/InputEvent;)V Landroid/view/InputEventSender;->dispatchInputEventFinished(IZ)V Landroid/view/inputmethod/InputMethodInfo;->mSubtypes:Landroid/view/inputmethod/InputMethodSubtypeArray; Landroid/view/inputmethod/InputMethodManager;->finishInputLocked()V diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java index 4ea0f55218a94..24f6989e00546 100644 --- a/core/java/android/hardware/input/InputManagerInternal.java +++ b/core/java/android/hardware/input/InputManagerInternal.java @@ -30,7 +30,14 @@ import java.util.List; * @hide Only for use within the system server. */ public abstract class InputManagerInternal { - public abstract boolean injectInputEvent(InputEvent event, int displayId, int mode); + /** + * Inject an input event. + * + * @param event The InputEvent to inject + * @param mode Synchronous or asynchronous mode + * @return True if injection has succeeded + */ + public abstract boolean injectInputEvent(InputEvent event, int mode); /** * Called by the display manager to set information about the displays as needed diff --git a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java index d2e3510ee3b1b..0982d65ee4c9b 100644 --- a/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java +++ b/core/java/android/inputmethodservice/IInputMethodSessionWrapper.java @@ -218,7 +218,7 @@ class IInputMethodSessionWrapper extends IInputMethodSession.Stub } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { if (mInputMethodSession == null) { // The session has been finished. finishInputEvent(event, false); diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 8588df7f136a0..c65710d75baa4 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -287,7 +287,7 @@ public abstract class WallpaperService extends Service { } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { boolean handled = false; try { if (event instanceof MotionEvent diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java index e2ad3ad45c649..1f2aab94958c1 100644 --- a/core/java/android/view/InputEvent.java +++ b/core/java/android/view/InputEvent.java @@ -51,7 +51,7 @@ public abstract class InputEvent implements Parcelable { * zero indicates that the event didn't come from a physical device * and maps to the default keymap. The other numbers are arbitrary and * you shouldn't depend on the values. - * + * * @return The device id. * @see InputDevice#getDevice */ @@ -59,7 +59,7 @@ public abstract class InputEvent implements Parcelable { /** * Gets the device that this event came from. - * + * * @return The device, or null if unknown. */ public final InputDevice getDevice() { @@ -68,7 +68,7 @@ public abstract class InputEvent implements Parcelable { /** * Gets the source of the event. - * + * * @return The event source or {@link InputDevice#SOURCE_UNKNOWN} if unknown. * @see InputDevice#getSources */ @@ -234,7 +234,7 @@ public abstract class InputEvent implements Parcelable { throw new IllegalStateException("Unexpected input event type token in parcel."); } } - + public InputEvent[] newArray(int size) { return new InputEvent[size]; } diff --git a/core/java/android/view/InputEventReceiver.java b/core/java/android/view/InputEventReceiver.java index c566a653da422..20ab539f52d23 100644 --- a/core/java/android/view/InputEventReceiver.java +++ b/core/java/android/view/InputEventReceiver.java @@ -111,10 +111,9 @@ public abstract class InputEventReceiver { * to indicate whether the event was handled. No new input events will be received * until {@link #finishInputEvent} is called. * - * @param displayId The display id on which input event triggered. * @param event The input event that was received. */ - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { finishInputEvent(event, false); } @@ -181,9 +180,9 @@ public abstract class InputEventReceiver { // Called from native code. @SuppressWarnings("unused") - private void dispatchInputEvent(int seq, InputEvent event, int displayId) { + private void dispatchInputEvent(int seq, InputEvent event) { mSeqMap.put(event.getSequenceNumber(), seq); - onInputEvent(event, displayId); + onInputEvent(event); } // Called from native code. diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index a59740563ceb1..dec0eccc904ff 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -1556,8 +1556,8 @@ public class KeyEvent extends InputEvent implements Parcelable { * @hide */ public static KeyEvent obtain(long downTime, long eventTime, int action, - int code, int repeat, int metaState, - int deviceId, int scancode, int flags, int source, String characters) { + int code, int repeat, int metaState, + int deviceId, int scancode, int flags, int source, String characters) { KeyEvent ev = obtain(); ev.mDownTime = downTime; ev.mEventTime = eventTime; diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 1d7c1dedc62e2..9148c27f60066 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -16,11 +16,14 @@ package android.view; +import static android.view.Display.DEFAULT_DISPLAY; + import android.annotation.TestApi; import android.graphics.Matrix; import android.os.Parcel; import android.os.Parcelable; import android.os.SystemClock; +import android.util.Log; import android.util.SparseArray; import dalvik.annotation.optimization.CriticalNative; @@ -172,6 +175,7 @@ import java.util.Objects; *

*/ public final class MotionEvent extends InputEvent implements Parcelable { + private static final String TAG = "MotionEvent"; private static final long NS_PER_MS = 1000000; private static final String LABEL_PREFIX = "AXIS_"; @@ -1470,7 +1474,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { private MotionEvent mNext; private static native long nativeInitialize(long nativePtr, - int deviceId, int source, int action, int flags, int edgeFlags, + int deviceId, int source, int displayId, int action, int flags, int edgeFlags, int metaState, int buttonState, float xOffset, float yOffset, float xPrecision, float yPrecision, long downTimeNanos, long eventTimeNanos, @@ -1514,7 +1518,11 @@ public final class MotionEvent extends InputEvent implements Parcelable { @CriticalNative private static native int nativeGetSource(long nativePtr); @CriticalNative - private static native int nativeSetSource(long nativePtr, int source); + private static native void nativeSetSource(long nativePtr, int source); + @CriticalNative + private static native int nativeGetDisplayId(long nativePtr); + @CriticalNative + private static native void nativeSetDisplayId(long nativePtr, int displayId); @CriticalNative private static native int nativeGetAction(long nativePtr); @CriticalNative @@ -1623,22 +1631,67 @@ public final class MotionEvent extends InputEvent implements Parcelable { * @param edgeFlags A bitfield indicating which edges, if any, were touched by this * MotionEvent. * @param source The source of this event. + * @param displayId The display ID associated with this event. * @param flags The motion event flags. + * @hide */ static public MotionEvent obtain(long downTime, long eventTime, int action, int pointerCount, PointerProperties[] pointerProperties, PointerCoords[] pointerCoords, int metaState, int buttonState, float xPrecision, float yPrecision, int deviceId, - int edgeFlags, int source, int flags) { + int edgeFlags, int source, int displayId, int flags) { MotionEvent ev = obtain(); ev.mNativePtr = nativeInitialize(ev.mNativePtr, - deviceId, source, action, flags, edgeFlags, metaState, buttonState, + deviceId, source, displayId, action, flags, edgeFlags, metaState, buttonState, 0, 0, xPrecision, yPrecision, downTime * NS_PER_MS, eventTime * NS_PER_MS, pointerCount, pointerProperties, pointerCoords); + if (ev.mNativePtr == 0) { + Log.e(TAG, "Could not initialize MotionEvent"); + ev.recycle(); + return null; + } return ev; } + /** + * Create a new MotionEvent, filling in all of the basic values that + * define the motion. + * + * @param downTime The time (in ms) when the user originally pressed down to start + * a stream of position events. This must be obtained from {@link SystemClock#uptimeMillis()}. + * @param eventTime The the time (in ms) when this specific event was generated. This + * must be obtained from {@link SystemClock#uptimeMillis()}. + * @param action The kind of action being performed, such as {@link #ACTION_DOWN}. + * @param pointerCount The number of pointers that will be in this event. + * @param pointerProperties An array of pointerCount values providing + * a {@link PointerProperties} property object for each pointer, which must + * include the pointer identifier. + * @param pointerCoords An array of pointerCount values providing + * a {@link PointerCoords} coordinate object for each pointer. + * @param metaState The state of any meta / modifier keys that were in effect when + * the event was generated. + * @param buttonState The state of buttons that are pressed. + * @param xPrecision The precision of the X coordinate being reported. + * @param yPrecision The precision of the Y coordinate being reported. + * @param deviceId The id for the device that this event came from. An id of + * zero indicates that the event didn't come from a physical device; other + * numbers are arbitrary and you shouldn't depend on the values. + * @param edgeFlags A bitfield indicating which edges, if any, were touched by this + * MotionEvent. + * @param source The source of this event. + * @param flags The motion event flags. + */ + public static MotionEvent obtain(long downTime, long eventTime, + int action, int pointerCount, PointerProperties[] pointerProperties, + PointerCoords[] pointerCoords, int metaState, int buttonState, + float xPrecision, float yPrecision, int deviceId, + int edgeFlags, int source, int flags) { + return obtain(downTime, eventTime, action, pointerCount, pointerProperties, pointerCoords, + metaState, buttonState, xPrecision, yPrecision, deviceId, edgeFlags, source, + DEFAULT_DISPLAY, flags); + } + /** * Create a new MotionEvent, filling in all of the basic values that * define the motion. @@ -1733,7 +1786,8 @@ public final class MotionEvent extends InputEvent implements Parcelable { pc[0].size = size; ev.mNativePtr = nativeInitialize(ev.mNativePtr, - deviceId, InputDevice.SOURCE_UNKNOWN, action, 0, edgeFlags, metaState, 0, + deviceId, InputDevice.SOURCE_UNKNOWN, DEFAULT_DISPLAY, + action, 0, edgeFlags, metaState, 0, 0, 0, xPrecision, yPrecision, downTime * NS_PER_MS, eventTime * NS_PER_MS, 1, pp, pc); @@ -1888,6 +1942,16 @@ public final class MotionEvent extends InputEvent implements Parcelable { nativeSetSource(mNativePtr, source); } + /** @hide */ + public int getDisplayId() { + return nativeGetDisplayId(mNativePtr); + } + + /** @hide */ + public void setDisplayId(int displayId) { + nativeSetDisplayId(mNativePtr, displayId); + } + /** * Return the kind of action being performed. * Consider using {@link #getActionMasked} and {@link #getActionIndex} to retrieve @@ -3023,7 +3087,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { /** * Adds all of the movement samples of the specified event to this one if * it is compatible. To be compatible, the event must have the same device id, - * source, action, flags, pointer count, pointer properties. + * source, display id, action, flags, pointer count, pointer properties. * * Only applies to {@link #ACTION_MOVE} or {@link #ACTION_HOVER_MOVE} events. * @@ -3043,6 +3107,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { if (nativeGetDeviceId(mNativePtr) != nativeGetDeviceId(event.mNativePtr) || nativeGetSource(mNativePtr) != nativeGetSource(event.mNativePtr) + || nativeGetDisplayId(mNativePtr) != nativeGetDisplayId(event.mNativePtr) || nativeGetFlags(mNativePtr) != nativeGetFlags(event.mNativePtr)) { return false; } @@ -3128,6 +3193,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { } ev.mNativePtr = nativeInitialize(ev.mNativePtr, nativeGetDeviceId(mNativePtr), nativeGetSource(mNativePtr), + nativeGetDisplayId(mNativePtr), nativeGetAction(mNativePtr), nativeGetFlags(mNativePtr), nativeGetEdgeFlags(mNativePtr), nativeGetMetaState(mNativePtr), nativeGetButtonState(mNativePtr), @@ -3172,7 +3238,6 @@ public final class MotionEvent extends InputEvent implements Parcelable { >> ACTION_POINTER_INDEX_SHIFT; int newActionPointerIndex = -1; int newPointerCount = 0; - int newIdBits = 0; for (int i = 0; i < oldPointerCount; i++) { nativeGetPointerProperties(mNativePtr, i, pp[newPointerCount]); final int idBit = 1 << pp[newPointerCount].id; @@ -3182,7 +3247,6 @@ public final class MotionEvent extends InputEvent implements Parcelable { } map[newPointerCount] = i; newPointerCount += 1; - newIdBits |= idBit; } } @@ -3221,6 +3285,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { if (h == 0) { ev.mNativePtr = nativeInitialize(ev.mNativePtr, nativeGetDeviceId(mNativePtr), nativeGetSource(mNativePtr), + nativeGetDisplayId(mNativePtr), newAction, nativeGetFlags(mNativePtr), nativeGetEdgeFlags(mNativePtr), nativeGetMetaState(mNativePtr), nativeGetButtonState(mNativePtr), @@ -3266,6 +3331,7 @@ public final class MotionEvent extends InputEvent implements Parcelable { msg.append(", downTime=").append(getDownTime()); msg.append(", deviceId=").append(getDeviceId()); msg.append(", source=0x").append(Integer.toHexString(getSource())); + msg.append(", displayId=").append(getDisplayId()); } msg.append(" }"); return msg.toString(); diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 01d9265cc92c8..9564e7c85e135 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -7098,7 +7098,7 @@ public final class ViewRootImpl implements ViewParent, } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { enqueueInputEvent(event, this, 0, true); } diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java index a6f36bbf4ef4c..f364d82835fe9 100644 --- a/core/java/android/view/WindowManagerPolicyConstants.java +++ b/core/java/android/view/WindowManagerPolicyConstants.java @@ -16,8 +16,6 @@ package android.view; -import static android.view.Display.DEFAULT_DISPLAY; - /** * Constants for interfacing with WindowManagerService and WindowManagerPolicyInternal. * @hide @@ -75,15 +73,6 @@ public interface WindowManagerPolicyConstants { * copy() must be made and the copy must be recycled. **/ void onPointerEvent(MotionEvent motionEvent); - - /** - * @see #onPointerEvent(MotionEvent) - **/ - default void onPointerEvent(MotionEvent motionEvent, int displayId) { - if (displayId == DEFAULT_DISPLAY) { - onPointerEvent(motionEvent); - } - } } /** Screen turned off because of a device admin */ diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp index 8fee7baa398f9..fb6dd9392e825 100644 --- a/core/jni/android_view_InputEventReceiver.cpp +++ b/core/jni/android_view_InputEventReceiver.cpp @@ -236,9 +236,8 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, for (;;) { uint32_t seq; InputEvent* inputEvent; - int32_t displayId; status_t status = mInputConsumer.consume(&mInputEventFactory, - consumeBatches, frameTime, &seq, &inputEvent, &displayId); + consumeBatches, frameTime, &seq, &inputEvent); if (status) { if (status == WOULD_BLOCK) { if (!skipCallbacks && !mBatchedInputEventPending @@ -315,8 +314,7 @@ status_t NativeInputEventReceiver::consumeEvents(JNIEnv* env, ALOGD("channel '%s' ~ Dispatching input event.", getInputChannelName().c_str()); } env->CallVoidMethod(receiverObj.get(), - gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj, - displayId); + gInputEventReceiverClassInfo.dispatchInputEvent, seq, inputEventObj); if (env->ExceptionCheck()) { ALOGE("Exception dispatching input event."); skipCallbacks = true; @@ -423,7 +421,7 @@ int register_android_view_InputEventReceiver(JNIEnv* env) { gInputEventReceiverClassInfo.dispatchInputEvent = GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, - "dispatchInputEvent", "(ILandroid/view/InputEvent;I)V"); + "dispatchInputEvent", "(ILandroid/view/InputEvent;)V"); gInputEventReceiverClassInfo.dispatchBatchedInputEventPending = GetMethodIDOrDie(env, gInputEventReceiverClassInfo.clazz, "dispatchBatchedInputEventPending", "()V"); diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp index effeed6b2af68..095252c283321 100644 --- a/core/jni/android_view_InputEventSender.cpp +++ b/core/jni/android_view_InputEventSender.cpp @@ -39,8 +39,6 @@ namespace android { // Log debug messages about the dispatch cycle. static const bool kDebugDispatchCycle = false; -// Display id for default(primary) display. -static const int32_t kDefaultDisplayId = 0; static struct { jclass clazz; @@ -138,7 +136,7 @@ status_t NativeInputEventSender::sendMotionEvent(uint32_t seq, const MotionEvent publishedSeq = mNextPublishedSeq++; status_t status = mInputPublisher.publishMotionEvent(publishedSeq, event->getDeviceId(), event->getSource(), - kDefaultDisplayId /* TODO(multi-display): propagate display id */, + event->getDisplayId(), event->getAction(), event->getActionButton(), event->getFlags(), event->getEdgeFlags(), event->getMetaState(), event->getButtonState(), event->getXOffset(), event->getYOffset(), diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp index 64bf0dc0ed91e..ecf811970a99c 100644 --- a/core/jni/android_view_MotionEvent.cpp +++ b/core/jni/android_view_MotionEvent.cpp @@ -333,7 +333,7 @@ static void pointerPropertiesFromNative(JNIEnv* env, const PointerProperties* po static jlong android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz, jlong nativePtr, - jint deviceId, jint source, jint action, jint flags, jint edgeFlags, + jint deviceId, jint source, jint displayId, jint action, jint flags, jint edgeFlags, jint metaState, jint buttonState, jfloat xOffset, jfloat yOffset, jfloat xPrecision, jfloat yPrecision, jlong downTimeNanos, jlong eventTimeNanos, @@ -372,8 +372,8 @@ static jlong android_view_MotionEvent_nativeInitialize(JNIEnv* env, jclass clazz env->DeleteLocalRef(pointerCoordsObj); } - event->initialize(deviceId, source, action, 0, flags, edgeFlags, metaState, buttonState, - xOffset, yOffset, xPrecision, yPrecision, + event->initialize(deviceId, source, displayId, action, 0, flags, edgeFlags, metaState, + buttonState, xOffset, yOffset, xPrecision, yPrecision, downTimeNanos, eventTimeNanos, pointerCount, pointerProperties, rawPointerCoords); return reinterpret_cast(event); @@ -598,6 +598,16 @@ static void android_view_MotionEvent_nativeSetSource(jlong nativePtr, jint sourc event->setSource(source); } +static jint android_view_MotionEvent_nativeGetDisplayId(jlong nativePtr) { + MotionEvent* event = reinterpret_cast(nativePtr); + return event->getDisplayId(); +} + +static void android_view_MotionEvent_nativeSetDisplayId(jlong nativePtr, jint displayId) { + MotionEvent* event = reinterpret_cast(nativePtr); + return event->setDisplayId(displayId); +} + static jint android_view_MotionEvent_nativeGetAction(jlong nativePtr) { MotionEvent* event = reinterpret_cast(nativePtr); return event->getAction(); @@ -737,7 +747,7 @@ static void android_view_MotionEvent_nativeTransform(jlong nativePtr, jlong matr static const JNINativeMethod gMotionEventMethods[] = { /* name, signature, funcPtr */ { "nativeInitialize", - "(JIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;" + "(JIIIIIIIIFFFFJJI[Landroid/view/MotionEvent$PointerProperties;" "[Landroid/view/MotionEvent$PointerCoords;)J", (void*)android_view_MotionEvent_nativeInitialize }, { "nativeDispose", @@ -792,8 +802,14 @@ static const JNINativeMethod gMotionEventMethods[] = { "(J)I", (void*)android_view_MotionEvent_nativeGetSource }, { "nativeSetSource", - "(JI)I", + "(JI)V", (void*)android_view_MotionEvent_nativeSetSource }, + { "nativeGetDisplayId", + "(J)I", + (void*)android_view_MotionEvent_nativeGetDisplayId }, + { "nativeSetDisplayId", + "(JI)V", + (void*)android_view_MotionEvent_nativeSetDisplayId }, { "nativeGetAction", "(J)I", (void*)android_view_MotionEvent_nativeGetAction }, diff --git a/core/tests/coretests/src/android/view/KeyEventTest.java b/core/tests/coretests/src/android/view/KeyEventTest.java new file mode 100644 index 0000000000000..aabf816068640 --- /dev/null +++ b/core/tests/coretests/src/android/view/KeyEventTest.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static org.junit.Assert.assertEquals; + +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@SmallTest +@RunWith(AndroidJUnit4.class) +public class KeyEventTest { + + @Test + public void testObtain() { + KeyEvent keyEvent = KeyEvent.obtain(0, 0, KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_0, + 0, 0, 0, 0, 0, InputDevice.SOURCE_KEYBOARD, null); + assertEquals(KeyEvent.ACTION_DOWN, keyEvent.getAction()); + assertEquals(KeyEvent.KEYCODE_0, keyEvent.getKeyCode()); + assertEquals(InputDevice.SOURCE_KEYBOARD, keyEvent.getSource()); + } +} diff --git a/core/tests/coretests/src/android/view/MotionEventTest.java b/core/tests/coretests/src/android/view/MotionEventTest.java new file mode 100644 index 0000000000000..1a480c77ada00 --- /dev/null +++ b/core/tests/coretests/src/android/view/MotionEventTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.view; + +import static android.view.MotionEvent.ACTION_DOWN; +import static android.view.MotionEvent.TOOL_TYPE_FINGER; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import android.support.test.filters.SmallTest; +import android.support.test.runner.AndroidJUnit4; +import android.view.MotionEvent.PointerCoords; +import android.view.MotionEvent.PointerProperties; + +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(AndroidJUnit4.class) +@SmallTest +public class MotionEventTest { + + @Test + public void testObtainWithDisplayId() { + final int pointerCount = 1; + PointerProperties[] properties = new PointerProperties[pointerCount]; + final PointerCoords[] coords = new PointerCoords[pointerCount]; + for (int i = 0; i < pointerCount; i++) { + final PointerCoords c = new PointerCoords(); + c.x = i * 10; + c.y = i * 20; + coords[i] = c; + final PointerProperties p = new PointerProperties(); + p.id = i; + p.toolType = TOOL_TYPE_FINGER; + properties[i] = p; + } + + int displayId = 2; + MotionEvent motionEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, + pointerCount, properties, coords, + 0, 0, 0, 0, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, displayId, 0); + assertEquals(displayId, motionEvent.getDisplayId()); + + displayId = 5; + motionEvent.setDisplayId(displayId); + assertEquals(displayId, motionEvent.getDisplayId()); + motionEvent.recycle(); + + // If invalid PointerProperties object is passed to obtain, + // there should not be a native crash, and instead it should just return null + properties[0] = null; + motionEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, + pointerCount, properties, coords, + 0, 0, 0, 0, 0, 0, InputDevice.SOURCE_TOUCHSCREEN, displayId, 0); + assertNull(motionEvent); + } +} diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java index df87e0f28cd9a..07cfbda7ac2b6 100644 --- a/media/java/android/media/tv/ITvInputSessionWrapper.java +++ b/media/java/android/media/tv/ITvInputSessionWrapper.java @@ -367,7 +367,7 @@ public class ITvInputSessionWrapper extends ITvInputSession.Stub implements Hand } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { if (mTvInputSessionImpl == null) { // The session has been finished. finishInputEvent(event, false); diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java index 38b8ae8418af1..0d25c91e62d9a 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/InputConsumerController.java @@ -67,7 +67,7 @@ public class InputConsumerController { } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { boolean handled = true; try { if (mListener != null && event instanceof MotionEvent) { diff --git a/services/core/java/com/android/server/input/InputForwarder.java b/services/core/java/com/android/server/input/InputForwarder.java index bebbc93e9ea59..38a1cd745722e 100644 --- a/services/core/java/com/android/server/input/InputForwarder.java +++ b/services/core/java/com/android/server/input/InputForwarder.java @@ -19,7 +19,7 @@ package com.android.server.input; import android.app.IInputForwarder; import android.hardware.input.InputManagerInternal; import android.view.InputEvent; -import android.os.Binder; +import android.view.MotionEvent; import com.android.server.LocalServices; @@ -40,7 +40,9 @@ class InputForwarder extends IInputForwarder.Stub { @Override public boolean forwardEvent(InputEvent event) { - return mInputManagerInternal.injectInputEvent(event, mDisplayId, - INJECT_INPUT_EVENT_MODE_ASYNC); + if (event instanceof MotionEvent) { + ((MotionEvent) event).setDisplayId(mDisplayId); + } + return mInputManagerInternal.injectInputEvent(event, INJECT_INPUT_EVENT_MODE_ASYNC); } } \ No newline at end of file diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index a951d470735a1..1192908f82f89 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -213,7 +213,7 @@ public class InputManagerService extends IInputManager.Stub InputWindowHandle inputWindowHandle, boolean monitor); private static native void nativeUnregisterInputChannel(long ptr, InputChannel inputChannel); private static native void nativeSetInputFilterEnabled(long ptr, boolean enable); - private static native int nativeInjectInputEvent(long ptr, InputEvent event, int displayId, + private static native int nativeInjectInputEvent(long ptr, InputEvent event, int injectorPid, int injectorUid, int syncMode, int timeoutMillis, int policyFlags); private static native void nativeToggleCapsLock(long ptr, int deviceId); @@ -597,10 +597,10 @@ public class InputManagerService extends IInputManager.Stub @Override // Binder call public boolean injectInputEvent(InputEvent event, int mode) { - return injectInputEventInternal(event, Display.DEFAULT_DISPLAY, mode); + return injectInputEventInternal(event, mode); } - private boolean injectInputEventInternal(InputEvent event, int displayId, int mode) { + private boolean injectInputEventInternal(InputEvent event, int mode) { if (event == null) { throw new IllegalArgumentException("event must not be null"); } @@ -615,7 +615,7 @@ public class InputManagerService extends IInputManager.Stub final long ident = Binder.clearCallingIdentity(); final int result; try { - result = nativeInjectInputEvent(mPtr, event, displayId, pid, uid, mode, + result = nativeInjectInputEvent(mPtr, event, pid, uid, mode, INJECTION_TIMEOUT_MILLIS, WindowManagerPolicy.FLAG_DISABLE_KEY_REPEAT); } finally { Binder.restoreCallingIdentity(ident); @@ -2222,7 +2222,7 @@ public class InputManagerService extends IInputManager.Stub synchronized (mInputFilterLock) { if (!mDisconnected) { - nativeInjectInputEvent(mPtr, event, Display.DEFAULT_DISPLAY, 0, 0, + nativeInjectInputEvent(mPtr, event, 0, 0, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC, 0, policyFlags | WindowManagerPolicy.FLAG_FILTERED); } @@ -2370,8 +2370,8 @@ public class InputManagerService extends IInputManager.Stub } @Override - public boolean injectInputEvent(InputEvent event, int displayId, int mode) { - return injectInputEventInternal(event, displayId, mode); + public boolean injectInputEvent(InputEvent event, int mode) { + return injectInputEventInternal(event, mode); } @Override diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 7efc9876993b8..7aef39f69ae16 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -4305,7 +4305,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { boolean handled = false; try { if (event instanceof MotionEvent diff --git a/services/core/java/com/android/server/wm/DragInputEventReceiver.java b/services/core/java/com/android/server/wm/DragInputEventReceiver.java index bee2bacf83d2e..5372d8b6e7960 100644 --- a/services/core/java/com/android/server/wm/DragInputEventReceiver.java +++ b/services/core/java/com/android/server/wm/DragInputEventReceiver.java @@ -54,7 +54,7 @@ class DragInputEventReceiver extends InputEventReceiver { } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { boolean handled = false; try { if (!(event instanceof MotionEvent) diff --git a/services/core/java/com/android/server/wm/PointerEventDispatcher.java b/services/core/java/com/android/server/wm/PointerEventDispatcher.java index ab8b8d472d9d5..f815fa058d556 100644 --- a/services/core/java/com/android/server/wm/PointerEventDispatcher.java +++ b/services/core/java/com/android/server/wm/PointerEventDispatcher.java @@ -36,7 +36,7 @@ public class PointerEventDispatcher extends InputEventReceiver { } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { try { if (event instanceof MotionEvent && (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { @@ -50,7 +50,7 @@ public class PointerEventDispatcher extends InputEventReceiver { listeners = mListenersArray; } for (int i = 0; i < listeners.length; ++i) { - listeners[i].onPointerEvent(motionEvent, displayId); + listeners[i].onPointerEvent(motionEvent); } } } finally { diff --git a/services/core/java/com/android/server/wm/TaskPositioner.java b/services/core/java/com/android/server/wm/TaskPositioner.java index 26c87b738f8c0..f73c2dbfc8412 100644 --- a/services/core/java/com/android/server/wm/TaskPositioner.java +++ b/services/core/java/com/android/server/wm/TaskPositioner.java @@ -126,7 +126,7 @@ class TaskPositioner { } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { if (!(event instanceof MotionEvent) || (event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) { return; diff --git a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java index 5abda27756644..f1e1592da83ed 100644 --- a/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java +++ b/services/core/java/com/android/server/wm/TaskTapPointerEventListener.java @@ -45,15 +45,11 @@ public class TaskTapPointerEventListener implements PointerEventListener { mDisplayContent = displayContent; } - @Override - public void onPointerEvent(MotionEvent motionEvent, int displayId) { - if (displayId == getDisplayId()) { - onPointerEvent(motionEvent); - } - } - @Override public void onPointerEvent(MotionEvent motionEvent) { + if (motionEvent.getDisplayId() != getDisplayId()) { + return; + } final int action = motionEvent.getAction(); switch (action & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: { diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index b706096f3d0b6..31a778706ef81 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -2094,7 +2094,7 @@ class WindowState extends WindowContainer implements WindowManagerP super(inputChannel, mService.mH.getLooper()); } @Override - public void onInputEvent(InputEvent event, int displayId) { + public void onInputEvent(InputEvent event) { finishInputEvent(event, true); } } diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index 27c2faca9d336..52f2d674f993f 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -1407,7 +1407,7 @@ static void nativeSetInputFilterEnabled(JNIEnv* /* env */, jclass /* clazz */, } static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */, - jlong ptr, jobject inputEventObj, jint displayId, jint injectorPid, jint injectorUid, + jlong ptr, jobject inputEventObj, jint injectorPid, jint injectorUid, jint syncMode, jint timeoutMillis, jint policyFlags) { NativeInputManager* im = reinterpret_cast(ptr); @@ -1420,7 +1420,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */, } return (jint) im->getInputManager()->getDispatcher()->injectInputEvent( - & keyEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis, + & keyEvent, injectorPid, injectorUid, syncMode, timeoutMillis, uint32_t(policyFlags)); } else if (env->IsInstanceOf(inputEventObj, gMotionEventClassInfo.clazz)) { const MotionEvent* motionEvent = android_view_MotionEvent_getNativePtr(env, inputEventObj); @@ -1430,7 +1430,7 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */, } return (jint) im->getInputManager()->getDispatcher()->injectInputEvent( - motionEvent, displayId, injectorPid, injectorUid, syncMode, timeoutMillis, + motionEvent, injectorPid, injectorUid, syncMode, timeoutMillis, uint32_t(policyFlags)); } else { jniThrowRuntimeException(env, "Invalid input event type."); @@ -1674,7 +1674,7 @@ static const JNINativeMethod gInputManagerMethods[] = { (void*) nativeUnregisterInputChannel }, { "nativeSetInputFilterEnabled", "(JZ)V", (void*) nativeSetInputFilterEnabled }, - { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIIII)I", + { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I", (void*) nativeInjectInputEvent }, { "nativeToggleCapsLock", "(JI)V", (void*) nativeToggleCapsLock },