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

Commit ea2e930e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Input devices configure on per-display basis (1/2)"

parents 3c2e0ce3 c23540e7
Loading
Loading
Loading
Loading
+61 −4
Original line number Diff line number Diff line
@@ -805,6 +805,30 @@ bool InputReader::isInputDeviceEnabled(int32_t deviceId) {
    return false;
}

bool InputReader::canDispatchToDisplay(int32_t deviceId, int32_t displayId) {
    AutoMutex _l(mLock);

    ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
    if (deviceIndex < 0) {
        ALOGW("Ignoring invalid device id %" PRId32 ".", deviceId);
        return false;
    }

    InputDevice* device = mDevices.valueAt(deviceIndex);
    std::optional<int32_t> associatedDisplayId = device->getAssociatedDisplay();
    // 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.");
        return true;
    }

    return *associatedDisplayId == displayId;
}

void InputReader::dump(std::string& dump) {
    AutoMutex _l(mLock);

@@ -1275,6 +1299,18 @@ void InputDevice::notifyReset(nsecs_t when) {
    mContext->getListener()->notifyDeviceReset(&args);
}

std::optional<int32_t> InputDevice::getAssociatedDisplay() {
    size_t numMappers = mMappers.size();
    for (size_t i = 0; i < numMappers; i++) {
        InputMapper* mapper = mMappers[i];
        std::optional<int32_t> associatedDisplayId = mapper->getAssociatedDisplay();
        if (associatedDisplayId) {
            return associatedDisplayId;
        }
    }

    return std::nullopt;
}

// --- CursorButtonAccumulator ---

@@ -2647,7 +2683,7 @@ void CursorInputMapper::configure(nsecs_t when,
        }

        // Update the PointerController if viewports changed.
        if (mParameters.hasAssociatedDisplay) {
        if (mParameters.mode == Parameters::MODE_POINTER) {
            getPolicy()->obtainPointerController(getDeviceId());
        }
        bumpGeneration();
@@ -2919,6 +2955,19 @@ void CursorInputMapper::fadePointer() {
    }
}

std::optional<int32_t> CursorInputMapper::getAssociatedDisplay() {
    if (mParameters.hasAssociatedDisplay) {
        if (mParameters.mode == Parameters::MODE_POINTER) {
            return std::make_optional(mPointerController->getDisplayId());
        } else {
            // If the device is orientationAware and not a mouse,
            // it expects to dispatch events to any display
            return std::make_optional(ADISPLAY_ID_NONE);
        }
    }
    return std::nullopt;
}

// --- RotaryEncoderInputMapper ---

RotaryEncoderInputMapper::RotaryEncoderInputMapper(InputDevice* device) :
@@ -6511,9 +6560,7 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32
            ALOG_ASSERT(false);
        }
    }
    const int32_t displayId = mPointerController != nullptr ?
            mPointerController->getDisplayId() : mViewport.displayId;

    const int32_t displayId = getAssociatedDisplay().value_or(ADISPLAY_ID_NONE);
    const int32_t deviceId = getDeviceId();
    std::vector<TouchVideoFrame> frames = mDevice->getEventHub()->getVideoFrames(deviceId);
    NotifyMotionArgs args(mContext->getNextSequenceNum(), when, deviceId,
@@ -6830,6 +6877,16 @@ bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCode
    return true;
}

std::optional<int32_t> TouchInputMapper::getAssociatedDisplay() {
    if (mParameters.hasAssociatedDisplay) {
        if (mDeviceMode == DEVICE_MODE_POINTER) {
            return std::make_optional(mPointerController->getDisplayId());
        } else {
            return std::make_optional(mViewport.displayId);
        }
    }
    return std::nullopt;
}

// --- SingleTouchInputMapper ---

+7 −2
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ public:
            ssize_t repeat, int32_t token);
    virtual void cancelVibrate(int32_t deviceId, int32_t token);

    virtual bool canDispatchToDisplay(int32_t deviceId, int32_t displayId);
protected:
    // These members are protected so they can be instrumented by test cases.
    virtual InputDevice* createDeviceLocked(int32_t deviceId, int32_t controllerNumber,
@@ -320,6 +321,7 @@ public:
        return value;
    }

    std::optional<int32_t> getAssociatedDisplay();
private:
    InputReaderContext* mContext;
    int32_t mId;
@@ -778,7 +780,9 @@ public:
    virtual void updateExternalStylusState(const StylusState& state);

    virtual void fadePointer();

    virtual std::optional<int32_t> getAssociatedDisplay() {
        return std::nullopt;
    }
protected:
    InputDevice* mDevice;
    InputReaderContext* mContext;
@@ -932,6 +936,7 @@ public:

    virtual void fadePointer();

    virtual std::optional<int32_t> getAssociatedDisplay();
private:
    // Amount that trackball needs to move in order to generate a key event.
    static const int32_t TRACKBALL_MOVEMENT_THRESHOLD = 6;
@@ -1025,7 +1030,7 @@ 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();
protected:
    CursorButtonAccumulator mCursorButtonAccumulator;
    CursorScrollAccumulator mCursorScrollAccumulator;
+3 −0
Original line number Diff line number Diff line
@@ -100,6 +100,9 @@ public:
    virtual void vibrate(int32_t deviceId, const nsecs_t* pattern, size_t patternSize,
            ssize_t repeat, int32_t token) = 0;
    virtual void cancelVibrate(int32_t deviceId, int32_t token) = 0;

    /* Return true if the device can send input events to the specified display. */
    virtual bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) = 0;
};

/* Reads raw events from the event hub and processes them, endlessly. */
+49 −4
Original line number Diff line number Diff line
@@ -841,6 +841,7 @@ class FakeInputMapper : public InputMapper {
    bool mResetWasCalled;
    bool mProcessWasCalled;

    std::optional<DisplayViewport> mViewport;
public:
    FakeInputMapper(InputDevice* device, uint32_t sources) :
            InputMapper(device),
@@ -909,8 +910,14 @@ private:
        }
    }

    virtual void configure(nsecs_t, const InputReaderConfiguration*, uint32_t) {
    virtual void configure(nsecs_t, const InputReaderConfiguration* config, uint32_t changes) {
        mConfigureWasCalled = true;

        // Find the associated viewport if exist.
        const std::optional<uint8_t> displayPort = mDevice->getAssociatedDisplayPort();
        if (displayPort && (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
            mViewport = config->getDisplayViewportByPort(*displayPort);
        }
    }

    virtual void reset(nsecs_t) {
@@ -957,6 +964,13 @@ private:

    virtual void fadePointer() {
    }

    virtual std::optional<int32_t> getAssociatedDisplay() {
        if (mViewport) {
            return std::make_optional(mViewport->displayId);
        }
        return std::nullopt;
    }
};


@@ -984,9 +998,10 @@ public:
    }

    InputDevice* newDevice(int32_t deviceId, int32_t controllerNumber, const std::string& name,
            uint32_t classes) {
            uint32_t classes, const std::string& location = "") {
        InputDeviceIdentifier identifier;
        identifier.name = name;
        identifier.location = location;
        int32_t generation = deviceId + 1;
        return new InputDevice(&mContext, deviceId, generation, controllerNumber, identifier,
                classes);
@@ -1286,7 +1301,7 @@ TEST_F(InputReaderTest, GetInputDevices) {
TEST_F(InputReaderTest, WhenEnabledChanges_SendsDeviceResetNotification) {
    constexpr int32_t deviceId = 1;
    constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
    InputDevice* device = mReader->newDevice(deviceId, 0, "fake", deviceClass);
    InputDevice* device = mReader->newDevice(deviceId, 0 /*controllerNumber*/, "fake", deviceClass);
    // Must add at least one mapper or the device will be ignored!
    FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_KEYBOARD);
    device->addMapper(mapper);
@@ -1470,7 +1485,7 @@ TEST_F(InputReaderTest, LoopOnce_ForwardsRawEventsToMappers) {
TEST_F(InputReaderTest, DeviceReset_IncrementsSequenceNumber) {
    constexpr int32_t deviceId = 1;
    constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
    InputDevice* device = mReader->newDevice(deviceId, 0, "fake", deviceClass);
    InputDevice* device = mReader->newDevice(deviceId, 0 /*controllerNumber*/, "fake", deviceClass);
    // Must add at least one mapper or the device will be ignored!
    FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_KEYBOARD);
    device->addMapper(mapper);
@@ -1500,6 +1515,36 @@ TEST_F(InputReaderTest, DeviceReset_IncrementsSequenceNumber) {
    prevSequenceNum = resetArgs.sequenceNum;
}

TEST_F(InputReaderTest, Device_CanDispatchToDisplay) {
    constexpr int32_t deviceId = 1;
    constexpr uint32_t deviceClass = INPUT_DEVICE_CLASS_KEYBOARD;
    const char* DEVICE_LOCATION = "USB1";
    InputDevice* device = mReader->newDevice(deviceId, 0 /*controllerNumber*/, "fake", deviceClass,
            DEVICE_LOCATION);
    FakeInputMapper* mapper = new FakeInputMapper(device, AINPUT_SOURCE_TOUCHSCREEN);
    device->addMapper(mapper);
    mReader->setNextDevice(device);
    addDevice(deviceId, "fake", deviceClass, nullptr);

    const uint8_t hdmi1 = 1;

    // Associated touch screen with second display.
    mFakePolicy->addInputPortAssociation(DEVICE_LOCATION, hdmi1);

    // Add default and second display.
    mFakePolicy->addDisplayViewport(DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
            DISPLAY_ORIENTATION_0, "local:0", NO_PORT, ViewportType::VIEWPORT_INTERNAL);
    mFakePolicy->addDisplayViewport(SECONDARY_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT,
            DISPLAY_ORIENTATION_0, "local:1", hdmi1, ViewportType::VIEWPORT_EXTERNAL);
    mReader->requestRefreshConfiguration(InputReaderConfiguration::CHANGE_DISPLAY_INFO);
    mReader->loopOnce();

    // Check device.
    ASSERT_EQ(deviceId, device->getId());
    ASSERT_FALSE(mReader->canDispatchToDisplay(deviceId, DISPLAY_ID));
    ASSERT_TRUE(mReader->canDispatchToDisplay(deviceId, SECONDARY_DISPLAY_ID));
}


// --- InputDeviceTest ---