diff options
| author | 2023-01-13 21:12:59 +0900 | |
|---|---|---|
| committer | 2023-02-02 11:22:57 +0000 | |
| commit | 670b33dd9068490e5a177ffa999639e774453b9e (patch) | |
| tree | 91ad2b55a3c5ce94b5d28baefb5d8935b4aeee3f | |
| parent | 3d0d262b93da10d6e01f5d3b277ace83aad4c2f6 (diff) | |
Separate default pointer for mouse and stylus (frameworks/base part)
PointerIcon.TYPE_NOT_SPECIFIED will be used for requesting default
pointer.
For the type, MouseCursorController will decide whether to show mouse or
stylus icon, based on the active source.
Need complement: the resource for default stylus icon should be added.
Test: Manual Test(hover pointer on handwriting area)
Bug: b/215436642
Change-Id: I6a337cb69bea57427f676e561900802270d206ae
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 17 | ||||
| -rw-r--r-- | libs/input/MouseCursorController.cpp | 33 | ||||
| -rw-r--r-- | libs/input/MouseCursorController.h | 3 | ||||
| -rw-r--r-- | libs/input/PointerController.cpp | 12 | ||||
| -rw-r--r-- | libs/input/PointerControllerContext.h | 1 | ||||
| -rw-r--r-- | libs/input/tests/PointerController_test.cpp | 26 | ||||
| -rw-r--r-- | services/core/jni/com_android_server_input_InputManagerService.cpp | 6 |
7 files changed, 83 insertions, 15 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 125960f0575f..308248cbf735 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -772,7 +772,12 @@ public final class ViewRootImpl implements ViewParent, private long mFpsPrevTime = -1; private int mFpsNumFrames; - private int mPointerIconType = PointerIcon.TYPE_NOT_SPECIFIED; + /** + * The resolved pointer icon type requested by this window. + * A null value indicates the resolved pointer icon has not yet been calculated. + */ + @Nullable + private Integer mPointerIconType = null; private PointerIcon mCustomPointerIcon = null; /** @@ -6905,13 +6910,13 @@ public final class ViewRootImpl implements ViewParent, || event.getActionMasked() == MotionEvent.ACTION_HOVER_EXIT) { // Other apps or the window manager may change the icon type outside of // this app, therefore the icon type has to be reset on enter/exit event. - mPointerIconType = PointerIcon.TYPE_NOT_SPECIFIED; + mPointerIconType = null; } if (event.getActionMasked() != MotionEvent.ACTION_HOVER_EXIT) { if (!updatePointerIcon(event) && event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE) { - mPointerIconType = PointerIcon.TYPE_NOT_SPECIFIED; + mPointerIconType = null; } } } @@ -6950,7 +6955,7 @@ public final class ViewRootImpl implements ViewParent, } private void resetPointerIcon(MotionEvent event) { - mPointerIconType = PointerIcon.TYPE_NOT_SPECIFIED; + mPointerIconType = null; updatePointerIcon(event); } @@ -6980,9 +6985,9 @@ public final class ViewRootImpl implements ViewParent, } final int pointerType = (pointerIcon != null) ? - pointerIcon.getType() : PointerIcon.TYPE_DEFAULT; + pointerIcon.getType() : PointerIcon.TYPE_NOT_SPECIFIED; - if (mPointerIconType != pointerType) { + if (mPointerIconType == null || mPointerIconType != pointerType) { mPointerIconType = pointerType; mCustomPointerIcon = null; if (mPointerIconType != PointerIcon.TYPE_CUSTOM) { diff --git a/libs/input/MouseCursorController.cpp b/libs/input/MouseCursorController.cpp index a83516791f33..24cfc9d70c9b 100644 --- a/libs/input/MouseCursorController.cpp +++ b/libs/input/MouseCursorController.cpp @@ -38,6 +38,8 @@ MouseCursorController::MouseCursorController(PointerControllerContext& context) : mContext(context) { std::scoped_lock lock(mLock); + mLocked.stylusHoverMode = false; + mLocked.animationFrameIndex = 0; mLocked.lastFrameUpdatedTime = 0; @@ -47,7 +49,8 @@ MouseCursorController::MouseCursorController(PointerControllerContext& context) mLocked.pointerAlpha = 0.0f; // pointer is initially faded mLocked.pointerSprite = mContext.getSpriteController()->createSprite(); mLocked.updatePointerIcon = false; - mLocked.requestedPointerType = mContext.getPolicy()->getDefaultPointerIconId(); + mLocked.requestedPointerType = PointerIconStyle::TYPE_NOT_SPECIFIED; + mLocked.resolvedPointerType = PointerIconStyle::TYPE_NOT_SPECIFIED; mLocked.resourcesLoaded = false; @@ -184,6 +187,15 @@ void MouseCursorController::unfade(PointerControllerInterface::Transition transi } } +void MouseCursorController::setStylusHoverMode(bool stylusHoverMode) { + std::scoped_lock lock(mLock); + + if (mLocked.stylusHoverMode != stylusHoverMode) { + mLocked.stylusHoverMode = stylusHoverMode; + mLocked.updatePointerIcon = true; + } +} + void MouseCursorController::reloadPointerResources(bool getAdditionalMouseResources) { std::scoped_lock lock(mLock); @@ -339,7 +351,7 @@ bool MouseCursorController::doFadingAnimationLocked(nsecs_t timestamp) REQUIRES( bool MouseCursorController::doBitmapAnimationLocked(nsecs_t timestamp) REQUIRES(mLock) { std::map<PointerIconStyle, PointerAnimation>::const_iterator iter = - mLocked.animationResources.find(mLocked.requestedPointerType); + mLocked.animationResources.find(mLocked.resolvedPointerType); if (iter == mLocked.animationResources.end()) { return false; } @@ -381,14 +393,23 @@ void MouseCursorController::updatePointerLocked() REQUIRES(mLock) { } if (mLocked.updatePointerIcon) { - if (mLocked.requestedPointerType == mContext.getPolicy()->getDefaultPointerIconId()) { + mLocked.resolvedPointerType = mLocked.requestedPointerType; + const PointerIconStyle defaultPointerIconId = + mContext.getPolicy()->getDefaultPointerIconId(); + if (mLocked.resolvedPointerType == PointerIconStyle::TYPE_NOT_SPECIFIED) { + mLocked.resolvedPointerType = mLocked.stylusHoverMode + ? mContext.getPolicy()->getDefaultStylusIconId() + : defaultPointerIconId; + } + + if (mLocked.resolvedPointerType == defaultPointerIconId) { mLocked.pointerSprite->setIcon(mLocked.pointerIcon); } else { std::map<PointerIconStyle, SpriteIcon>::const_iterator iter = - mLocked.additionalMouseResources.find(mLocked.requestedPointerType); + mLocked.additionalMouseResources.find(mLocked.resolvedPointerType); if (iter != mLocked.additionalMouseResources.end()) { std::map<PointerIconStyle, PointerAnimation>::const_iterator anim_iter = - mLocked.animationResources.find(mLocked.requestedPointerType); + mLocked.animationResources.find(mLocked.resolvedPointerType); if (anim_iter != mLocked.animationResources.end()) { mLocked.animationFrameIndex = 0; mLocked.lastFrameUpdatedTime = systemTime(SYSTEM_TIME_MONOTONIC); @@ -396,7 +417,7 @@ void MouseCursorController::updatePointerLocked() REQUIRES(mLock) { } mLocked.pointerSprite->setIcon(iter->second); } else { - ALOGW("Can't find the resource for icon id %d", mLocked.requestedPointerType); + ALOGW("Can't find the resource for icon id %d", mLocked.resolvedPointerType); mLocked.pointerSprite->setIcon(mLocked.pointerIcon); } } diff --git a/libs/input/MouseCursorController.h b/libs/input/MouseCursorController.h index 208d33d7c717..db0ab56429b2 100644 --- a/libs/input/MouseCursorController.h +++ b/libs/input/MouseCursorController.h @@ -53,6 +53,7 @@ public: void fade(PointerControllerInterface::Transition transition); void unfade(PointerControllerInterface::Transition transition); void setDisplayViewport(const DisplayViewport& viewport, bool getAdditionalMouseResources); + void setStylusHoverMode(bool stylusHoverMode); void updatePointerIcon(PointerIconStyle iconId); void setCustomPointerIcon(const SpriteIcon& icon); @@ -74,6 +75,7 @@ private: struct Locked { DisplayViewport viewport; + bool stylusHoverMode; size_t animationFrameIndex; nsecs_t lastFrameUpdatedTime; @@ -92,6 +94,7 @@ private: std::map<PointerIconStyle, PointerAnimation> animationResources; PointerIconStyle requestedPointerType; + PointerIconStyle resolvedPointerType; int32_t buttonState; diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp index 099efd3a1a2f..fedf58d7c6d0 100644 --- a/libs/input/PointerController.cpp +++ b/libs/input/PointerController.cpp @@ -195,7 +195,11 @@ void PointerController::setPresentation(Presentation presentation) { return; } - if (presentation == Presentation::POINTER) { + if (presentation == Presentation::POINTER || presentation == Presentation::STYLUS_HOVER) { + // For now, we support stylus hover using the mouse cursor implementation. + // TODO: Add proper support for stylus hover icons. + mCursorController.setStylusHoverMode(presentation == Presentation::STYLUS_HOVER); + mCursorController.getAdditionalMouseResources(); clearSpotsLocked(); } @@ -249,7 +253,8 @@ void PointerController::reloadPointerResources() { if (mCursorController.resourcesLoaded()) { bool getAdditionalMouseResources = false; - if (mLocked.presentation == PointerController::Presentation::POINTER) { + if (mLocked.presentation == PointerController::Presentation::POINTER || + mLocked.presentation == PointerController::Presentation::STYLUS_HOVER) { getAdditionalMouseResources = true; } mCursorController.reloadPointerResources(getAdditionalMouseResources); @@ -260,7 +265,8 @@ void PointerController::setDisplayViewport(const DisplayViewport& viewport) { std::scoped_lock lock(getLock()); bool getAdditionalMouseResources = false; - if (mLocked.presentation == PointerController::Presentation::POINTER) { + if (mLocked.presentation == PointerController::Presentation::POINTER || + mLocked.presentation == PointerController::Presentation::STYLUS_HOVER) { getAdditionalMouseResources = true; } mCursorController.setDisplayViewport(viewport, getAdditionalMouseResources); diff --git a/libs/input/PointerControllerContext.h b/libs/input/PointerControllerContext.h index 1797428b343f..96d83a5f0d15 100644 --- a/libs/input/PointerControllerContext.h +++ b/libs/input/PointerControllerContext.h @@ -79,6 +79,7 @@ public: std::map<PointerIconStyle, PointerAnimation>* outAnimationResources, int32_t displayId) = 0; virtual PointerIconStyle getDefaultPointerIconId() = 0; + virtual PointerIconStyle getDefaultStylusIconId() = 0; virtual PointerIconStyle getCustomPointerIconId() = 0; virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) = 0; }; diff --git a/libs/input/tests/PointerController_test.cpp b/libs/input/tests/PointerController_test.cpp index a6a4115476df..c820d0007a4b 100644 --- a/libs/input/tests/PointerController_test.cpp +++ b/libs/input/tests/PointerController_test.cpp @@ -35,6 +35,7 @@ enum TestCursorType { CURSOR_TYPE_ANCHOR, CURSOR_TYPE_ADDITIONAL, CURSOR_TYPE_ADDITIONAL_ANIM, + CURSOR_TYPE_STYLUS, CURSOR_TYPE_CUSTOM = -1, }; @@ -57,6 +58,7 @@ public: std::map<PointerIconStyle, PointerAnimation>* outAnimationResources, int32_t displayId) override; virtual PointerIconStyle getDefaultPointerIconId() override; + virtual PointerIconStyle getDefaultStylusIconId() override; virtual PointerIconStyle getCustomPointerIconId() override; virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos) override; @@ -105,6 +107,11 @@ void MockPointerControllerPolicyInterface::loadAdditionalMouseResources( (*outResources)[static_cast<PointerIconStyle>(cursorType)] = icon; (*outAnimationResources)[static_cast<PointerIconStyle>(cursorType)] = anim; + // CURSOR_TYPE_STYLUS doesn't have animation resource. + cursorType = CURSOR_TYPE_STYLUS; + loadPointerIconForType(&icon, cursorType); + (*outResources)[static_cast<PointerIconStyle>(cursorType)] = icon; + additionalMouseResourcesLoaded = true; } @@ -112,6 +119,10 @@ PointerIconStyle MockPointerControllerPolicyInterface::getDefaultPointerIconId() return static_cast<PointerIconStyle>(CURSOR_TYPE_DEFAULT); } +PointerIconStyle MockPointerControllerPolicyInterface::getDefaultStylusIconId() { + return static_cast<PointerIconStyle>(CURSOR_TYPE_STYLUS); +} + PointerIconStyle MockPointerControllerPolicyInterface::getCustomPointerIconId() { return static_cast<PointerIconStyle>(CURSOR_TYPE_CUSTOM); } @@ -214,6 +225,21 @@ TEST_F(PointerControllerTest, useDefaultCursorTypeByDefault) { mPointerController->reloadPointerResources(); } +TEST_F(PointerControllerTest, useStylusTypeForStylusHover) { + ensureDisplayViewportIsSet(); + mPointerController->setPresentation(PointerController::Presentation::STYLUS_HOVER); + mPointerController->unfade(PointerController::Transition::IMMEDIATE); + std::pair<float, float> hotspot = getHotSpotCoordinatesForType(CURSOR_TYPE_STYLUS); + EXPECT_CALL(*mPointerSprite, setVisible(true)); + EXPECT_CALL(*mPointerSprite, setAlpha(1.0f)); + EXPECT_CALL(*mPointerSprite, + setIcon(AllOf(Field(&SpriteIcon::style, + static_cast<PointerIconStyle>(CURSOR_TYPE_STYLUS)), + Field(&SpriteIcon::hotSpotX, hotspot.first), + Field(&SpriteIcon::hotSpotY, hotspot.second)))); + mPointerController->reloadPointerResources(); +} + TEST_F(PointerControllerTest, updatePointerIcon) { ensureDisplayViewportIsSet(); mPointerController->setPresentation(PointerController::Presentation::POINTER); diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index f4d1d1ef88d1..56ccf872d2f6 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -363,6 +363,7 @@ public: std::map<PointerIconStyle, SpriteIcon>* outResources, std::map<PointerIconStyle, PointerAnimation>* outAnimationResources, int32_t displayId); virtual PointerIconStyle getDefaultPointerIconId(); + virtual PointerIconStyle getDefaultStylusIconId(); virtual PointerIconStyle getCustomPointerIconId(); virtual void onPointerDisplayIdChanged(int32_t displayId, float xPos, float yPos); @@ -1605,6 +1606,11 @@ PointerIconStyle NativeInputManager::getDefaultPointerIconId() { return PointerIconStyle::TYPE_ARROW; } +PointerIconStyle NativeInputManager::getDefaultStylusIconId() { + // TODO: add resource for default stylus icon and change this + return PointerIconStyle::TYPE_CROSSHAIR; +} + PointerIconStyle NativeInputManager::getCustomPointerIconId() { return PointerIconStyle::TYPE_CUSTOM; } |