Merge changes from topics "styluspointericon-config", "styluspointericon-presentation"

* changes:
  check config for showing a stylus pointer (frameworks/base part)
  Separate default pointer for mouse and stylus (frameworks/base part)
This commit is contained in:
Prabir Pradhan
2023-02-03 12:52:26 +00:00
committed by Android (Google) Code Review
8 changed files with 100 additions and 15 deletions

View File

@@ -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) {

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
};

View File

@@ -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);

View File

@@ -2748,6 +2748,13 @@ public class InputManagerService extends IInputManager.Stub
return null;
}
// Native callback.
@SuppressWarnings("unused")
private boolean isStylusPointerIconEnabled() {
return Objects.requireNonNull(mContext.getSystemService(InputManager.class))
.isStylusPointerIconEnabled();
}
private static class PointerDisplayIdChangedArgs {
final int mPointerDisplayId;
final float mXPosition;

View File

@@ -137,6 +137,7 @@ static struct {
jmethodID notifyDropWindow;
jmethodID getParentSurfaceForPointers;
jmethodID isPerDisplayTouchModeEnabled;
jmethodID isStylusPointerIconEnabled;
} gServiceClassInfo;
static struct {
@@ -363,6 +364,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);
@@ -659,6 +661,12 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon
outConfig->pointerGestureTapSlop = hoverTapSlop;
}
jboolean stylusPointerIconEnabled =
env->CallBooleanMethod(mServiceObj, gServiceClassInfo.isStylusPointerIconEnabled);
if (!checkAndClearExceptionFromCallback(env, "isStylusPointerIconEnabled")) {
outConfig->stylusPointerIconEnabled = stylusPointerIconEnabled;
}
{ // acquire lock
AutoMutex _l(mLock);
@@ -1605,6 +1613,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;
}
@@ -2787,6 +2800,9 @@ int register_android_server_InputManager(JNIEnv* env) {
GET_METHOD_ID(gServiceClassInfo.isPerDisplayTouchModeEnabled, clazz,
"isPerDisplayTouchModeEnabled", "()Z");
GET_METHOD_ID(gServiceClassInfo.isStylusPointerIconEnabled, clazz, "isStylusPointerIconEnabled",
"()Z");
// InputDevice
FIND_CLASS(gInputDeviceClassInfo.clazz, "android/view/InputDevice");