Move displayId into InputEvent

Now both KeyEvent and MotionEvent will contain displayId. This will help
with dispatching input events to specific displays. There are use cases
where a particular input device is used for a specific display only, and
it sends key events to the system. This will help with those usages.

Test: atest view.MotionEventTest view.KeyEventTest
Bug: 64258305
Change-Id: I75891037617ed60820d60736216a0d615ab5e3b0
This commit is contained in:
Siarhei Vishniakou
2018-06-08 22:49:30 +01:00
parent beac1471aa
commit 91fa08ff1b
8 changed files with 135 additions and 16 deletions

View File

@@ -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.
*

View File

@@ -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;
}
/**
* <p>Returns the state of the meta keys.</p>
*
@@ -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);

View File

@@ -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);
}

View File

@@ -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(),

View File

@@ -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");

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -2,6 +2,8 @@ cc_library_static {
name: "libservices.core",
defaults: ["libservices.core-libs"],
cpp_std: "c++17",
cflags: [
"-Wall",
"-Werror",