From 8dca8a3434230643649718b82692253fd2cd9a39 Mon Sep 17 00:00:00 2001 From: Peter Liang Date: Sun, 6 Nov 2022 22:17:03 +0800 Subject: [PATCH] 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 --- .../src/com/android/systemui/Prefs.java | 4 +- .../floatingmenu/MenuAnimationController.java | 39 ++++++++----------- .../floatingmenu/MenuInfoRepository.java | 12 ++++++ .../MenuItemAccessibilityDelegate.java | 4 +- .../accessibility/floatingmenu/MenuView.java | 35 ++++++++++++++++- .../floatingmenu/MenuViewModel.java | 10 +++++ .../MenuAnimationControllerTest.java | 37 +++++++++++++++++- .../floatingmenu/MenuViewLayerTest.java | 1 + 8 files changed, 115 insertions(+), 27 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java index 9aa5fae1044d1..70750a1dafb5a 100644 --- a/packages/SystemUI/src/com/android/systemui/Prefs.java +++ b/packages/SystemUI/src/com/android/systemui/Prefs.java @@ -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) { diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java index 0cfd6a4689f4a..1e14763e57d54 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationController.java @@ -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(); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java index 4c52b331497d9..5bc7406bb9d03 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuInfoRepository.java @@ -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 callback) { + callback.onReady( + Prefs.getBoolean(mContext, Prefs.Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED, + DEFAULT_MOVE_TO_TUCKED_VALUE)); + } + void loadMenuPosition(OnInfoReady 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, diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java index ac5736b0c26d7..14517ba5bdb44 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuItemAccessibilityDelegate.java @@ -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 = diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java index 2ecb58c84ff63..986aa51ecce1a 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuView.java @@ -58,12 +58,15 @@ class MenuView extends FrameLayout implements this::updateSystemGestureExcludeRects; private final Observer mFadeEffectInfoObserver = this::onMenuFadeEffectInfoChanged; + private final Observer mMoveToTuckedObserver = this::onMoveToTucked; private final Observer mPercentagePositionObserver = this::onPercentagePosition; private final Observer mSizeTypeObserver = this::onSizeTypeChanged; private final Observer> 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); diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java index e8a2b6e8767ba..bd417877c1242 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewModel.java @@ -35,6 +35,7 @@ class MenuViewModel implements MenuInfoRepository.OnSettingsContentsChanged { private final MutableLiveData mSizeTypeData = new MutableLiveData<>(); private final MutableLiveData mFadeEffectInfoData = new MutableLiveData<>(); + private final MutableLiveData mMoveToTuckedData = new MutableLiveData<>(); private final MutableLiveData mPercentagePositionData = new MutableLiveData<>(); private final MenuInfoRepository mInfoRepository; @@ -57,10 +58,19 @@ class MenuViewModel implements MenuInfoRepository.OnSettingsContentsChanged { mFadeEffectInfoData.setValue(fadeEffectInfo); } + void updateMenuMoveToTucked(boolean isMoveToTucked) { + mInfoRepository.updateMoveToTucked(isMoveToTucked); + } + void updateMenuSavingPosition(Position percentagePosition) { mInfoRepository.updateMenuSavingPosition(percentagePosition); } + LiveData getMoveToTuckedData() { + mInfoRepository.loadMenuMoveToTucked(mMoveToTuckedData::setValue); + return mMoveToTuckedData; + } + LiveData getPercentagePositionData() { mInfoRepository.loadMenuPosition(mPercentagePositionData::setValue); return mPercentagePositionData; diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java index d0bd4f7026ebc..b2c52668e057a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuAnimationControllerTest.java @@ -32,8 +32,10 @@ import android.view.WindowManager; import androidx.test.filters.SmallTest; +import com.android.systemui.Prefs; import com.android.systemui.SysuiTestCase; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -44,6 +46,7 @@ import org.junit.runner.RunWith; @SmallTest public class MenuAnimationControllerTest extends SysuiTestCase { + private boolean mLastIsMoveToTucked; private ViewPropertyAnimator mViewPropertyAnimator; private MenuView mMenuView; private MenuAnimationController mMenuAnimationController; @@ -60,6 +63,14 @@ public class MenuAnimationControllerTest extends SysuiTestCase { doReturn(mViewPropertyAnimator).when(mMenuView).animate(); mMenuAnimationController = new MenuAnimationController(mMenuView); + mLastIsMoveToTucked = Prefs.getBoolean(mContext, + Prefs.Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED, /* defaultValue= */ false); + } + + @After + public void tearDown() throws Exception { + Prefs.putBoolean(mContext, Prefs.Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED, + mLastIsMoveToTucked); } @Test @@ -81,10 +92,34 @@ public class MenuAnimationControllerTest extends SysuiTestCase { @Test public void startGrowAnimation_menuCompletelyOpaque() { - mMenuAnimationController.startShrinkAnimation(null); + mMenuAnimationController.startShrinkAnimation(/* endAction= */ null); mMenuAnimationController.startGrowAnimation(); assertThat(mMenuView.getAlpha()).isEqualTo(/* completelyOpaque */ 1.0f); } + + @Test + public void moveToEdgeAndHide_untucked_expectedSharedPreferenceValue() { + Prefs.putBoolean(mContext, Prefs.Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED, /* value= */ + false); + + mMenuAnimationController.moveToEdgeAndHide(); + final boolean isMoveToTucked = Prefs.getBoolean(mContext, + Prefs.Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED, /* defaultValue= */ false); + + assertThat(isMoveToTucked).isTrue(); + } + + @Test + public void moveOutEdgeAndShow_tucked_expectedSharedPreferenceValue() { + Prefs.putBoolean(mContext, Prefs.Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED, /* value= */ + true); + + mMenuAnimationController.moveOutEdgeAndShow(); + final boolean isMoveToTucked = Prefs.getBoolean(mContext, + Prefs.Key.HAS_ACCESSIBILITY_FLOATING_MENU_TUCKED, /* defaultValue= */ true); + + assertThat(isMoveToTucked).isFalse(); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java index 3e0aad8a17f8f..428a00a6dcefc 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewLayerTest.java @@ -141,6 +141,7 @@ public class MenuViewLayerTest extends SysuiTestCase { Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, mLastEnabledAccessibilityServices, UserHandle.USER_CURRENT); + mMenuView.updateMenuMoveToTucked(/* isMoveToTucked= */ false); mMenuViewLayer.onDetachedFromWindow(); }