Move displayid into InputEvent

There are certain use cases where key events should be associated with a
particular display. Refactor KeyEvent and MotionEvent to have an
associated display id.

Remove "hasAssociatedDisplay" variable from KeyboardInputMapper,
it just used to mirror "isOrientationAware".

If the keyboard is orientation aware (= it is physically attached to a
display, and therefore rotates together with that display), then
associate that keyboard with the internal viewport. Otherwise, the key
events are not associated with any particular display.

Remaining to do:
- make mInternalDisplay, mExternalDisplay, mVirtualDisplays into a
single vector with type (internal, external, virtual)
- have getDisplayViewport return std::optional (will require deep
changes)

Bug: 64258305
Test: atest inputflinger_tests libinput_tests

Change-Id: I4fe145e74cb59310efaa55bfc9dc3c2b3bd997e3
diff --git a/services/inputflinger/Android.bp b/services/inputflinger/Android.bp
index a9e5a43..45efb9f 100644
--- a/services/inputflinger/Android.bp
+++ b/services/inputflinger/Android.bp
@@ -15,6 +15,8 @@
 cc_library_shared {
     name: "libinputflinger",
 
+    cpp_std: "c++17",
+
     srcs: [
         "EventHub.cpp",
         "InputApplication.cpp",
diff --git a/services/inputflinger/InputDispatcher.cpp b/services/inputflinger/InputDispatcher.cpp
index 078fbca..18744c3 100644
--- a/services/inputflinger/InputDispatcher.cpp
+++ b/services/inputflinger/InputDispatcher.cpp
@@ -702,7 +702,7 @@
         entry->repeatCount += 1;
     } else {
         KeyEntry* newEntry = new KeyEntry(currentTime,
-                entry->deviceId, entry->source, policyFlags,
+                entry->deviceId, entry->source, entry->displayId, policyFlags,
                 entry->action, entry->flags, entry->keyCode, entry->scanCode,
                 entry->metaState, entry->repeatCount + 1, entry->downTime);
 
@@ -851,11 +851,11 @@
 
 void InputDispatcher::logOutboundKeyDetailsLocked(const char* prefix, const KeyEntry* entry) {
 #if DEBUG_OUTBOUND_EVENT_DETAILS
-    ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, policyFlags=0x%x, "
-            "action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, "
-            "repeatCount=%d, downTime=%" PRId64,
+    ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32 ", "
+            "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
+            "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
             prefix,
-            entry->eventTime, entry->deviceId, entry->source, entry->policyFlags,
+            entry->eventTime, entry->deviceId, entry->source, entry->displayId, entry->policyFlags,
             entry->action, entry->flags, entry->keyCode, entry->scanCode, entry->metaState,
             entry->repeatCount, entry->downTime);
 #endif
@@ -2018,7 +2018,7 @@
 
             // Publish the key event.
             status = connection->inputPublisher.publishKeyEvent(dispatchEntry->seq,
-                    keyEntry->deviceId, keyEntry->source,
+                    keyEntry->deviceId, keyEntry->source, keyEntry->displayId,
                     dispatchEntry->resolvedAction, dispatchEntry->resolvedFlags,
                     keyEntry->keyCode, keyEntry->scanCode,
                     keyEntry->metaState, keyEntry->repeatCount, keyEntry->downTime,
@@ -2464,9 +2464,9 @@
 void InputDispatcher::notifyKey(const NotifyKeyArgs* args) {
 #if DEBUG_INBOUND_EVENT_DETAILS
     ALOGD("notifyKey - eventTime=%" PRId64
-            ", deviceId=%d, source=0x%x, policyFlags=0x%x, action=0x%x, "
+            ", deviceId=%d, source=0x%x, displayId=%" PRId32 "policyFlags=0x%x, action=0x%x, "
             "flags=0x%x, keyCode=0x%x, scanCode=0x%x, metaState=0x%x, downTime=%" PRId64,
-            args->eventTime, args->deviceId, args->source, args->policyFlags,
+            args->eventTime, args->deviceId, args->source, args->displayId, args->policyFlags,
             args->action, args->flags, args->keyCode, args->scanCode,
             args->metaState, args->downTime);
 #endif
@@ -2491,7 +2491,7 @@
     accelerateMetaShortcuts(args->deviceId, args->action, keyCode, metaState);
 
     KeyEvent event;
-    event.initialize(args->deviceId, args->source, args->action,
+    event.initialize(args->deviceId, args->source, args->displayId, args->action,
             flags, keyCode, args->scanCode, metaState, 0,
             args->downTime, args->eventTime);
 
@@ -2519,7 +2519,7 @@
 
         int32_t repeatCount = 0;
         KeyEntry* newEntry = new KeyEntry(args->eventTime,
-                args->deviceId, args->source, policyFlags,
+                args->deviceId, args->source, args->displayId, policyFlags,
                 args->action, flags, keyCode, args->scanCode,
                 metaState, repeatCount, args->downTime);
 
@@ -2687,8 +2687,8 @@
         int32_t metaState = keyEvent.getMetaState();
         accelerateMetaShortcuts(keyEvent.getDeviceId(), action,
                 /*byref*/ keyCode, /*byref*/ metaState);
-        keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), action,
-            flags, keyCode, keyEvent.getScanCode(), metaState, 0,
+        keyEvent.initialize(keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
+            action, flags, keyCode, keyEvent.getScanCode(), metaState, 0,
             keyEvent.getDownTime(), keyEvent.getEventTime());
 
         if (flags & AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY) {
@@ -2706,7 +2706,7 @@
 
         mLock.lock();
         firstInjectedEntry = new KeyEntry(keyEvent.getEventTime(),
-                keyEvent.getDeviceId(), keyEvent.getSource(),
+                keyEvent.getDeviceId(), keyEvent.getSource(), keyEvent.getDisplayId(),
                 policyFlags, action, flags,
                 keyEvent.getKeyCode(), keyEvent.getScanCode(), keyEvent.getMetaState(),
                 keyEvent.getRepeatCount(), keyEvent.getDownTime());
@@ -3840,6 +3840,7 @@
                 keyEntry->eventTime = event.getEventTime();
                 keyEntry->deviceId = event.getDeviceId();
                 keyEntry->source = event.getSource();
+                keyEntry->displayId = event.getDisplayId();
                 keyEntry->flags = event.getFlags() | AKEY_EVENT_FLAG_FALLBACK;
                 keyEntry->keyCode = fallbackKeyCode;
                 keyEntry->scanCode = event.getScanCode();
@@ -3878,7 +3879,7 @@
 }
 
 void InputDispatcher::initializeKeyEvent(KeyEvent* event, const KeyEntry* entry) {
-    event->initialize(entry->deviceId, entry->source, entry->action, entry->flags,
+    event->initialize(entry->deviceId, entry->source, entry->displayId, entry->action, entry->flags,
             entry->keyCode, entry->scanCode, entry->metaState, entry->repeatCount,
             entry->downTime, entry->eventTime);
 }
@@ -4014,11 +4015,11 @@
 // --- InputDispatcher::KeyEntry ---
 
 InputDispatcher::KeyEntry::KeyEntry(nsecs_t eventTime,
-        int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
+        int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags, int32_t action,
         int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
         int32_t repeatCount, nsecs_t downTime) :
         EventEntry(TYPE_KEY, eventTime, policyFlags),
-        deviceId(deviceId), source(source), action(action), flags(flags),
+        deviceId(deviceId), source(source), displayId(displayId), action(action), flags(flags),
         keyCode(keyCode), scanCode(scanCode), metaState(metaState),
         repeatCount(repeatCount), downTime(downTime),
         syntheticRepeat(false), interceptKeyResult(KeyEntry::INTERCEPT_KEY_RESULT_UNKNOWN),
@@ -4029,10 +4030,10 @@
 }
 
 void InputDispatcher::KeyEntry::appendDescription(std::string& msg) const {
-    msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, action=%s, "
+    msg += StringPrintf("KeyEvent(deviceId=%d, source=0x%08x, displayId=%" PRId32 ", action=%s, "
             "flags=0x%08x, keyCode=%d, scanCode=%d, metaState=0x%08x, "
             "repeatCount=%d), policyFlags=0x%08x",
-            deviceId, source, keyActionToString(action).c_str(), flags, keyCode,
+            deviceId, source, displayId, keyActionToString(action).c_str(), flags, keyCode,
             scanCode, metaState, repeatCount, policyFlags);
 }
 
@@ -4302,6 +4303,7 @@
         const KeyMemento& memento = mKeyMementos.itemAt(i);
         if (memento.deviceId == entry->deviceId
                 && memento.source == entry->source
+                && memento.displayId == entry->displayId
                 && memento.keyCode == entry->keyCode
                 && memento.scanCode == entry->scanCode) {
             return i;
@@ -4329,6 +4331,7 @@
     KeyMemento& memento = mKeyMementos.editTop();
     memento.deviceId = entry->deviceId;
     memento.source = entry->source;
+    memento.displayId = entry->displayId;
     memento.keyCode = entry->keyCode;
     memento.scanCode = entry->scanCode;
     memento.metaState = entry->metaState;
@@ -4367,7 +4370,7 @@
         const KeyMemento& memento = mKeyMementos.itemAt(i);
         if (shouldCancelKey(memento, options)) {
             outEvents.push(new KeyEntry(currentTime,
-                    memento.deviceId, memento.source, memento.policyFlags,
+                    memento.deviceId, memento.source, memento.displayId, memento.policyFlags,
                     AKEY_EVENT_ACTION_UP, memento.flags | AKEY_EVENT_FLAG_CANCELED,
                     memento.keyCode, memento.scanCode, memento.metaState, 0, memento.downTime));
         }
@@ -4535,7 +4538,7 @@
 // --- InputDispatcher::TouchState ---
 
 InputDispatcher::TouchState::TouchState() :
-    down(false), split(false), deviceId(-1), source(0), displayId(-1) {
+    down(false), split(false), deviceId(-1), source(0), displayId(ADISPLAY_ID_NONE) {
 }
 
 InputDispatcher::TouchState::~TouchState() {
@@ -4546,7 +4549,7 @@
     split = false;
     deviceId = -1;
     source = 0;
-    displayId = -1;
+    displayId = ADISPLAY_ID_NONE;
     windows.clear();
 }
 
diff --git a/services/inputflinger/InputDispatcher.h b/services/inputflinger/InputDispatcher.h
index 82960b7..1072eb6 100644
--- a/services/inputflinger/InputDispatcher.h
+++ b/services/inputflinger/InputDispatcher.h
@@ -474,6 +474,7 @@
     struct KeyEntry : EventEntry {
         int32_t deviceId;
         uint32_t source;
+        int32_t displayId;
         int32_t action;
         int32_t flags;
         int32_t keyCode;
@@ -494,8 +495,8 @@
         nsecs_t interceptKeyWakeupTime; // used with INTERCEPT_KEY_RESULT_TRY_AGAIN_LATER
 
         KeyEntry(nsecs_t eventTime,
-                int32_t deviceId, uint32_t source, uint32_t policyFlags, int32_t action,
-                int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
+                int32_t deviceId, uint32_t source, int32_t displayId, uint32_t policyFlags,
+                int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode, int32_t metaState,
                 int32_t repeatCount, nsecs_t downTime);
         virtual void appendDescription(std::string& msg) const;
         void recycle();
@@ -753,6 +754,7 @@
         struct KeyMemento {
             int32_t deviceId;
             uint32_t source;
+            int32_t displayId;
             int32_t keyCode;
             int32_t scanCode;
             int32_t metaState;
diff --git a/services/inputflinger/InputListener.cpp b/services/inputflinger/InputListener.cpp
index c36d7cf..25a39a8 100644
--- a/services/inputflinger/InputListener.cpp
+++ b/services/inputflinger/InputListener.cpp
@@ -43,17 +43,18 @@
 // --- NotifyKeyArgs ---
 
 NotifyKeyArgs::NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source,
-        uint32_t policyFlags,
+        int32_t displayId, uint32_t policyFlags,
         int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
         int32_t metaState, nsecs_t downTime) :
-        eventTime(eventTime), deviceId(deviceId), source(source), policyFlags(policyFlags),
+        eventTime(eventTime), deviceId(deviceId), source(source), displayId(displayId),
+        policyFlags(policyFlags),
         action(action), flags(flags), keyCode(keyCode), scanCode(scanCode),
         metaState(metaState), downTime(downTime) {
 }
 
 NotifyKeyArgs::NotifyKeyArgs(const NotifyKeyArgs& other) :
         eventTime(other.eventTime), deviceId(other.deviceId), source(other.source),
-        policyFlags(other.policyFlags),
+        displayId(other.displayId), policyFlags(other.policyFlags),
         action(other.action), flags(other.flags),
         keyCode(other.keyCode), scanCode(other.scanCode),
         metaState(other.metaState), downTime(other.downTime) {
diff --git a/services/inputflinger/InputListener.h b/services/inputflinger/InputListener.h
index d24be4c..a3d919b 100644
--- a/services/inputflinger/InputListener.h
+++ b/services/inputflinger/InputListener.h
@@ -55,6 +55,7 @@
     nsecs_t eventTime;
     int32_t deviceId;
     uint32_t source;
+    int32_t displayId;
     uint32_t policyFlags;
     int32_t action;
     int32_t flags;
@@ -65,8 +66,8 @@
 
     inline NotifyKeyArgs() { }
 
-    NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, uint32_t policyFlags,
-            int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
+    NotifyKeyArgs(nsecs_t eventTime, int32_t deviceId, uint32_t source, int32_t displayId,
+            uint32_t policyFlags, int32_t action, int32_t flags, int32_t keyCode, int32_t scanCode,
             int32_t metaState, nsecs_t downTime);
 
     NotifyKeyArgs(const NotifyKeyArgs& other);
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp
index 50229cb..9a35510 100644
--- a/services/inputflinger/InputReader.cpp
+++ b/services/inputflinger/InputReader.cpp
@@ -226,7 +226,7 @@
 }
 
 static void synthesizeButtonKey(InputReaderContext* context, int32_t action,
-        nsecs_t when, int32_t deviceId, uint32_t source,
+        nsecs_t when, int32_t deviceId, uint32_t source, int32_t displayId,
         uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState,
         int32_t buttonState, int32_t keyCode) {
     if (
@@ -236,19 +236,19 @@
             || (action == AKEY_EVENT_ACTION_UP
                     && (lastButtonState & buttonState)
                     && !(currentButtonState & buttonState))) {
-        NotifyKeyArgs args(when, deviceId, source, policyFlags,
+        NotifyKeyArgs args(when, deviceId, source, displayId, policyFlags,
                 action, 0, keyCode, 0, context->getGlobalMetaState(), when);
         context->getListener()->notifyKey(&args);
     }
 }
 
 static void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
-        nsecs_t when, int32_t deviceId, uint32_t source,
+        nsecs_t when, int32_t deviceId, uint32_t source, int32_t displayId,
         uint32_t policyFlags, int32_t lastButtonState, int32_t currentButtonState) {
-    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
+    synthesizeButtonKey(context, action, when, deviceId, source, displayId, policyFlags,
             lastButtonState, currentButtonState,
             AMOTION_EVENT_BUTTON_BACK, AKEYCODE_BACK);
-    synthesizeButtonKey(context, action, when, deviceId, source, policyFlags,
+    synthesizeButtonKey(context, action, when, deviceId, source, displayId, policyFlags,
             lastButtonState, currentButtonState,
             AMOTION_EVENT_BUTTON_FORWARD, AKEYCODE_FORWARD);
 }
@@ -2240,8 +2240,7 @@
 
 KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
         uint32_t source, int32_t keyboardType) :
-        InputMapper(device), mSource(source),
-        mKeyboardType(keyboardType) {
+        InputMapper(device), mSource(source), mKeyboardType(keyboardType) {
 }
 
 KeyboardInputMapper::~KeyboardInputMapper() {
@@ -2251,6 +2250,20 @@
     return mSource;
 }
 
+int32_t KeyboardInputMapper::getOrientation() {
+    if (mViewport) {
+        return mViewport->orientation;
+    }
+    return DISPLAY_ORIENTATION_0;
+}
+
+int32_t KeyboardInputMapper::getDisplayId() {
+    if (mViewport) {
+        return mViewport->displayId;
+    }
+    return ADISPLAY_ID_NONE;
+}
+
 void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
     InputMapper::populateDeviceInfo(info);
 
@@ -2262,7 +2275,7 @@
     dump += INDENT2 "Keyboard Input Mapper:\n";
     dumpParameters(dump);
     dump += StringPrintf(INDENT3 "KeyboardType: %d\n", mKeyboardType);
-    dump += StringPrintf(INDENT3 "Orientation: %d\n", mOrientation);
+    dump += StringPrintf(INDENT3 "Orientation: %d\n", getOrientation());
     dump += StringPrintf(INDENT3 "KeyDowns: %zu keys currently down\n", mKeyDowns.size());
     dump += StringPrintf(INDENT3 "MetaState: 0x%0x\n", mMetaState);
     dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime);
@@ -2279,12 +2292,10 @@
     }
 
     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
-        mOrientation = DISPLAY_ORIENTATION_0;
-        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
-            DisplayViewport v;
-            if (config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, NULL, &v)) {
-                mOrientation = v.orientation;
-            }
+        if (mParameters.orientationAware) {
+            DisplayViewport dvp;
+            config->getDisplayViewport(ViewportType::VIEWPORT_INTERNAL, NULL, &dvp);
+            mViewport = dvp;
         }
     }
 }
@@ -2307,10 +2318,7 @@
     config.tryGetProperty(String8("keyboard.orientationAware"),
             mParameters.orientationAware);
 
-    mParameters.hasAssociatedDisplay = false;
     if (mParameters.orientationAware) {
-        mParameters.hasAssociatedDisplay = true;
-
         mapStemKey(AKEYCODE_STEM_PRIMARY, config, "keyboard.rotated.stem_primary");
         mapStemKey(AKEYCODE_STEM_1, config, "keyboard.rotated.stem_1");
         mapStemKey(AKEYCODE_STEM_2, config, "keyboard.rotated.stem_2");
@@ -2324,8 +2332,6 @@
 
 void KeyboardInputMapper::dumpParameters(std::string& dump) {
     dump += INDENT3 "Parameters:\n";
-    dump += StringPrintf(INDENT4 "HasAssociatedDisplay: %s\n",
-            toString(mParameters.hasAssociatedDisplay));
     dump += StringPrintf(INDENT4 "OrientationAware: %s\n",
             toString(mParameters.orientationAware));
     dump += StringPrintf(INDENT4 "HandlesKeyRepeat: %s\n",
@@ -2420,8 +2426,8 @@
 
     if (down) {
         // Rotate key codes according to orientation if needed.
-        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
-            keyCode = rotateKeyCode(keyCode, mOrientation);
+        if (mParameters.orientationAware) {
+            keyCode = rotateKeyCode(keyCode, getOrientation());
         }
 
         // Add key down.
@@ -2486,7 +2492,7 @@
         policyFlags |= POLICY_FLAG_DISABLE_KEY_REPEAT;
     }
 
-    NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
+    NotifyKeyArgs args(when, getDeviceId(), mSource, getDisplayId(), policyFlags,
             down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
             AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, keyMetaState, downTime);
     getListener()->notifyKey(&args);
@@ -2868,7 +2874,7 @@
 
     // Synthesize key down from buttons if needed.
     synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
-            policyFlags, lastButtonState, currentButtonState);
+            displayId, policyFlags, lastButtonState, currentButtonState);
 
     // Send motion event.
     if (downChanged || moved || scrolled || buttonsChanged) {
@@ -2947,7 +2953,7 @@
 
     // Synthesize key up from buttons if needed.
     synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
-            policyFlags, lastButtonState, currentButtonState);
+            displayId, policyFlags, lastButtonState, currentButtonState);
 
     mCursorMotionAccumulator.finishSync();
     mCursorScrollAccumulator.finishSync();
@@ -4427,7 +4433,8 @@
 
     // Synthesize key down from raw buttons if needed.
     synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mSource,
-            policyFlags, mLastCookedState.buttonState, mCurrentCookedState.buttonState);
+            mViewport.displayId, policyFlags,
+            mLastCookedState.buttonState, mCurrentCookedState.buttonState);
 
     // Dispatch the touches either directly or by translation through a pointer on screen.
     if (mDeviceMode == DEVICE_MODE_POINTER) {
@@ -4499,7 +4506,8 @@
 
     // Synthesize key up from raw buttons if needed.
     synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mSource,
-            policyFlags, mLastCookedState.buttonState, mCurrentCookedState.buttonState);
+            mViewport.displayId, policyFlags,
+            mLastCookedState.buttonState, mCurrentCookedState.buttonState);
 
     // Clear some transient state.
     mCurrentRawState.rawVScroll = 0;
@@ -4714,8 +4722,8 @@
     int32_t metaState = mContext->getGlobalMetaState();
     policyFlags |= POLICY_FLAG_VIRTUAL;
 
-    NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
-            keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+    NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, mViewport.displayId,
+            policyFlags, keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
     getListener()->notifyKey(&args);
 }
 
diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h
index cef3212..89290a8 100644
--- a/services/inputflinger/InputReader.h
+++ b/services/inputflinger/InputReader.h
@@ -35,6 +35,7 @@
 #include <utils/BitSet.h>
 #include <utils/SortedVector.h>
 
+#include <optional>
 #include <stddef.h>
 #include <unistd.h>
 
@@ -1094,6 +1095,9 @@
     virtual void updateMetaState(int32_t keyCode);
 
 private:
+    // The current viewport.
+    std::optional<DisplayViewport> mViewport;
+
     struct KeyDown {
         int32_t keyCode;
         int32_t scanCode;
@@ -1102,8 +1106,6 @@
     uint32_t mSource;
     int32_t mKeyboardType;
 
-    int32_t mOrientation; // orientation for dpad keys
-
     Vector<KeyDown> mKeyDowns; // keys that are down
     int32_t mMetaState;
     nsecs_t mDownTime; // time of most recent key down
@@ -1120,7 +1122,6 @@
 
     // Immutable configuration parameters.
     struct Parameters {
-        bool hasAssociatedDisplay;
         bool orientationAware;
         bool handlesKeyRepeat;
     } mParameters;
@@ -1128,6 +1129,9 @@
     void configureParameters();
     void dumpParameters(std::string& dump);
 
+    int32_t getOrientation();
+    int32_t getDisplayId();
+
     bool isKeyboardOrGamepadKey(int32_t scanCode);
     bool isMediaKey(int32_t keyCode);
 
diff --git a/services/inputflinger/tests/Android.bp b/services/inputflinger/tests/Android.bp
index 2faa794..ccd14c9 100644
--- a/services/inputflinger/tests/Android.bp
+++ b/services/inputflinger/tests/Android.bp
@@ -2,6 +2,7 @@
 
 cc_test {
     name: "inputflinger_tests",
+    cpp_std: "c++17",
     srcs: [
         "InputReader_test.cpp",
         "InputDispatcher_test.cpp",
diff --git a/services/inputflinger/tests/InputDispatcher_test.cpp b/services/inputflinger/tests/InputDispatcher_test.cpp
index 9c72c77..0e26d4a 100644
--- a/services/inputflinger/tests/InputDispatcher_test.cpp
+++ b/services/inputflinger/tests/InputDispatcher_test.cpp
@@ -120,7 +120,7 @@
     KeyEvent event;
 
     // Rejects undefined key actions.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
             /*action*/ -1, 0,
             AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
@@ -129,7 +129,7 @@
             << "Should reject key events with undefined action.";
 
     // Rejects ACTION_MULTIPLE since it is not supported despite being defined in the API.
-    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD,
+    event.initialize(DEVICE_ID, AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_NONE,
             AKEY_EVENT_ACTION_MULTIPLE, 0,
             AKEYCODE_A, KEY_A, AMETA_NONE, 0, ARBITRARY_TIME, ARBITRARY_TIME);
     ASSERT_EQ(INPUT_EVENT_INJECTION_FAILED, mDispatcher->injectInputEvent(
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 22f15a0..4f29e3a 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -1996,6 +1996,64 @@
     ASSERT_EQ(AKEYCODE_DPAD_RIGHT, args.keyCode);
 }
 
+TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_NotOrientationAware) {
+    // If the keyboard is not orientation aware,
+    // key events should not be associated with a specific display id
+    mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addMapperAndConfigure(mapper);
+    NotifyKeyArgs args;
+
+    // Display id should be ADISPLAY_ID_NONE without any display configuration.
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(ADISPLAY_ID_NONE, args.displayId);
+}
+
+TEST_F(KeyboardInputMapperTest, DisplayIdConfigurationChange_OrientationAware) {
+    // If the keyboard is orientation aware,
+    // key events should be associated with the internal viewport
+    mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0);
+
+    KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
+            AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);
+    addConfigurationProperty("keyboard.orientationAware", "1");
+    addMapperAndConfigure(mapper);
+    NotifyKeyArgs args;
+
+    // Display id should be ADISPLAY_ID_NONE without any display configuration.
+    // ^--- already checked by the previous test
+
+    setDisplayInfoAndReconfigure(DISPLAY_ID,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(DISPLAY_ID, args.displayId);
+
+    constexpr int32_t newDisplayId = 2;
+    setDisplayInfoAndReconfigure(newDisplayId,
+            DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0);
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 1);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    process(mapper, ARBITRARY_TIME, DEVICE_ID, EV_KEY, KEY_UP, 0);
+    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args));
+    ASSERT_EQ(newDisplayId, args.displayId);
+}
+
 TEST_F(KeyboardInputMapperTest, GetKeyCodeState) {
     KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice,
             AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC);