diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java index 1f2aab94958c1..c25736495b0ea 100644 --- a/core/java/android/view/InputEvent.java +++ b/core/java/android/view/InputEvent.java @@ -94,6 +94,19 @@ public abstract class InputEvent implements Parcelable { return (getSource() & source) == source; } + /** + * Gets the display id of the event. + * @return The display id associated with the event. + * @hide + */ + public abstract int getDisplayId(); + + /** + * Modifies the display id associated with the event + * @param displayId + * @hide + */ + public abstract void setDisplayId(int displayId); /** * Copies the event. * diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index 35546f8bf186c..2c00391e74505 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -16,6 +16,8 @@ package android.view; +import static android.view.Display.INVALID_DISPLAY; + import android.annotation.NonNull; import android.annotation.TestApi; import android.os.Parcel; @@ -1246,6 +1248,7 @@ public class KeyEvent extends InputEvent implements Parcelable { private int mDeviceId; private int mSource; + private int mDisplayId; private int mMetaState; private int mAction; private int mKeyCode; @@ -1473,6 +1476,7 @@ public class KeyEvent extends InputEvent implements Parcelable { mScanCode = scancode; mFlags = flags; mSource = source; + mDisplayId = INVALID_DISPLAY; } /** @@ -1497,6 +1501,7 @@ public class KeyEvent extends InputEvent implements Parcelable { mDeviceId = deviceId; mFlags = flags; mSource = InputDevice.SOURCE_KEYBOARD; + mDisplayId = INVALID_DISPLAY; } /** @@ -1511,6 +1516,7 @@ public class KeyEvent extends InputEvent implements Parcelable { mMetaState = origEvent.mMetaState; mDeviceId = origEvent.mDeviceId; mSource = origEvent.mSource; + mDisplayId = origEvent.mDisplayId; mScanCode = origEvent.mScanCode; mFlags = origEvent.mFlags; mCharacters = origEvent.mCharacters; @@ -1537,6 +1543,7 @@ public class KeyEvent extends InputEvent implements Parcelable { mMetaState = origEvent.mMetaState; mDeviceId = origEvent.mDeviceId; mSource = origEvent.mSource; + mDisplayId = origEvent.mDisplayId; mScanCode = origEvent.mScanCode; mFlags = origEvent.mFlags; mCharacters = origEvent.mCharacters; @@ -1564,7 +1571,7 @@ public class KeyEvent extends InputEvent implements Parcelable { */ 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 deviceId, int scancode, int flags, int source, int displayId, String characters) { KeyEvent ev = obtain(); ev.mDownTime = downTime; ev.mEventTime = eventTime; @@ -1576,10 +1583,25 @@ public class KeyEvent extends InputEvent implements Parcelable { ev.mScanCode = scancode; ev.mFlags = flags; ev.mSource = source; + ev.mDisplayId = displayId; ev.mCharacters = characters; return ev; } + /** + * Obtains a (potentially recycled) key event. + * + * @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) { + return obtain(downTime, eventTime, action, code, repeat, metaState, deviceId, scancode, + flags, source, INVALID_DISPLAY, characters); + } + + /** + /** * Obtains a (potentially recycled) copy of another key event. * @@ -1597,6 +1619,7 @@ public class KeyEvent extends InputEvent implements Parcelable { ev.mScanCode = other.mScanCode; ev.mFlags = other.mFlags; ev.mSource = other.mSource; + ev.mDisplayId = other.mDisplayId; ev.mCharacters = other.mCharacters; return ev; } @@ -1683,6 +1706,7 @@ public class KeyEvent extends InputEvent implements Parcelable { mMetaState = origEvent.mMetaState; mDeviceId = origEvent.mDeviceId; mSource = origEvent.mSource; + mDisplayId = origEvent.mDisplayId; mScanCode = origEvent.mScanCode; mFlags = origEvent.mFlags; // Don't copy mCharacters, since one way or the other we'll lose it @@ -1917,6 +1941,18 @@ public class KeyEvent extends InputEvent implements Parcelable { mSource = source; } + /** @hide */ + @Override + public final int getDisplayId() { + return mDisplayId; + } + + /** @hide */ + @Override + public final void setDisplayId(int displayId) { + mDisplayId = displayId; + } + /** *
Returns the state of the meta keys.
* @@ -2852,6 +2888,7 @@ public class KeyEvent extends InputEvent implements Parcelable { msg.append(", downTime=").append(mDownTime); msg.append(", deviceId=").append(mDeviceId); msg.append(", source=0x").append(Integer.toHexString(mSource)); + msg.append(", displayId=").append(mDisplayId); msg.append(" }"); return msg.toString(); } @@ -2983,6 +3020,7 @@ public class KeyEvent extends InputEvent implements Parcelable { private KeyEvent(Parcel in) { mDeviceId = in.readInt(); mSource = in.readInt(); + mDisplayId = in.readInt(); mAction = in.readInt(); mKeyCode = in.readInt(); mRepeatCount = in.readInt(); @@ -2999,6 +3037,7 @@ public class KeyEvent extends InputEvent implements Parcelable { out.writeInt(mDeviceId); out.writeInt(mSource); + out.writeInt(mDisplayId); out.writeInt(mAction); out.writeInt(mKeyCode); out.writeInt(mRepeatCount); diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java index 9148c27f60066..344806aa4d508 100644 --- a/core/java/android/view/MotionEvent.java +++ b/core/java/android/view/MotionEvent.java @@ -1943,11 +1943,13 @@ public final class MotionEvent extends InputEvent implements Parcelable { } /** @hide */ + @Override public int getDisplayId() { return nativeGetDisplayId(mNativePtr); } /** @hide */ + @Override public void setDisplayId(int displayId) { nativeSetDisplayId(mNativePtr, displayId); } diff --git a/core/jni/android_view_InputEventSender.cpp b/core/jni/android_view_InputEventSender.cpp index 095252c283321..10da89227f514 100644 --- a/core/jni/android_view_InputEventSender.cpp +++ b/core/jni/android_view_InputEventSender.cpp @@ -114,8 +114,8 @@ status_t NativeInputEventSender::sendKeyEvent(uint32_t seq, const KeyEvent* even uint32_t publishedSeq = mNextPublishedSeq++; status_t status = mInputPublisher.publishKeyEvent(publishedSeq, - event->getDeviceId(), event->getSource(), event->getAction(), event->getFlags(), - event->getKeyCode(), event->getScanCode(), event->getMetaState(), + event->getDeviceId(), event->getSource(), event->getDisplayId(), event->getAction(), + event->getFlags(), event->getKeyCode(), event->getScanCode(), event->getMetaState(), event->getRepeatCount(), event->getDownTime(), event->getEventTime()); if (status) { ALOGW("Failed to send key event on channel '%s'. status=%d", @@ -135,8 +135,7 @@ status_t NativeInputEventSender::sendMotionEvent(uint32_t seq, const MotionEvent for (size_t i = 0; i <= event->getHistorySize(); i++) { publishedSeq = mNextPublishedSeq++; status_t status = mInputPublisher.publishMotionEvent(publishedSeq, - event->getDeviceId(), event->getSource(), - event->getDisplayId(), + event->getDeviceId(), event->getSource(), 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_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp index 8a6e745b60a85..f0107723a43e6 100644 --- a/core/jni/android_view_KeyEvent.cpp +++ b/core/jni/android_view_KeyEvent.cpp @@ -39,6 +39,7 @@ static struct { jfieldID mDeviceId; jfieldID mSource; + jfieldID mDisplayId; jfieldID mMetaState; jfieldID mAction; jfieldID mKeyCode; @@ -65,6 +66,7 @@ jobject android_view_KeyEvent_fromNative(JNIEnv* env, const KeyEvent* event) { event->getScanCode(), event->getFlags(), event->getSource(), + event->getDisplayId(), NULL); if (env->ExceptionCheck()) { ALOGE("An exception occurred while obtaining a key event."); @@ -79,6 +81,7 @@ status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, KeyEvent* event) { jint deviceId = env->GetIntField(eventObj, gKeyEventClassInfo.mDeviceId); jint source = env->GetIntField(eventObj, gKeyEventClassInfo.mSource); + jint displayId = env->GetIntField(eventObj, gKeyEventClassInfo.mDisplayId); jint metaState = env->GetIntField(eventObj, gKeyEventClassInfo.mMetaState); jint action = env->GetIntField(eventObj, gKeyEventClassInfo.mAction); jint keyCode = env->GetIntField(eventObj, gKeyEventClassInfo.mKeyCode); @@ -88,7 +91,8 @@ status_t android_view_KeyEvent_toNative(JNIEnv* env, jobject eventObj, jlong downTime = env->GetLongField(eventObj, gKeyEventClassInfo.mDownTime); jlong eventTime = env->GetLongField(eventObj, gKeyEventClassInfo.mEventTime); - event->initialize(deviceId, source, action, flags, keyCode, scanCode, metaState, repeatCount, + event->initialize(deviceId, source, displayId, action, flags, keyCode, scanCode, metaState, + repeatCount, milliseconds_to_nanoseconds(downTime), milliseconds_to_nanoseconds(eventTime)); return OK; @@ -131,12 +135,14 @@ int register_android_view_KeyEvent(JNIEnv* env) { gKeyEventClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gKeyEventClassInfo.obtain = GetStaticMethodIDOrDie(env, gKeyEventClassInfo.clazz, - "obtain", "(JJIIIIIIIILjava/lang/String;)Landroid/view/KeyEvent;"); + "obtain", "(JJIIIIIIIIILjava/lang/String;)Landroid/view/KeyEvent;"); gKeyEventClassInfo.recycle = GetMethodIDOrDie(env, gKeyEventClassInfo.clazz, "recycle", "()V"); gKeyEventClassInfo.mDeviceId = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mDeviceId", "I"); gKeyEventClassInfo.mSource = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mSource", "I"); + gKeyEventClassInfo.mDisplayId = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mDisplayId", + "I"); gKeyEventClassInfo.mMetaState = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mMetaState", "I"); gKeyEventClassInfo.mAction = GetFieldIDOrDie(env, gKeyEventClassInfo.clazz, "mAction", "I"); diff --git a/core/tests/coretests/src/android/view/KeyEventTest.java b/core/tests/coretests/src/android/view/KeyEventTest.java index aabf816068640..b9d95e542f119 100644 --- a/core/tests/coretests/src/android/view/KeyEventTest.java +++ b/core/tests/coretests/src/android/view/KeyEventTest.java @@ -16,6 +16,8 @@ package android.view; +import static android.view.Display.INVALID_DISPLAY; + import static org.junit.Assert.assertEquals; import android.support.test.filters.SmallTest; @@ -28,12 +30,71 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class KeyEventTest { + private static final int DOWN_TIME = 50; + private static final long EVENT_TIME = 100; + private static final int ACTION = KeyEvent.ACTION_DOWN; + private static final int KEYCODE = KeyEvent.KEYCODE_0; + private static final int REPEAT = 0; + private static final int METASTATE = 0; + private static final int DEVICE_ID = 0; + private static final int SCAN_CODE = 0; + private static final int FLAGS = 0; + private static final int SOURCE = InputDevice.SOURCE_KEYBOARD; + private static final String CHARACTERS = null; + @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()); + KeyEvent keyEvent = KeyEvent.obtain(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT, + METASTATE, DEVICE_ID, SCAN_CODE, FLAGS, SOURCE, CHARACTERS); + assertEquals(DOWN_TIME, keyEvent.getDownTime()); + assertEquals(EVENT_TIME, keyEvent.getEventTime()); + assertEquals(ACTION, keyEvent.getAction()); + assertEquals(KEYCODE, keyEvent.getKeyCode()); + assertEquals(REPEAT, keyEvent.getRepeatCount()); + assertEquals(METASTATE, keyEvent.getMetaState()); + assertEquals(DEVICE_ID, keyEvent.getDeviceId()); + assertEquals(SCAN_CODE, keyEvent.getScanCode()); + assertEquals(FLAGS, keyEvent.getFlags()); + assertEquals(SOURCE, keyEvent.getSource()); + assertEquals(INVALID_DISPLAY, keyEvent.getDisplayId()); + assertEquals(CHARACTERS, keyEvent.getCharacters()); + } + + @Test + public void testObtainFromKeyEvent() { + KeyEvent keyEvent = KeyEvent.obtain(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT, + METASTATE, DEVICE_ID, SCAN_CODE, FLAGS, SOURCE, CHARACTERS); + KeyEvent keyEvent2 = KeyEvent.obtain(keyEvent); + assertEquals(keyEvent.getDownTime(), keyEvent2.getDownTime()); + assertEquals(keyEvent.getEventTime(), keyEvent2.getEventTime()); + assertEquals(keyEvent.getAction(), keyEvent2.getAction()); + assertEquals(keyEvent.getKeyCode(), keyEvent2.getKeyCode()); + assertEquals(keyEvent.getRepeatCount(), keyEvent2.getRepeatCount()); + assertEquals(keyEvent.getMetaState(), keyEvent2.getMetaState()); + assertEquals(keyEvent.getDeviceId(), keyEvent2.getDeviceId()); + assertEquals(keyEvent.getScanCode(), keyEvent2.getScanCode()); + assertEquals(keyEvent.getFlags(), keyEvent2.getFlags()); + assertEquals(keyEvent.getSource(), keyEvent2.getSource()); + assertEquals(keyEvent.getDisplayId(), keyEvent2.getDisplayId()); + assertEquals(keyEvent.getCharacters(), keyEvent2.getCharacters()); + } + + @Test + public void testObtainWithDisplayId() { + final int displayId = 5; + KeyEvent keyEvent = KeyEvent.obtain(DOWN_TIME, EVENT_TIME, ACTION, KEYCODE, REPEAT, + METASTATE, DEVICE_ID, SCAN_CODE, FLAGS, SOURCE, displayId, CHARACTERS); + assertEquals(DOWN_TIME, keyEvent.getDownTime()); + assertEquals(EVENT_TIME, keyEvent.getEventTime()); + assertEquals(ACTION, keyEvent.getAction()); + assertEquals(KEYCODE, keyEvent.getKeyCode()); + assertEquals(REPEAT, keyEvent.getRepeatCount()); + assertEquals(METASTATE, keyEvent.getMetaState()); + assertEquals(DEVICE_ID, keyEvent.getDeviceId()); + assertEquals(SCAN_CODE, keyEvent.getScanCode()); + assertEquals(FLAGS, keyEvent.getFlags()); + assertEquals(SOURCE, keyEvent.getSource()); + assertEquals(displayId, keyEvent.getDisplayId()); + assertEquals(CHARACTERS, keyEvent.getCharacters()); } } diff --git a/services/core/java/com/android/server/input/InputForwarder.java b/services/core/java/com/android/server/input/InputForwarder.java index 38a1cd745722e..00af8398d0fff 100644 --- a/services/core/java/com/android/server/input/InputForwarder.java +++ b/services/core/java/com/android/server/input/InputForwarder.java @@ -19,7 +19,6 @@ package com.android.server.input; import android.app.IInputForwarder; import android.hardware.input.InputManagerInternal; import android.view.InputEvent; -import android.view.MotionEvent; import com.android.server.LocalServices; @@ -40,9 +39,7 @@ class InputForwarder extends IInputForwarder.Stub { @Override public boolean forwardEvent(InputEvent event) { - if (event instanceof MotionEvent) { - ((MotionEvent) event).setDisplayId(mDisplayId); - } + event.setDisplayId(mDisplayId); return mInputManagerInternal.injectInputEvent(event, INJECT_INPUT_EVENT_MODE_ASYNC); } } \ No newline at end of file diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 89efe12927baa..9e1191d2c1ef6 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -2,6 +2,8 @@ cc_library_static { name: "libservices.core", defaults: ["libservices.core-libs"], + cpp_std: "c++17", + cflags: [ "-Wall", "-Werror",