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

Commit 19eaae56 authored by Arpit Singh's avatar Arpit Singh Committed by Android (Google) Code Review
Browse files

Merge changes from topics "cd-cursor", "cd-cursor-position" into main

* changes:
  Expose current viewport transform of PointerController
  Check if cursor has moved out of viewport bounds in CursorController
parents ef6e3a2c 1886eea9
Loading
Loading
Loading
Loading
+23 −11
Original line number Diff line number Diff line
@@ -28,12 +28,14 @@
#define INDENT "  "
#define INDENT2 "    "

namespace android {

namespace {

// Time to spend fading out the pointer completely.
const nsecs_t POINTER_FADE_DURATION = 500 * 1000000LL; // 500 ms
} // namespace

namespace android {
} // namespace

// --- MouseCursorController ---

@@ -64,17 +66,23 @@ MouseCursorController::~MouseCursorController() {
    mLocked.pointerSprite.clear();
}

void MouseCursorController::move(float deltaX, float deltaY) {
FloatPoint MouseCursorController::move(float deltaX, float deltaY) {
#if DEBUG_MOUSE_CURSOR_UPDATES
    ALOGD("Move pointer by deltaX=%0.3f, deltaY=%0.3f", deltaX, deltaY);
#endif
    if (deltaX == 0.0f && deltaY == 0.0f) {
        return;
        return {0, 0};
    }

    // When transition occurs, the MouseCursorController object may or may not be deleted, depending
    // if there's another display on the other side of the transition. At this point we still need
    // to move the cursor to the boundary.
    std::scoped_lock lock(mLock);

    setPositionLocked(mLocked.pointerX + deltaX, mLocked.pointerY + deltaY);
    const FloatPoint position{mLocked.pointerX + deltaX, mLocked.pointerY + deltaY};
    setPositionLocked(position.x, position.y);
    // The amount of the delta that was not consumed as a result of the cursor
    // hitting the edge of the display.
    return {position.x - mLocked.pointerX, position.y - mLocked.pointerY};
}

void MouseCursorController::setPosition(float x, float y) {
@@ -85,19 +93,23 @@ void MouseCursorController::setPosition(float x, float y) {
    setPositionLocked(x, y);
}

void MouseCursorController::setPositionLocked(float x, float y) REQUIRES(mLock) {
    const auto& v = mLocked.viewport;
    if (!v.isValid()) return;

FloatRect MouseCursorController::getBoundsLocked() REQUIRES(mLock) {
    // The valid bounds for a mouse cursor. Since the right and bottom edges are considered outside
    // the display, clip the bounds by one pixel instead of letting the cursor get arbitrarily
    // close to the outside edge.
    const FloatRect bounds{
    return FloatRect{
            static_cast<float>(mLocked.viewport.logicalLeft),
            static_cast<float>(mLocked.viewport.logicalTop),
            static_cast<float>(mLocked.viewport.logicalRight - 1),
            static_cast<float>(mLocked.viewport.logicalBottom - 1),
    };
}

void MouseCursorController::setPositionLocked(float x, float y) REQUIRES(mLock) {
    const auto& v = mLocked.viewport;
    if (!v.isValid()) return;

    const FloatRect bounds = getBoundsLocked();
    mLocked.pointerX = std::max(bounds.left, std::min(bounds.right, x));
    mLocked.pointerY = std::max(bounds.top, std::min(bounds.bottom, y));

+3 −4
Original line number Diff line number Diff line
@@ -20,9 +20,6 @@
#include <gui/DisplayEventReceiver.h>
#include <input/DisplayViewport.h>
#include <input/Input.h>
#include <utils/BitSet.h>
#include <utils/Looper.h>
#include <utils/RefBase.h>

#include <functional>
#include <map>
@@ -43,7 +40,8 @@ public:
    MouseCursorController(PointerControllerContext& context);
    ~MouseCursorController();

    void move(float deltaX, float deltaY);
    // Move the pointer and return unconsumed delta
    FloatPoint move(float deltaX, float deltaY);
    void setPosition(float x, float y);
    FloatPoint getPosition() const;
    ui::LogicalDisplayId getDisplayId() const;
@@ -113,6 +111,7 @@ private:
    bool doFadingAnimationLocked(nsecs_t timestamp);

    void startAnimationLocked();
    FloatRect getBoundsLocked();
};

} // namespace android
+14 −5
Original line number Diff line number Diff line
@@ -138,15 +138,19 @@ std::mutex& PointerController::getLock() const {
    return mDisplayInfoListener->mLock;
}

void PointerController::move(float deltaX, float deltaY) {
FloatPoint PointerController::move(float deltaX, float deltaY) {
    const ui::LogicalDisplayId displayId = mCursorController.getDisplayId();
    vec2 transformed;
    ui::Transform transform;
    {
        std::scoped_lock lock(getLock());
        const auto& transform = getTransformForDisplayLocked(displayId);
        transformed = transformWithoutTranslation(transform, {deltaX, deltaY});
        transform = getTransformForDisplayLocked(displayId);
    }
    mCursorController.move(transformed.x, transformed.y);

    const vec2 transformed = transformWithoutTranslation(transform, {deltaX, deltaY});

    const FloatPoint unconsumedDelta = mCursorController.move(transformed.x, transformed.y);
    return FloatPoint(transformWithoutTranslation(transform.inverse(),
                                                  {unconsumedDelta.x, unconsumedDelta.y}));
}

void PointerController::setPosition(float x, float y) {
@@ -295,6 +299,11 @@ void PointerController::clearSkipScreenshotFlags() {
    mCursorController.setSkipScreenshot(false);
}

ui::Transform PointerController::getDisplayTransform() const {
    std::scoped_lock lock(getLock());
    return getTransformForDisplayLocked(mLocked.pointerDisplayId);
}

void PointerController::doInactivityTimeout() {
    fade(Transition::GRADUAL);
}
+3 −2
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ public:

    ~PointerController() override;

    void move(float deltaX, float deltaY) override;
    FloatPoint move(float deltaX, float deltaY) override;
    void setPosition(float x, float y) override;
    FloatPoint getPosition() const override;
    ui::LogicalDisplayId getDisplayId() const override;
@@ -67,6 +67,7 @@ public:
    void setCustomPointerIcon(const SpriteIcon& icon) override;
    void setSkipScreenshotFlagForDisplay(ui::LogicalDisplayId displayId) override;
    void clearSkipScreenshotFlags() override;
    ui::Transform getDisplayTransform() const override;

    virtual void setInactivityTimeout(InactivityTimeout inactivityTimeout);
    void doInactivityTimeout();
@@ -165,7 +166,7 @@ public:

    ~TouchPointerController() override;

    void move(float, float) override {
    FloatPoint move(float, float) override {
        LOG_ALWAYS_FATAL("Should not be called");
    }
    void setPosition(float, float) override {
+131 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ enum TestCursorType {
    CURSOR_TYPE_CUSTOM = -1,
};

static constexpr float EPSILON = MotionEvent::ROUNDING_PRECISION;

using ::testing::AllOf;
using ::testing::Field;
using ::testing::NiceMock;
@@ -399,6 +401,135 @@ INSTANTIATE_TEST_SUITE_P(PointerControllerSkipScreenshotFlagTest,
                         testing::Values(PointerControllerInterface::ControllerType::MOUSE,
                                         PointerControllerInterface::ControllerType::STYLUS));

class MousePointerControllerTest : public PointerControllerTest {
protected:
    MousePointerControllerTest() {
        sp<MockSprite> testPointerSprite(new NiceMock<MockSprite>);
        EXPECT_CALL(*mSpriteController, createSprite).WillOnce(Return(testPointerSprite));

        // create a mouse pointer controller
        mPointerController =
                PointerController::create(mPolicy, mLooper, *mSpriteController,
                                          PointerControllerInterface::ControllerType::MOUSE);

        // set display viewport
        DisplayViewport viewport;
        viewport.displayId = ui::LogicalDisplayId::DEFAULT;
        viewport.logicalRight = 5;
        viewport.logicalBottom = 5;
        viewport.physicalRight = 5;
        viewport.physicalBottom = 5;
        viewport.deviceWidth = 5;
        viewport.deviceHeight = 5;
        mPointerController->setDisplayViewport(viewport);
    }
};

struct MousePointerControllerTestParam {
    vec2 startPosition;
    vec2 delta;
    vec2 endPosition;
    vec2 unconsumedDelta;
};

class PointerControllerViewportTransitionTest
      : public MousePointerControllerTest,
        public testing::WithParamInterface<MousePointerControllerTestParam> {};

TEST_P(PointerControllerViewportTransitionTest, testPointerViewportTransition) {
    const auto& params = GetParam();

    mPointerController->setPosition(params.startPosition.x, params.startPosition.y);
    auto unconsumedDelta = mPointerController->move(params.delta.x, params.delta.y);

    auto position = mPointerController->getPosition();
    EXPECT_NEAR(position.x, params.endPosition.x, EPSILON);
    EXPECT_NEAR(position.y, params.endPosition.y, EPSILON);
    EXPECT_NEAR(unconsumedDelta.x, params.unconsumedDelta.x, EPSILON);
    EXPECT_NEAR(unconsumedDelta.y, params.unconsumedDelta.y, EPSILON);
}

INSTANTIATE_TEST_SUITE_P(PointerControllerViewportTransitionTest,
                         PointerControllerViewportTransitionTest,
                         testing::Values(
                                 // no transition
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {2.0f, 2.0f},
                                                                 {4.0f, 4.0f},
                                                                 {0.0f, 0.0f}},
                                 // right boundary
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {3.0f, 0.0f},
                                                                 {4.0f, 2.0f},
                                                                 {1.0f, 0.0f}},
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {3.0f, -1.0f},
                                                                 {4.0f, 1.0f},
                                                                 {1.0f, 0.0f}},
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {3.0f, 1.0f},
                                                                 {4.0f, 3.0f},
                                                                 {1.0f, 0.0f}},
                                 // left boundary
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {-3.0f, 0.0f},
                                                                 {0.0f, 2.0f},
                                                                 {-1.0f, 0.0f}},
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {-3.0f, -1.0f},
                                                                 {0.0f, 1.0f},
                                                                 {-1.0f, 0.0f}},
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {-3.0f, 1.0f},
                                                                 {0.0f, 3.0f},
                                                                 {-1.0f, 0.0f}},
                                 // bottom boundary
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {0.0f, 3.0f},
                                                                 {2.0f, 4.0f},
                                                                 {0.0f, 1.0f}},
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {-1.0f, 3.0f},
                                                                 {1.0f, 4.0f},
                                                                 {0.0f, 1.0f}},
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {1.0f, 3.0f},
                                                                 {3.0f, 4.0f},
                                                                 {0.0f, 1.0f}},
                                 // top boundary
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {0.0f, -3.0f},
                                                                 {2.0f, 0.0f},
                                                                 {0.0f, -1.0f}},
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {-1.0f, -3.0f},
                                                                 {1.0f, 0.0f},
                                                                 {0.0f, -1.0f}},
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {1.0f, -3.0f},
                                                                 {3.0f, 0.0f},
                                                                 {0.0f, -1.0f}},
                                 // top-left corner
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {-3.0f, -3.0f},
                                                                 {0.0f, 0.0f},
                                                                 {-1.0f, -1.0f}},
                                 // top-right corner
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {3.0f, -3.0f},
                                                                 {4.0f, 0.0f},
                                                                 {1.0f, -1.0f}},
                                 // bottom-right corner
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {3.0f, 3.0f},
                                                                 {4.0f, 4.0f},
                                                                 {1.0f, 1.0f}},
                                 // bottom-left corner
                                 MousePointerControllerTestParam{{2.0f, 2.0f},
                                                                 {-3.0f, 3.0f},
                                                                 {0.0f, 4.0f},
                                                                 {-1.0f, 1.0f}}));

class PointerControllerWindowInfoListenerTest : public Test {};

TEST_F(PointerControllerWindowInfoListenerTest,