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

Commit 8dca8a34 authored by Peter Liang's avatar Peter Liang
Browse files

Fix that accessibility floating menu did not remember tucked state when lock/unlock the phone.

Actions:
1) Add a new SharedPreference key to record the tucked state.
2) Add a new LiveData for the tucked state.

Bug: 251082969
Test: atest MenuAnimationControllerTest MenuViewLayerTest
Change-Id: I8e8ae6867b6ad72959de3f6bb92c913ae61286c2
parent e1e1887e
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -72,7 +72,8 @@ public final class Prefs {
            Key.HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP,
            Key.ACCESSIBILITY_FLOATING_MENU_POSITION,
            Key.HAS_CLICKED_NUDGE_TO_SETUP_DREAM,
            Key.HAS_DISMISSED_NUDGE_TO_SETUP_DREAM
            Key.HAS_DISMISSED_NUDGE_TO_SETUP_DREAM,
            Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED
    })
    // TODO: annotate these with their types so {@link PrefsCommandLine} can know how to set them
    public @interface Key {
@@ -117,6 +118,7 @@ public final class Prefs {
        String ACCESSIBILITY_FLOATING_MENU_POSITION = "AccessibilityFloatingMenuPosition";
        String HAS_CLICKED_NUDGE_TO_SETUP_DREAM = "HasClickedNudgeToSetupDream";
        String HAS_DISMISSED_NUDGE_TO_SETUP_DREAM = "HasDismissedNudgeToSetupDream";
        String HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED = "HasAccessibilityFloatingMenuTucked";
    }

    public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
+17 −22
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package com.android.systemui.accessibility.floatingmenu;

import static android.util.MathUtils.constrain;

import static java.util.Objects.requireNonNull;

import android.animation.ValueAnimator;
@@ -64,7 +62,6 @@ class MenuAnimationController {
    private final MenuView mMenuView;
    private final ValueAnimator mFadeOutAnimator;
    private final Handler mHandler;
    private boolean mIsMovedToEdge;
    private boolean mIsFadeEffectEnabled;
    private DismissAnimationController.DismissCallback mDismissCallback;

@@ -111,25 +108,25 @@ class MenuAnimationController {
    }

    void moveToTopLeftPosition() {
        mIsMovedToEdge = false;
        mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ false);
        final Rect draggableBounds = mMenuView.getMenuDraggableBounds();
        moveAndPersistPosition(new PointF(draggableBounds.left, draggableBounds.top));
    }

    void moveToTopRightPosition() {
        mIsMovedToEdge = false;
        mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ false);
        final Rect draggableBounds = mMenuView.getMenuDraggableBounds();
        moveAndPersistPosition(new PointF(draggableBounds.right, draggableBounds.top));
    }

    void moveToBottomLeftPosition() {
        mIsMovedToEdge = false;
        mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ false);
        final Rect draggableBounds = mMenuView.getMenuDraggableBounds();
        moveAndPersistPosition(new PointF(draggableBounds.left, draggableBounds.bottom));
    }

    void moveToBottomRightPosition() {
        mIsMovedToEdge = false;
        mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ false);
        final Rect draggableBounds = mMenuView.getMenuDraggableBounds();
        moveAndPersistPosition(new PointF(draggableBounds.right, draggableBounds.bottom));
    }
@@ -254,6 +251,8 @@ class MenuAnimationController {
        // If the translation x is zero, it should be at the left of the bound.
        if (currentXTranslation < draggableBounds.left
                || currentXTranslation > draggableBounds.right) {
            constrainPositionAndUpdate(
                    new PointF(mMenuView.getTranslationX(), mMenuView.getTranslationY()));
            moveToEdgeAndHide();
            return true;
        }
@@ -262,37 +261,33 @@ class MenuAnimationController {
        return false;
    }

    private boolean isOnLeftSide() {
    boolean isOnLeftSide() {
        return mMenuView.getTranslationX() < mMenuView.getMenuDraggableBounds().centerX();
    }

    boolean isMovedToEdge() {
        return mIsMovedToEdge;
    boolean isMoveToTucked() {
        return mMenuView.isMoveToTucked();
    }

    void moveToEdgeAndHide() {
        mIsMovedToEdge = true;
        mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ true);

        final Rect draggableBounds = mMenuView.getMenuDraggableBounds();
        final float endY = constrain(mMenuView.getTranslationY(), draggableBounds.top,
                draggableBounds.bottom);
        final float menuHalfWidth = mMenuView.getWidth() / 2.0f;
        final PointF position = mMenuView.getMenuPosition();
        final float menuHalfWidth = mMenuView.getMenuWidth() / 2.0f;
        final float endX = isOnLeftSide()
                ? draggableBounds.left - menuHalfWidth
                : draggableBounds.right + menuHalfWidth;
        moveAndPersistPosition(new PointF(endX, endY));
                ? position.x - menuHalfWidth
                : position.x + menuHalfWidth;
        moveToPosition(new PointF(endX, position.y));

        // Keep the touch region let users could click extra space to pop up the menu view
        // from the screen edge
        mMenuView.onBoundsInParentChanged(isOnLeftSide()
                ? draggableBounds.left
                : draggableBounds.right, (int) mMenuView.getTranslationY());
        mMenuView.onBoundsInParentChanged((int) position.x, (int) position.y);

        fadeOutIfEnabled();
    }

    void moveOutEdgeAndShow() {
        mIsMovedToEdge = false;
        mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ false);

        mMenuView.onPositionChanged();
        mMenuView.onEdgeChangedIfNeeded();
+12 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ class MenuInfoRepository {

    @FloatRange(from = 0.0, to = 1.0)
    private static final float DEFAULT_MENU_POSITION_Y_PERCENT = 0.77f;
    private static final boolean DEFAULT_MOVE_TO_TUCKED_VALUE = false;

    private final Context mContext;
    private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -92,6 +93,12 @@ class MenuInfoRepository {
        mPercentagePosition = getStartPosition();
    }

    void loadMenuMoveToTucked(OnInfoReady<Boolean> callback) {
        callback.onReady(
                Prefs.getBoolean(mContext, Prefs.Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED,
                        DEFAULT_MOVE_TO_TUCKED_VALUE));
    }

    void loadMenuPosition(OnInfoReady<Position> callback) {
        callback.onReady(mPercentagePosition);
    }
@@ -113,6 +120,11 @@ class MenuInfoRepository {
                getMenuOpacityFromSettings(mContext));
    }

    void updateMoveToTucked(boolean isMoveToTucked) {
        Prefs.putBoolean(mContext, Prefs.Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED,
                isMoveToTucked);
    }

    void updateMenuSavingPosition(Position percentagePosition) {
        mPercentagePosition = percentagePosition;
        Prefs.putString(mContext, Prefs.Key.ACCESSIBILITY_FLOATING_MENU_POSITION,
+2 −2
Original line number Diff line number Diff line
@@ -74,10 +74,10 @@ class MenuItemAccessibilityDelegate extends RecyclerViewAccessibilityDelegate.It
                                R.string.accessibility_floating_button_action_move_bottom_right));
        info.addAction(moveBottomRight);

        final int moveEdgeId = mAnimationController.isMovedToEdge()
        final int moveEdgeId = mAnimationController.isMoveToTucked()
                ? R.id.action_move_out_edge_and_show
                : R.id.action_move_to_edge_and_hide;
        final int moveEdgeTextResId = mAnimationController.isMovedToEdge()
        final int moveEdgeTextResId = mAnimationController.isMoveToTucked()
                ? R.string.accessibility_floating_button_action_move_out_edge_and_show
                : R.string.accessibility_floating_button_action_move_to_edge_and_hide_to_half;
        final AccessibilityNodeInfoCompat.AccessibilityActionCompat moveToOrOutEdge =
+34 −1
Original line number Diff line number Diff line
@@ -58,12 +58,15 @@ class MenuView extends FrameLayout implements
            this::updateSystemGestureExcludeRects;
    private final Observer<MenuFadeEffectInfo> mFadeEffectInfoObserver =
            this::onMenuFadeEffectInfoChanged;
    private final Observer<Boolean> mMoveToTuckedObserver = this::onMoveToTucked;
    private final Observer<Position> mPercentagePositionObserver = this::onPercentagePosition;
    private final Observer<Integer> mSizeTypeObserver = this::onSizeTypeChanged;
    private final Observer<List<AccessibilityTarget>> mTargetFeaturesObserver =
            this::onTargetFeaturesChanged;
    private final MenuViewAppearance mMenuViewAppearance;

    private boolean mIsMoveToTucked;

    private OnTargetFeaturesChangeListener mFeaturesChangeListener;

    MenuView(Context context, MenuViewModel menuViewModel, MenuViewAppearance menuViewAppearance) {
@@ -161,6 +164,12 @@ class MenuView extends FrameLayout implements
                mMenuViewAppearance.getMenuStrokeColor());
    }

    private void onMoveToTucked(boolean isMoveToTucked) {
        mIsMoveToTucked = isMoveToTucked;

        onPositionChanged();
    }

    private void onPercentagePosition(Position percentagePosition) {
        mMenuViewAppearance.setPercentagePosition(percentagePosition);

@@ -171,6 +180,10 @@ class MenuView extends FrameLayout implements
        final PointF position = mMenuViewAppearance.getMenuPosition();
        mMenuAnimationController.moveToPosition(position);
        onBoundsInParentChanged((int) position.x, (int) position.y);

        if (isMoveToTucked()) {
            mMenuAnimationController.moveToEdgeAndHide();
        }
    }

    @SuppressLint("NotifyDataSetChanged")
@@ -227,6 +240,14 @@ class MenuView extends FrameLayout implements
        return mMenuViewAppearance.getMenuHeight();
    }

    int getMenuWidth() {
        return mMenuViewAppearance.getMenuWidth();
    }

    PointF getMenuPosition() {
        return mMenuViewAppearance.getMenuPosition();
    }

    void persistPositionAndUpdateEdge(Position percentagePosition) {
        mMenuViewModel.updateMenuSavingPosition(percentagePosition);
        mMenuViewAppearance.setPercentagePosition(percentagePosition);
@@ -234,6 +255,16 @@ class MenuView extends FrameLayout implements
        onEdgeChangedIfNeeded();
    }

    boolean isMoveToTucked() {
        return mIsMoveToTucked;
    }

    void updateMenuMoveToTucked(boolean isMoveToTucked) {
        mIsMoveToTucked = isMoveToTucked;
        mMenuViewModel.updateMenuMoveToTucked(isMoveToTucked);
    }


    /**
     * Uses the touch events from the parent view to identify if users clicked the extra
     * space of the menu view. If yes, will use the percentage position and update the
@@ -249,7 +280,7 @@ class MenuView extends FrameLayout implements
    boolean maybeMoveOutEdgeAndShow(int x, int y) {
        // Utilizes the touch region of the parent view to implement that users could tap extra
        // the space region to show the menu from the edge.
        if (!mMenuAnimationController.isMovedToEdge() || !mBoundsInParent.contains(x, y)) {
        if (!isMoveToTucked() || !mBoundsInParent.contains(x, y)) {
            return false;
        }

@@ -266,6 +297,7 @@ class MenuView extends FrameLayout implements
        mMenuViewModel.getFadeEffectInfoData().observeForever(mFadeEffectInfoObserver);
        mMenuViewModel.getTargetFeaturesData().observeForever(mTargetFeaturesObserver);
        mMenuViewModel.getSizeTypeData().observeForever(mSizeTypeObserver);
        mMenuViewModel.getMoveToTuckedData().observeForever(mMoveToTuckedObserver);
        setVisibility(VISIBLE);
        mMenuViewModel.registerContentObservers();
        getViewTreeObserver().addOnComputeInternalInsetsListener(this);
@@ -279,6 +311,7 @@ class MenuView extends FrameLayout implements
        mMenuViewModel.getFadeEffectInfoData().removeObserver(mFadeEffectInfoObserver);
        mMenuViewModel.getTargetFeaturesData().removeObserver(mTargetFeaturesObserver);
        mMenuViewModel.getSizeTypeData().removeObserver(mSizeTypeObserver);
        mMenuViewModel.getMoveToTuckedData().removeObserver(mMoveToTuckedObserver);
        mMenuViewModel.unregisterContentObservers();
        getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
        getViewTreeObserver().removeOnDrawListener(mSystemGestureExcludeUpdater);
Loading