Loading core/java/android/hardware/input/InputManagerInternal.java +8 −1 Original line number Diff line number Diff line Loading @@ -75,8 +75,15 @@ public abstract class InputManagerInternal { /** * Sets the display id that the MouseCursorController will be forced to target. Pass * {@link android.view.Display#INVALID_DISPLAY} to clear the override. * * Note: This method generally blocks until the pointer display override has propagated. * When setting a new override, the caller should ensure that an input device that can control * the mouse pointer is connected. If a new override is set when no such input device is * connected, the caller may be blocked for an arbitrary period of time. * * @return true if the pointer displayId was set successfully, or false if it fails. */ public abstract void setVirtualMousePointerDisplayId(int pointerDisplayId); public abstract boolean setVirtualMousePointerDisplayId(int pointerDisplayId); /** * Gets the display id that the MouseCursorController is being forced to target. Returns Loading libs/input/PointerController.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ PointerController::PointerController(const sp<PointerControllerPolicyInterface>& PointerController::~PointerController() { mDisplayInfoListener->onPointerControllerDestroyed(); mUnregisterWindowInfosListener(mDisplayInfoListener); mContext.getPolicy()->onPointerDisplayIdChanged(ADISPLAY_ID_NONE, 0, 0); } std::mutex& PointerController::getLock() const { Loading Loading @@ -255,6 +256,12 @@ void PointerController::setDisplayViewport(const DisplayViewport& viewport) { getAdditionalMouseResources = true; } mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources); if (viewport.displayId != mLocked.pointerDisplayId) { float xPos, yPos; mCursorController.getPosition(&xPos, &yPos); mContext.getPolicy()->onPointerDisplayIdChanged(viewport.displayId, xPos, yPos); mLocked.pointerDisplayId = viewport.displayId; } } void PointerController::updatePointerIcon(int32_t iconId) { Loading libs/input/PointerController.h +1 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ private: struct Locked { Presentation presentation; int32_t pointerDisplayId = ADISPLAY_ID_NONE; std::vector<gui::DisplayInfo> mDisplayInfos; std::unordered_map<int32_t /* displayId */, TouchSpotController> spotControllers; Loading libs/input/PointerControllerContext.h +1 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ public: std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) = 0; virtual int32_t getDefaultPointerIconId() = 0; virtual int32_t getCustomPointerIconId() = 0; virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) = 0; }; /* Loading libs/input/tests/PointerController_test.cpp +37 −3 Original line number Diff line number Diff line Loading @@ -56,9 +56,11 @@ public: std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) override; virtual int32_t getDefaultPointerIconId() override; virtual int32_t getCustomPointerIconId() override; virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) override; bool allResourcesAreLoaded(); bool noResourcesAreLoaded(); std::optional<int32_t> getLastReportedPointerDisplayId() { return latestPointerDisplayId; } private: void loadPointerIconForType(SpriteIcon* icon, int32_t cursorType); Loading @@ -66,6 +68,7 @@ private: bool pointerIconLoaded{false}; bool pointerResourcesLoaded{false}; bool additionalMouseResourcesLoaded{false}; std::optional<int32_t /*displayId*/> latestPointerDisplayId; }; void MockPointerControllerPolicyInterface::loadPointerIcon(SpriteIcon* icon, int32_t) { Loading Loading @@ -126,12 +129,19 @@ void MockPointerControllerPolicyInterface::loadPointerIconForType(SpriteIcon* ic icon->hotSpotX = hotSpot.first; icon->hotSpotY = hotSpot.second; } void MockPointerControllerPolicyInterface::onPointerDisplayIdChanged(int32_t displayId, float /*xPos*/, float /*yPos*/) { latestPointerDisplayId = displayId; } class PointerControllerTest : public Test { protected: PointerControllerTest(); ~PointerControllerTest(); void ensureDisplayViewportIsSet(); void ensureDisplayViewportIsSet(int32_t displayId = ADISPLAY_ID_DEFAULT); sp<MockSprite> mPointerSprite; sp<MockPointerControllerPolicyInterface> mPolicy; Loading Loading @@ -168,9 +178,9 @@ PointerControllerTest::~PointerControllerTest() { mThread.join(); } void PointerControllerTest::ensureDisplayViewportIsSet() { void PointerControllerTest::ensureDisplayViewportIsSet(int32_t displayId) { DisplayViewport viewport; viewport.displayId = ADISPLAY_ID_DEFAULT; viewport.displayId = displayId; viewport.logicalRight = 1600; viewport.logicalBottom = 1200; viewport.physicalRight = 800; Loading Loading @@ -255,6 +265,30 @@ TEST_F(PointerControllerTest, doesNotGetResourcesBeforeSettingViewport) { ensureDisplayViewportIsSet(); } TEST_F(PointerControllerTest, notifiesPolicyWhenPointerDisplayChanges) { EXPECT_FALSE(mPolicy->getLastReportedPointerDisplayId()) << "A pointer display change does not occur when PointerController is created."; ensureDisplayViewportIsSet(ADISPLAY_ID_DEFAULT); const auto lastReportedPointerDisplayId = mPolicy->getLastReportedPointerDisplayId(); ASSERT_TRUE(lastReportedPointerDisplayId) << "The policy is notified of a pointer display change when the viewport is first set."; EXPECT_EQ(ADISPLAY_ID_DEFAULT, *lastReportedPointerDisplayId) << "Incorrect pointer display notified."; ensureDisplayViewportIsSet(42); EXPECT_EQ(42, *mPolicy->getLastReportedPointerDisplayId()) << "The policy is notified when the pointer display changes."; // Release the PointerController. mPointerController = nullptr; EXPECT_EQ(ADISPLAY_ID_NONE, *mPolicy->getLastReportedPointerDisplayId()) << "The pointer display changes to invalid when PointerController is destroyed."; } class PointerControllerWindowInfoListenerTest : public Test {}; class TestPointerController : public PointerController { Loading Loading
core/java/android/hardware/input/InputManagerInternal.java +8 −1 Original line number Diff line number Diff line Loading @@ -75,8 +75,15 @@ public abstract class InputManagerInternal { /** * Sets the display id that the MouseCursorController will be forced to target. Pass * {@link android.view.Display#INVALID_DISPLAY} to clear the override. * * Note: This method generally blocks until the pointer display override has propagated. * When setting a new override, the caller should ensure that an input device that can control * the mouse pointer is connected. If a new override is set when no such input device is * connected, the caller may be blocked for an arbitrary period of time. * * @return true if the pointer displayId was set successfully, or false if it fails. */ public abstract void setVirtualMousePointerDisplayId(int pointerDisplayId); public abstract boolean setVirtualMousePointerDisplayId(int pointerDisplayId); /** * Gets the display id that the MouseCursorController is being forced to target. Returns Loading
libs/input/PointerController.cpp +7 −0 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ PointerController::PointerController(const sp<PointerControllerPolicyInterface>& PointerController::~PointerController() { mDisplayInfoListener->onPointerControllerDestroyed(); mUnregisterWindowInfosListener(mDisplayInfoListener); mContext.getPolicy()->onPointerDisplayIdChanged(ADISPLAY_ID_NONE, 0, 0); } std::mutex& PointerController::getLock() const { Loading Loading @@ -255,6 +256,12 @@ void PointerController::setDisplayViewport(const DisplayViewport& viewport) { getAdditionalMouseResources = true; } mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources); if (viewport.displayId != mLocked.pointerDisplayId) { float xPos, yPos; mCursorController.getPosition(&xPos, &yPos); mContext.getPolicy()->onPointerDisplayIdChanged(viewport.displayId, xPos, yPos); mLocked.pointerDisplayId = viewport.displayId; } } void PointerController::updatePointerIcon(int32_t iconId) { Loading
libs/input/PointerController.h +1 −0 Original line number Diff line number Diff line Loading @@ -104,6 +104,7 @@ private: struct Locked { Presentation presentation; int32_t pointerDisplayId = ADISPLAY_ID_NONE; std::vector<gui::DisplayInfo> mDisplayInfos; std::unordered_map<int32_t /* displayId */, TouchSpotController> spotControllers; Loading
libs/input/PointerControllerContext.h +1 −0 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ public: std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) = 0; virtual int32_t getDefaultPointerIconId() = 0; virtual int32_t getCustomPointerIconId() = 0; virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) = 0; }; /* Loading
libs/input/tests/PointerController_test.cpp +37 −3 Original line number Diff line number Diff line Loading @@ -56,9 +56,11 @@ public: std::map<int32_t, PointerAnimation>* outAnimationResources, int32_t displayId) override; virtual int32_t getDefaultPointerIconId() override; virtual int32_t getCustomPointerIconId() override; virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) override; bool allResourcesAreLoaded(); bool noResourcesAreLoaded(); std::optional<int32_t> getLastReportedPointerDisplayId() { return latestPointerDisplayId; } private: void loadPointerIconForType(SpriteIcon* icon, int32_t cursorType); Loading @@ -66,6 +68,7 @@ private: bool pointerIconLoaded{false}; bool pointerResourcesLoaded{false}; bool additionalMouseResourcesLoaded{false}; std::optional<int32_t /*displayId*/> latestPointerDisplayId; }; void MockPointerControllerPolicyInterface::loadPointerIcon(SpriteIcon* icon, int32_t) { Loading Loading @@ -126,12 +129,19 @@ void MockPointerControllerPolicyInterface::loadPointerIconForType(SpriteIcon* ic icon->hotSpotX = hotSpot.first; icon->hotSpotY = hotSpot.second; } void MockPointerControllerPolicyInterface::onPointerDisplayIdChanged(int32_t displayId, float /*xPos*/, float /*yPos*/) { latestPointerDisplayId = displayId; } class PointerControllerTest : public Test { protected: PointerControllerTest(); ~PointerControllerTest(); void ensureDisplayViewportIsSet(); void ensureDisplayViewportIsSet(int32_t displayId = ADISPLAY_ID_DEFAULT); sp<MockSprite> mPointerSprite; sp<MockPointerControllerPolicyInterface> mPolicy; Loading Loading @@ -168,9 +178,9 @@ PointerControllerTest::~PointerControllerTest() { mThread.join(); } void PointerControllerTest::ensureDisplayViewportIsSet() { void PointerControllerTest::ensureDisplayViewportIsSet(int32_t displayId) { DisplayViewport viewport; viewport.displayId = ADISPLAY_ID_DEFAULT; viewport.displayId = displayId; viewport.logicalRight = 1600; viewport.logicalBottom = 1200; viewport.physicalRight = 800; Loading Loading @@ -255,6 +265,30 @@ TEST_F(PointerControllerTest, doesNotGetResourcesBeforeSettingViewport) { ensureDisplayViewportIsSet(); } TEST_F(PointerControllerTest, notifiesPolicyWhenPointerDisplayChanges) { EXPECT_FALSE(mPolicy->getLastReportedPointerDisplayId()) << "A pointer display change does not occur when PointerController is created."; ensureDisplayViewportIsSet(ADISPLAY_ID_DEFAULT); const auto lastReportedPointerDisplayId = mPolicy->getLastReportedPointerDisplayId(); ASSERT_TRUE(lastReportedPointerDisplayId) << "The policy is notified of a pointer display change when the viewport is first set."; EXPECT_EQ(ADISPLAY_ID_DEFAULT, *lastReportedPointerDisplayId) << "Incorrect pointer display notified."; ensureDisplayViewportIsSet(42); EXPECT_EQ(42, *mPolicy->getLastReportedPointerDisplayId()) << "The policy is notified when the pointer display changes."; // Release the PointerController. mPointerController = nullptr; EXPECT_EQ(ADISPLAY_ID_NONE, *mPolicy->getLastReportedPointerDisplayId()) << "The pointer display changes to invalid when PointerController is destroyed."; } class PointerControllerWindowInfoListenerTest : public Test {}; class TestPointerController : public PointerController { Loading