Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3fbdbbad authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I81246b29,Ia270695b into main

* changes:
  inputflinger: remove viewport fake for device context
  JoystickInputMapperTest: migrate to InputMapperUnitTest
parents 2a3c3a5b 0b613dc0
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -72,7 +72,7 @@ public:
    inline std::optional<std::string> getDeviceTypeAssociation() const {
        return mAssociatedDeviceType;
    }
    inline std::optional<DisplayViewport> getAssociatedViewport() const {
    inline virtual std::optional<DisplayViewport> getAssociatedViewport() const {
        return mAssociatedViewport;
    }
    inline bool hasMic() const { return mHasMic; }
+22 −49
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "CursorInputMapper.h"

#include <list>
#include <optional>
#include <string>
#include <tuple>
#include <variant>
@@ -93,38 +94,6 @@ DisplayViewport createSecondaryViewport() {
    return v;
}

/**
 * A fake InputDeviceContext that allows the associated viewport to be specified for the mapper.
 *
 * This is currently necessary because InputMapperUnitTest doesn't register the mappers it creates
 * with the InputDevice object, meaning that InputDevice::isIgnored becomes true, and the input
 * device doesn't set its associated viewport when it's configured.
 *
 * TODO(b/319217713): work out a way to avoid this fake.
 */
class ViewportFakingInputDeviceContext : public InputDeviceContext {
public:
    ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId,
                                     std::optional<DisplayViewport> viewport)
          : InputDeviceContext(device, eventHubId), mAssociatedViewport(viewport) {}

    ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId,
                                     ui::Rotation orientation)
          : ViewportFakingInputDeviceContext(device, eventHubId,
                                             createPrimaryViewport(orientation)) {}

    std::optional<DisplayViewport> getAssociatedViewport() const override {
        return mAssociatedViewport;
    }

    void setViewport(const std::optional<DisplayViewport>& viewport) {
        mAssociatedViewport = viewport;
    }

private:
    std::optional<DisplayViewport> mAssociatedViewport;
};

} // namespace

namespace input_flags = com::android::input::flags;
@@ -541,8 +510,9 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldNotRotateMotionsWhenOrientationAw
    // need to be rotated.
    mPropertyMap.addProperty("cursor.mode", "navigation");
    mPropertyMap.addProperty("cursor.orientationAware", "1");
    ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation90);
    mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
    EXPECT_CALL((*mDevice), getAssociatedViewport)
            .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation90)));
    mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);

    ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0,  1,  0,  1));
    ASSERT_NO_FATAL_FAILURE(testMotionRotation( 1,  1,  1,  1));
@@ -558,8 +528,9 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldRotateMotionsWhenNotOrientationAw
    // Since InputReader works in the un-rotated coordinate space, only devices that are not
    // orientation-aware are affected by display rotation.
    mPropertyMap.addProperty("cursor.mode", "navigation");
    ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, ui::Rotation::Rotation0);
    mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
    EXPECT_CALL((*mDevice), getAssociatedViewport)
            .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation0)));
    mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);

    ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0,  1,  0,  1));
    ASSERT_NO_FATAL_FAILURE(testMotionRotation( 1,  1,  1,  1));
@@ -570,7 +541,8 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldRotateMotionsWhenNotOrientationAw
    ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1,  0, -1,  0));
    ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1,  1, -1,  1));

    deviceContext.setViewport(createPrimaryViewport(ui::Rotation::Rotation90));
    EXPECT_CALL((*mDevice), getAssociatedViewport)
            .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation90)));
    std::list<NotifyArgs> args =
            mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
                                 InputReaderConfiguration::Change::DISPLAY_INFO);
@@ -583,7 +555,8 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldRotateMotionsWhenNotOrientationAw
    ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1,  0,  0, -1));
    ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1,  1, -1, -1));

    deviceContext.setViewport(createPrimaryViewport(ui::Rotation::Rotation180));
    EXPECT_CALL((*mDevice), getAssociatedViewport)
            .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation180)));
    args = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
                                InputReaderConfiguration::Change::DISPLAY_INFO);
    ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0,  1,  0, -1));
@@ -595,7 +568,8 @@ TEST_F(CursorInputMapperUnitTest, ProcessShouldRotateMotionsWhenNotOrientationAw
    ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1,  0,  1,  0));
    ASSERT_NO_FATAL_FAILURE(testMotionRotation(-1,  1,  1, -1));

    deviceContext.setViewport(createPrimaryViewport(ui::Rotation::Rotation270));
    EXPECT_CALL((*mDevice), getAssociatedViewport)
            .WillRepeatedly(Return(createPrimaryViewport(ui::Rotation::Rotation270)));
    args = mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
                                InputReaderConfiguration::Change::DISPLAY_INFO);
    ASSERT_NO_FATAL_FAILURE(testMotionRotation( 0,  1,  1,  0));
@@ -649,8 +623,8 @@ TEST_F(CursorInputMapperUnitTest, ConfigureDisplayIdWithAssociatedViewport) {
    mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
    // Set up the secondary display as the display on which the pointer should be shown.
    // The InputDevice is not associated with any display.
    ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
    mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
    EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(secondaryViewport));
    mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);

    std::list<NotifyArgs> args;
    // Ensure input events are generated for the secondary display.
@@ -670,8 +644,8 @@ TEST_F(CursorInputMapperUnitTest,
    mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});
    // Set up the primary display as the display on which the pointer should be shown.
    // Associate the InputDevice with the secondary display.
    ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
    mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
    EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(secondaryViewport));
    mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);

    // With PointerChoreographer enabled, there could be a PointerController for the associated
    // display even if it is different from the pointer display. So the mapper should generate an
@@ -1027,8 +1001,8 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationWithAsso
    mPropertyMap.addProperty("cursor.mode", "pointer");
    DisplayViewport primaryViewport = createPrimaryViewport(ui::Rotation::Rotation0);
    mReaderConfiguration.setDisplayViewports({primaryViewport});
    ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, primaryViewport);
    mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
    EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(primaryViewport));
    mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);

    std::list<NotifyArgs> args;

@@ -1066,9 +1040,8 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationOnDispla
    mReaderConfiguration.displaysWithMousePointerAccelerationDisabled.emplace(DISPLAY_ID);

    // Don't associate the device with the display yet.
    ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID,
                                                   /*viewport=*/std::nullopt);
    mMapper = createInputMapper<CursorInputMapper>(deviceContext, mReaderConfiguration);
    EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(std::nullopt));
    mMapper = createInputMapper<CursorInputMapper>(*mDeviceContext, mReaderConfiguration);

    std::list<NotifyArgs> args;

@@ -1082,7 +1055,7 @@ TEST_F(CursorInputMapperUnitTestWithNewBallistics, ConfigureAccelerationOnDispla
    ASSERT_GT(coords.getAxisValue(AMOTION_EVENT_AXIS_RELATIVE_Y), 20.f);

    // Now associate the device with the display, and verify that acceleration is disabled.
    deviceContext.setViewport(primaryViewport);
    EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(primaryViewport));
    args += mMapper->reconfigure(ARBITRARY_TIME, mReaderConfiguration,
                                 InputReaderConfiguration::Change::DISPLAY_INFO);
    args.clear();
+1 −0
Original line number Diff line number Diff line
@@ -198,6 +198,7 @@ public:
          : InputDevice(context, id, generation, identifier) {}

    MOCK_METHOD(uint32_t, getSources, (), (const, override));
    MOCK_METHOD(std::optional<DisplayViewport>, getAssociatedViewport, (), (const));
    MOCK_METHOD(bool, isEnabled, (), ());

    MOCK_METHOD(void, dump, (std::string& dump, const std::string& eventHubDevStr), ());
+34 −54
Original line number Diff line number Diff line
@@ -16,11 +16,13 @@

#include "JoystickInputMapper.h"

#include <list>
#include <optional>

#include <EventHub.h>
#include <NotifyArgs.h>
#include <ftl/flags.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <input/DisplayViewport.h>
#include <linux/input-event-codes.h>
@@ -28,76 +30,54 @@

#include "InputMapperTest.h"
#include "TestConstants.h"
#include "TestEventMatchers.h"

namespace android {

namespace {

using namespace ftl::flag_operators;
using testing::ElementsAre;
using testing::IsEmpty;
using testing::Return;
using testing::VariantWith;

} // namespace

class JoystickInputMapperTest : public InputMapperTest {
class JoystickInputMapperTest : public InputMapperUnitTest {
protected:
    static const int32_t RAW_X_MIN;
    static const int32_t RAW_X_MAX;
    static const int32_t RAW_Y_MIN;
    static const int32_t RAW_Y_MAX;

    static constexpr ui::LogicalDisplayId VIRTUAL_DISPLAY_ID = ui::LogicalDisplayId{1};
    static const char* const VIRTUAL_DISPLAY_UNIQUE_ID;

    void SetUp() override {
        InputMapperTest::SetUp(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL);
    }
    void prepareAxes() {
        mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_X, RAW_X_MIN, RAW_X_MAX, 0, 0);
        mFakeEventHub->addAbsoluteAxis(EVENTHUB_ID, ABS_Y, RAW_Y_MIN, RAW_Y_MAX, 0, 0);
    }

    void processAxis(JoystickInputMapper& mapper, int32_t axis, int32_t value) {
        process(mapper, ARBITRARY_TIME, READ_TIME, EV_ABS, axis, value);
    }

    void processSync(JoystickInputMapper& mapper) {
        process(mapper, ARBITRARY_TIME, READ_TIME, EV_SYN, SYN_REPORT, 0);
    }

    void prepareVirtualDisplay(ui::Rotation orientation) {
        setDisplayInfoAndReconfigure(VIRTUAL_DISPLAY_ID, /*width=*/400, /*height=*/500, orientation,
                                     VIRTUAL_DISPLAY_UNIQUE_ID, /*physicalPort=*/std::nullopt,
                                     ViewportType::VIRTUAL);
        InputMapperUnitTest::SetUp();
        EXPECT_CALL(mMockEventHub, getDeviceClasses(EVENTHUB_ID))
                .WillRepeatedly(Return(InputDeviceClass::JOYSTICK | InputDeviceClass::EXTERNAL));

        // The mapper requests info on all ABS axis IDs, including ones which aren't actually used
        // (e.g. in the range from 0x0b (ABS_BRAKE) to 0x0f (ABS_HAT0X)), so just return nullopt for
        // all axes we don't explicitly set up below.
        EXPECT_CALL(mMockEventHub, getAbsoluteAxisInfo(EVENTHUB_ID, testing::_))
                .WillRepeatedly(Return(std::nullopt));

        setupAxis(ABS_X, /*valid=*/true, /*min=*/-32767, /*max=*/32767, /*resolution=*/0);
        setupAxis(ABS_Y, /*valid=*/true, /*min=*/-32767, /*max=*/32767, /*resolution=*/0);
    }
};

const int32_t JoystickInputMapperTest::RAW_X_MIN = -32767;
const int32_t JoystickInputMapperTest::RAW_X_MAX = 32767;
const int32_t JoystickInputMapperTest::RAW_Y_MIN = -32767;
const int32_t JoystickInputMapperTest::RAW_Y_MAX = 32767;
const char* const JoystickInputMapperTest::VIRTUAL_DISPLAY_UNIQUE_ID = "virtual:1";

TEST_F(JoystickInputMapperTest, Configure_AssignsDisplayUniqueId) {
    prepareAxes();
    JoystickInputMapper& mapper = constructAndAddMapper<JoystickInputMapper>();
    DisplayViewport viewport;
    viewport.displayId = ui::LogicalDisplayId{1};
    EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(viewport));
    mMapper = createInputMapper<JoystickInputMapper>(*mDeviceContext,
                                                     mFakePolicy->getReaderConfiguration());

    mFakePolicy->addInputUniqueIdAssociation(DEVICE_LOCATION, VIRTUAL_DISPLAY_UNIQUE_ID);

    prepareVirtualDisplay(ui::ROTATION_0);
    std::list<NotifyArgs> out;

    // Send an axis event
    processAxis(mapper, ABS_X, 100);
    processSync(mapper);

    NotifyMotionArgs args;
    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
    ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
    out = process(EV_ABS, ABS_X, 100);
    ASSERT_THAT(out, IsEmpty());
    out = process(EV_SYN, SYN_REPORT, 0);
    ASSERT_THAT(out, ElementsAre(VariantWith<NotifyMotionArgs>(WithDisplayId(viewport.displayId))));

    // Send another axis event
    processAxis(mapper, ABS_Y, 100);
    processSync(mapper);

    ASSERT_NO_FATAL_FAILURE(mFakeListener->assertNotifyMotionWasCalled(&args));
    ASSERT_EQ(VIRTUAL_DISPLAY_ID, args.displayId);
    out = process(EV_ABS, ABS_Y, 100);
    ASSERT_THAT(out, IsEmpty());
    out = process(EV_SYN, SYN_REPORT, 0);
    ASSERT_THAT(out, ElementsAre(VariantWith<NotifyMotionArgs>(WithDisplayId(viewport.displayId))));
}

} // namespace android
+2 −32
Original line number Diff line number Diff line
@@ -78,36 +78,6 @@ DisplayViewport createSecondaryViewport() {
    return v;
}

/**
 * A fake InputDeviceContext that allows the associated viewport to be specified for the mapper.
 *
 * This is currently necessary because InputMapperUnitTest doesn't register the mappers it creates
 * with the InputDevice object, meaning that InputDevice::isIgnored becomes true, and the input
 * device doesn't set its associated viewport when it's configured.
 *
 * TODO(b/319217713): work out a way to avoid this fake.
 */
class ViewportFakingInputDeviceContext : public InputDeviceContext {
public:
    ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId,
                                     std::optional<DisplayViewport> viewport)
          : InputDeviceContext(device, eventHubId), mAssociatedViewport(viewport) {}

    ViewportFakingInputDeviceContext(InputDevice& device, int32_t eventHubId)
          : ViewportFakingInputDeviceContext(device, eventHubId, createPrimaryViewport()) {}

    std::optional<DisplayViewport> getAssociatedViewport() const override {
        return mAssociatedViewport;
    }

    void setViewport(const std::optional<DisplayViewport>& viewport) {
        mAssociatedViewport = viewport;
    }

private:
    std::optional<DisplayViewport> mAssociatedViewport;
};

} // namespace

namespace vd_flags = android::companion::virtualdevice::flags;
@@ -138,8 +108,8 @@ TEST_F(RotaryEncoderInputMapperTest, ConfigureDisplayIdWithAssociatedViewport) {
    mReaderConfiguration.setDisplayViewports({primaryViewport, secondaryViewport});

    // Set up the secondary display as the associated viewport of the mapper.
    ViewportFakingInputDeviceContext deviceContext(*mDevice, EVENTHUB_ID, secondaryViewport);
    mMapper = createInputMapper<RotaryEncoderInputMapper>(deviceContext, mReaderConfiguration);
    EXPECT_CALL((*mDevice), getAssociatedViewport).WillRepeatedly(Return(secondaryViewport));
    mMapper = createInputMapper<RotaryEncoderInputMapper>(*mDeviceContext, mReaderConfiguration);

    std::list<NotifyArgs> args;
    // Ensure input events are generated for the secondary display.