diff options
author | 2019-08-28 02:34:24 +0000 | |
---|---|---|
committer | 2019-08-28 02:34:24 +0000 | |
commit | 645e65e97ff06c10b6218a1b0f850303eff6cf08 (patch) | |
tree | 26032975c0a76f9e9bb81269c42ff28b01d4ab5c | |
parent | 554897f62837c4c15e4ff30ab9740626e44a59cb (diff) | |
parent | 2c9a3341977e315ffb8e78cac2343a2682e71dc3 (diff) |
Merge "Add associated function to physical keyboard"
-rw-r--r-- | services/inputflinger/InputReader.cpp | 86 | ||||
-rw-r--r-- | services/inputflinger/InputReader.h | 22 | ||||
-rw-r--r-- | services/inputflinger/tests/InputReader_test.cpp | 216 |
3 files changed, 258 insertions, 66 deletions
diff --git a/services/inputflinger/InputReader.cpp b/services/inputflinger/InputReader.cpp index 4631becee8..1cbf78eb43 100644 --- a/services/inputflinger/InputReader.cpp +++ b/services/inputflinger/InputReader.cpp @@ -819,14 +819,19 @@ bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) { } InputDevice* device = mDevices.valueAt(deviceIndex); - std::optional<int32_t> associatedDisplayId = device->getAssociatedDisplay(); + if (!device->isEnabled()) { + ALOGW("Ignoring disabled device %s", device->getName().c_str()); + return false; + } + + std::optional<int32_t> associatedDisplayId = device->getAssociatedDisplayId(); // No associated display. By default, can dispatch to all displays. if (!associatedDisplayId) { return true; } if (*associatedDisplayId == ADISPLAY_ID_NONE) { - ALOGW("Device has associated, but no associated display id."); + ALOGW("Device %s is associated with display ADISPLAY_ID_NONE.", device->getName().c_str()); return true; } @@ -1002,6 +1007,13 @@ bool InputDevice::isEnabled() { } void InputDevice::setEnabled(bool enabled, nsecs_t when) { + if (enabled && mAssociatedDisplayPort && !mAssociatedViewport) { + ALOGW("Cannot enable input device %s because it is associated with port %" PRIu8 ", " + "but the corresponding viewport is not found", + getName().c_str(), *mAssociatedDisplayPort); + enabled = false; + } + if (isEnabled() == enabled) { return; } @@ -1103,6 +1115,7 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) { // In most situations, no port will be specified. mAssociatedDisplayPort = std::nullopt; + mAssociatedViewport = std::nullopt; // Find the display port that corresponds to the current input port. const std::string& inputPort = mIdentifier.location; if (!inputPort.empty()) { @@ -1112,6 +1125,23 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config mAssociatedDisplayPort = std::make_optional(displayPort->second); } } + + // If the device was explicitly disabled by the user, it would be present in the + // "disabledDevices" list. If it is associated with a specific display, and it was not + // explicitly disabled, then enable/disable the device based on whether we can find the + // corresponding viewport. + bool enabled = (config->disabledDevices.find(mId) == config->disabledDevices.end()); + if (mAssociatedDisplayPort) { + mAssociatedViewport = config->getDisplayViewportByPort(*mAssociatedDisplayPort); + if (!mAssociatedViewport) { + ALOGW("Input device %s should be associated with display on port %" PRIu8 ", " + "but the corresponding viewport is not found.", + getName().c_str(), *mAssociatedDisplayPort); + enabled = false; + } + } + + setEnabled(enabled, when); } for (InputMapper* mapper : mMappers) { @@ -1276,9 +1306,15 @@ void InputDevice::notifyReset(nsecs_t when) { mContext->getListener()->notifyDeviceReset(&args); } -std::optional<int32_t> InputDevice::getAssociatedDisplay() { +std::optional<int32_t> InputDevice::getAssociatedDisplayId() { + // Check if we had associated to the specific display. + if (mAssociatedViewport) { + return mAssociatedViewport->displayId; + } + + // No associated display port, check if some InputMapper is associated. for (InputMapper* mapper : mMappers) { - std::optional<int32_t> associatedDisplayId = mapper->getAssociatedDisplay(); + std::optional<int32_t> associatedDisplayId = mapper->getAssociatedDisplayId(); if (associatedDisplayId) { return associatedDisplayId; } @@ -2229,6 +2265,22 @@ void KeyboardInputMapper::dump(std::string& dump) { dump += StringPrintf(INDENT3 "DownTime: %" PRId64 "\n", mDownTime); } +std::optional<DisplayViewport> KeyboardInputMapper::findViewport( + nsecs_t when, const InputReaderConfiguration* config) { + const std::optional<uint8_t> displayPort = mDevice->getAssociatedDisplayPort(); + if (displayPort) { + // Find the viewport that contains the same port + return mDevice->getAssociatedViewport(); + } + + // No associated display defined, try to find default display if orientationAware. + if (mParameters.orientationAware) { + return config->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL); + } + + return std::nullopt; +} + void KeyboardInputMapper::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) { InputMapper::configure(when, config, changes); @@ -2239,9 +2291,7 @@ void KeyboardInputMapper::configure(nsecs_t when, } if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) { - if (mParameters.orientationAware) { - mViewport = config->getDisplayViewportByType(ViewportType::VIEWPORT_INTERNAL); - } + mViewport = findViewport(when, config); } } @@ -2521,6 +2571,12 @@ void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState, } } +std::optional<int32_t> KeyboardInputMapper::getAssociatedDisplayId() { + if (mViewport) { + return std::make_optional(mViewport->displayId); + } + return std::nullopt; +} // --- CursorInputMapper --- @@ -2935,7 +2991,7 @@ void CursorInputMapper::fadePointer() { } } -std::optional<int32_t> CursorInputMapper::getAssociatedDisplay() { +std::optional<int32_t> CursorInputMapper::getAssociatedDisplayId() { if (mParameters.hasAssociatedDisplay) { if (mParameters.mode == Parameters::MODE_POINTER) { return std::make_optional(mPointerController->getDisplayId()); @@ -3467,15 +3523,10 @@ std::optional<DisplayViewport> TouchInputMapper::findViewport() { const std::optional<uint8_t> displayPort = mDevice->getAssociatedDisplayPort(); if (displayPort) { // Find the viewport that contains the same port - std::optional<DisplayViewport> v = mConfig.getDisplayViewportByPort(*displayPort); - if (!v) { - ALOGW("Input device %s should be associated with display on port %" PRIu8 ", " - "but the corresponding viewport is not found.", - getDeviceName().c_str(), *displayPort); - } - return v; + return mDevice->getAssociatedViewport(); } + // Check if uniqueDisplayId is specified in idc file. if (!mParameters.uniqueDisplayId.empty()) { return mConfig.getDisplayViewportByUniqueId(mParameters.uniqueDisplayId); } @@ -3499,6 +3550,7 @@ std::optional<DisplayViewport> TouchInputMapper::findViewport() { return viewport; } + // No associated display, return a non-display viewport. DisplayViewport newViewport; // Raw width and height in the natural orientation. int32_t rawWidth = mRawPointerAxes.getRawWidth(); @@ -6508,7 +6560,7 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32 if (mDeviceMode == DEVICE_MODE_POINTER) { mPointerController->getPosition(&xCursorPosition, &yCursorPosition); } - const int32_t displayId = getAssociatedDisplay().value_or(ADISPLAY_ID_NONE); + const int32_t displayId = getAssociatedDisplayId().value_or(ADISPLAY_ID_NONE); const int32_t deviceId = getDeviceId(); std::vector<TouchVideoFrame> frames = mDevice->getEventHub()->getVideoFrames(deviceId); std::for_each(frames.begin(), frames.end(), @@ -6817,7 +6869,7 @@ bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCode return true; } -std::optional<int32_t> TouchInputMapper::getAssociatedDisplay() { +std::optional<int32_t> TouchInputMapper::getAssociatedDisplayId() { if (mParameters.hasAssociatedDisplay) { if (mDeviceMode == DEVICE_MODE_POINTER) { return std::make_optional(mPointerController->getDisplayId()); diff --git a/services/inputflinger/InputReader.h b/services/inputflinger/InputReader.h index b7f94c18f3..0666ca54bf 100644 --- a/services/inputflinger/InputReader.h +++ b/services/inputflinger/InputReader.h @@ -265,7 +265,9 @@ public: inline std::optional<uint8_t> getAssociatedDisplayPort() const { return mAssociatedDisplayPort; } - + inline std::optional<DisplayViewport> getAssociatedViewport() const { + return mAssociatedViewport; + } inline void setMic(bool hasMic) { mHasMic = hasMic; } inline bool hasMic() const { return mHasMic; } @@ -324,7 +326,8 @@ public: return value; } - std::optional<int32_t> getAssociatedDisplay(); + std::optional<int32_t> getAssociatedDisplayId(); + private: InputReaderContext* mContext; int32_t mId; @@ -339,6 +342,7 @@ private: uint32_t mSources; bool mIsExternal; std::optional<uint8_t> mAssociatedDisplayPort; + std::optional<DisplayViewport> mAssociatedViewport; bool mHasMic; bool mDropUntilNextSync; @@ -718,9 +722,8 @@ public: virtual void updateExternalStylusState(const StylusState& state); virtual void fadePointer(); - virtual std::optional<int32_t> getAssociatedDisplay() { - return std::nullopt; - } + virtual std::optional<int32_t> getAssociatedDisplayId() { return std::nullopt; } + protected: InputDevice* mDevice; InputReaderContext* mContext; @@ -802,6 +805,7 @@ public: virtual int32_t getMetaState(); virtual void updateMetaState(int32_t keyCode); + virtual std::optional<int32_t> getAssociatedDisplayId(); private: // The current viewport. @@ -855,6 +859,8 @@ private: void updateLedState(bool reset); void updateLedStateForModifier(LedState& ledState, int32_t led, int32_t modifier, bool reset); + std::optional<DisplayViewport> findViewport(nsecs_t when, + const InputReaderConfiguration* config); }; @@ -874,7 +880,8 @@ public: virtual void fadePointer(); - virtual std::optional<int32_t> getAssociatedDisplay(); + virtual std::optional<int32_t> getAssociatedDisplayId(); + private: // Amount that trackball needs to move in order to generate a key event. static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6; @@ -968,7 +975,8 @@ public: virtual void cancelTouch(nsecs_t when); virtual void timeoutExpired(nsecs_t when); virtual void updateExternalStylusState(const StylusState& state); - virtual std::optional<int32_t> getAssociatedDisplay(); + virtual std::optional<int32_t> getAssociatedDisplayId(); + protected: CursorButtonAccumulator mCursorButtonAccumulator; CursorScrollAccumulator mCursorScrollAccumulator; diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp index d95ac96124..348a12bf3a 100644 --- a/services/inputflinger/tests/InputReader_test.cpp +++ b/services/inputflinger/tests/InputReader_test.cpp @@ -1556,10 +1556,14 @@ TEST_F(InputReaderTest, Device_CanDispatchToDisplay) { mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO); mReader->loopOnce(); - // Check device. + // Device should only dispatch to the specified display. ASSERT_EQ(deviceId, device->getId()); ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, DISPLAY_ID)); ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID)); + + // Can't dispatch event from a disabled device. + disableDevice(deviceId, device); + ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID)); } @@ -1568,6 +1572,7 @@ TEST_F(InputReaderTest, Device_CanDispatchToDisplay) { class InputDeviceTest : public testing::Test { protected: static const char* DEVICE_NAME; + static const char* DEVICE_LOCATION; static const int32_t DEVICE_ID; static const int32_t DEVICE_GENERATION; static const int32_t DEVICE_CONTROLLER_NUMBER; @@ -1589,6 +1594,7 @@ protected: mFakeEventHub->addDevice(DEVICE_ID, DEVICE_NAME, 0); InputDeviceIdentifier identifier; identifier.name = DEVICE_NAME; + identifier.location = DEVICE_LOCATION; mDevice = new InputDevice(mFakeContext, DEVICE_ID, DEVICE_GENERATION, DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES); } @@ -1603,6 +1609,7 @@ protected: }; const char* InputDeviceTest::DEVICE_NAME = "device"; +const char* InputDeviceTest::DEVICE_LOCATION = "USB1"; const int32_t InputDeviceTest::DEVICE_ID = 1; const int32_t InputDeviceTest::DEVICE_GENERATION = 2; const int32_t InputDeviceTest::DEVICE_CONTROLLER_NUMBER = 0; @@ -1755,6 +1762,49 @@ TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRe ASSERT_NO_FATAL_FAILURE(mapper2->assertProcessWasCalled()); } +// A single input device is associated with a specific display. Check that: +// 1. Device is disabled if the viewport corresponding to the associated display is not found +// 2. Device is disabled when setEnabled API is called +TEST_F(InputDeviceTest, Configure_AssignsDisplayPort) { + FakeInputMapper* mapper = new FakeInputMapper(mDevice, AINPUT_SOURCE_TOUCHSCREEN); + mDevice->addMapper(mapper); + + // First Configuration. + mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0); + + // Device should be enabled by default. + ASSERT_TRUE(mDevice->isEnabled()); + + // Prepare associated info. + constexpr uint8_t hdmi = 1; + const std::string UNIQUE_ID = "local:1"; + + mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi); + mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), + InputReaderConfiguration::CHANGE_DISPLAY_INFO); + // Device should be disabled because it is associated with a specific display via + // input port <-> display port association, but the corresponding display is not found + ASSERT_FALSE(mDevice->isEnabled()); + + // Prepare displays. + mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, + DISPLAY_ORIENTATION_0, UNIQUE_ID, hdmi, + ViewportType::VIEWPORT_INTERNAL); + mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), + InputReaderConfiguration::CHANGE_DISPLAY_INFO); + ASSERT_TRUE(mDevice->isEnabled()); + + // Device should be disabled after set disable. + mFakePolicy->addDisabledDevice(mDevice->getId()); + mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), + InputReaderConfiguration::CHANGE_ENABLED_STATE); + ASSERT_FALSE(mDevice->isEnabled()); + + // Device should still be disabled even found the associated display. + mDevice->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), + InputReaderConfiguration::CHANGE_DISPLAY_INFO); + ASSERT_FALSE(mDevice->isEnabled()); +} // --- InputMapperTest --- @@ -1926,8 +1976,9 @@ protected: void prepareDisplay(int32_t orientation); - void testDPadKeyRotation(KeyboardInputMapper* mapper, - int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode); + void testDPadKeyRotation(KeyboardInputMapper* mapper, int32_t originalScanCode, + int32_t originalKeyCode, int32_t rotatedKeyCode, + int32_t displayId = ADISPLAY_ID_NONE); }; /* Similar to setDisplayInfoAndReconfigure, but pre-populates all parameters except for the @@ -1939,7 +1990,8 @@ void KeyboardInputMapperTest::prepareDisplay(int32_t orientation) { } void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper, - int32_t originalScanCode, int32_t originalKeyCode, int32_t rotatedKeyCode) { + int32_t originalScanCode, int32_t originalKeyCode, + int32_t rotatedKeyCode, int32_t displayId) { NotifyKeyArgs args; process(mapper, ARBITRARY_TIME, EV_KEY, originalScanCode, 1); @@ -1947,15 +1999,16 @@ void KeyboardInputMapperTest::testDPadKeyRotation(KeyboardInputMapper* mapper, ASSERT_EQ(AKEY_EVENT_ACTION_DOWN, args.action); ASSERT_EQ(originalScanCode, args.scanCode); ASSERT_EQ(rotatedKeyCode, args.keyCode); + ASSERT_EQ(displayId, args.displayId); process(mapper, ARBITRARY_TIME, EV_KEY, originalScanCode, 0); ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyKeyWasCalled(&args)); ASSERT_EQ(AKEY_EVENT_ACTION_UP, args.action); ASSERT_EQ(originalScanCode, args.scanCode); ASSERT_EQ(rotatedKeyCode, args.keyCode); + ASSERT_EQ(displayId, args.displayId); } - TEST_F(KeyboardInputMapperTest, GetSources) { KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); @@ -2136,47 +2189,47 @@ TEST_F(KeyboardInputMapperTest, Process_WhenOrientationAware_ShouldRotateDPad) { addMapperAndConfigure(mapper); prepareDisplay(DISPLAY_ORIENTATION_0); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_RIGHT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_DOWN)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_LEFT)); + ASSERT_NO_FATAL_FAILURE( + testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, + AKEYCODE_DPAD_RIGHT, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN, + AKEYCODE_DPAD_DOWN, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT, + AKEYCODE_DPAD_LEFT, DISPLAY_ID)); clearViewports(); prepareDisplay(DISPLAY_ORIENTATION_90); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_UP)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_RIGHT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_DOWN)); + ASSERT_NO_FATAL_FAILURE( + testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_LEFT, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, + AKEYCODE_DPAD_UP, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN, + AKEYCODE_DPAD_RIGHT, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT, + AKEYCODE_DPAD_DOWN, DISPLAY_ID)); clearViewports(); prepareDisplay(DISPLAY_ORIENTATION_180); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_LEFT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_UP)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_RIGHT)); + ASSERT_NO_FATAL_FAILURE( + testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_DOWN, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, + AKEYCODE_DPAD_LEFT, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN, + AKEYCODE_DPAD_UP, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT, + AKEYCODE_DPAD_RIGHT, DISPLAY_ID)); clearViewports(); prepareDisplay(DISPLAY_ORIENTATION_270); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_RIGHT, AKEYCODE_DPAD_RIGHT, AKEYCODE_DPAD_DOWN)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_DOWN, AKEYCODE_DPAD_DOWN, AKEYCODE_DPAD_LEFT)); - ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, - KEY_LEFT, AKEYCODE_DPAD_LEFT, AKEYCODE_DPAD_UP)); + ASSERT_NO_FATAL_FAILURE( + testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_RIGHT, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, + AKEYCODE_DPAD_DOWN, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN, + AKEYCODE_DPAD_LEFT, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT, + AKEYCODE_DPAD_UP, DISPLAY_ID)); // Special case: if orientation changes while key is down, we still emit the same keycode // in the key up as we did in the key down. @@ -2360,6 +2413,84 @@ TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleMetaStateAndLeds) ASSERT_EQ(AMETA_NONE, mapper->getMetaState()); } +TEST_F(KeyboardInputMapperTest, Configure_AssignsDisplayPort) { + // keyboard 1. + mFakeEventHub->addKey(DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0); + mFakeEventHub->addKey(DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0); + mFakeEventHub->addKey(DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0); + mFakeEventHub->addKey(DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0); + + // keyboard 2. + const std::string USB2 = "USB2"; + constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1; + InputDeviceIdentifier identifier; + identifier.name = "KEYBOARD2"; + identifier.location = USB2; + std::unique_ptr<InputDevice> device2 = + std::make_unique<InputDevice>(mFakeContext, SECOND_DEVICE_ID, DEVICE_GENERATION, + DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES); + mFakeEventHub->addDevice(SECOND_DEVICE_ID, DEVICE_NAME, 0 /*classes*/); + mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_UP, 0, AKEYCODE_DPAD_UP, 0); + mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_RIGHT, 0, AKEYCODE_DPAD_RIGHT, 0); + mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_DOWN, 0, AKEYCODE_DPAD_DOWN, 0); + mFakeEventHub->addKey(SECOND_DEVICE_ID, KEY_LEFT, 0, AKEYCODE_DPAD_LEFT, 0); + + KeyboardInputMapper* mapper = new KeyboardInputMapper(mDevice, AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); + addMapperAndConfigure(mapper); + + KeyboardInputMapper* mapper2 = new KeyboardInputMapper(device2.get(), AINPUT_SOURCE_KEYBOARD, + AINPUT_KEYBOARD_TYPE_ALPHABETIC); + device2->addMapper(mapper2); + device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/); + device2->reset(ARBITRARY_TIME); + + // Prepared displays and associated info. + constexpr uint8_t hdmi1 = 0; + constexpr uint8_t hdmi2 = 1; + const std::string SECONDARY_UNIQUE_ID = "local:1"; + + mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1); + mFakePolicy->addInputPortAssociation(USB2, hdmi2); + + // No associated display viewport found, should disable the device. + device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), + InputReaderConfiguration::CHANGE_DISPLAY_INFO); + ASSERT_FALSE(device2->isEnabled()); + + // Prepare second display. + constexpr int32_t newDisplayId = 2; + setDisplayInfoAndReconfigure(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0, + UNIQUE_ID, hdmi1, ViewportType::VIEWPORT_INTERNAL); + setDisplayInfoAndReconfigure(newDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT, DISPLAY_ORIENTATION_0, + SECONDARY_UNIQUE_ID, hdmi2, ViewportType::VIEWPORT_EXTERNAL); + // Default device will reconfigure above, need additional reconfiguration for another device. + device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), + InputReaderConfiguration::CHANGE_DISPLAY_INFO); + + // Device should be enabled after the associated display is found. + ASSERT_TRUE(mDevice->isEnabled()); + ASSERT_TRUE(device2->isEnabled()); + + // Test pad key events + ASSERT_NO_FATAL_FAILURE( + testDPadKeyRotation(mapper, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, + AKEYCODE_DPAD_RIGHT, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_DOWN, AKEYCODE_DPAD_DOWN, + AKEYCODE_DPAD_DOWN, DISPLAY_ID)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper, KEY_LEFT, AKEYCODE_DPAD_LEFT, + AKEYCODE_DPAD_LEFT, DISPLAY_ID)); + + ASSERT_NO_FATAL_FAILURE( + testDPadKeyRotation(mapper2, KEY_UP, AKEYCODE_DPAD_UP, AKEYCODE_DPAD_UP, newDisplayId)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_RIGHT, AKEYCODE_DPAD_RIGHT, + AKEYCODE_DPAD_RIGHT, newDisplayId)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_DOWN, AKEYCODE_DPAD_DOWN, + AKEYCODE_DPAD_DOWN, newDisplayId)); + ASSERT_NO_FATAL_FAILURE(testDPadKeyRotation(mapper2, KEY_LEFT, AKEYCODE_DPAD_LEFT, + AKEYCODE_DPAD_LEFT, newDisplayId)); +} // --- CursorInputMapperTest --- @@ -6276,12 +6407,13 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) { // Create the second touch screen device, and enable multi fingers. const std::string USB2 = "USB2"; - const int32_t SECOND_DEVICE_ID = 2; + constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1; InputDeviceIdentifier identifier; - identifier.name = DEVICE_NAME; + identifier.name = "TOUCHSCREEN2"; identifier.location = USB2; - InputDevice* device2 = new InputDevice(mFakeContext, SECOND_DEVICE_ID, DEVICE_GENERATION, - DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES); + std::unique_ptr<InputDevice> device2 = + std::make_unique<InputDevice>(mFakeContext, SECOND_DEVICE_ID, DEVICE_GENERATION, + DEVICE_CONTROLLER_NUMBER, identifier, DEVICE_CLASSES); mFakeEventHub->addDevice(SECOND_DEVICE_ID, DEVICE_NAME, 0 /*classes*/); mFakeEventHub->addAbsoluteAxis(SECOND_DEVICE_ID, ABS_MT_POSITION_X, RAW_X_MIN, RAW_X_MAX, 0 /*flat*/, 0 /*fuzz*/); @@ -6296,7 +6428,7 @@ TEST_F(MultiTouchInputMapperTest, Process_Pointer_ShowTouches) { String8("touchScreen")); // Setup the second touch screen device. - MultiTouchInputMapper* mapper2 = new MultiTouchInputMapper(device2); + MultiTouchInputMapper* mapper2 = new MultiTouchInputMapper(device2.get()); device2->addMapper(mapper2); device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/); device2->reset(ARBITRARY_TIME); |