diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java index c5f35e2d1a8a5..7b4ce61d2cfe1 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java @@ -43,9 +43,10 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu { private static final float DEFAULT_OPACITY_VALUE = 0.55f; private final Context mContext; private final AccessibilityFloatingMenuView mMenuView; + private final Handler mHandler = new Handler(Looper.getMainLooper()); private final ContentObserver mContentObserver = - new ContentObserver(new Handler(Looper.getMainLooper())) { + new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { mMenuView.onTargetsChanged(getTargets(mContext, ACCESSIBILITY_BUTTON)); @@ -53,23 +54,15 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu { }; private final ContentObserver mSizeContentObserver = - new ContentObserver(new Handler(Looper.getMainLooper())) { + new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { mMenuView.setSizeType(getSizeType(mContext)); } }; - private final ContentObserver mShapeContentObserver = - new ContentObserver(new Handler(Looper.getMainLooper())) { - @Override - public void onChange(boolean selfChange) { - mMenuView.setShapeType(getShapeType(mContext)); - } - }; - private final ContentObserver mFadeOutContentObserver = - new ContentObserver(new Handler(Looper.getMainLooper())) { + new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { mMenuView.updateOpacityWith(isFadeEffectEnabled(mContext), @@ -152,10 +145,6 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu { Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE), /* notifyForDescendants */ false, mSizeContentObserver, UserHandle.USER_CURRENT); - mContext.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE), - /* notifyForDescendants */ false, mShapeContentObserver, - UserHandle.USER_CURRENT); mContext.getContentResolver().registerContentObserver( Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED), /* notifyForDescendants */ false, mFadeOutContentObserver, @@ -169,7 +158,6 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu { private void unregisterContentObservers() { mContext.getContentResolver().unregisterContentObserver(mContentObserver); mContext.getContentResolver().unregisterContentObserver(mSizeContentObserver); - mContext.getContentResolver().unregisterContentObserver(mShapeContentObserver); mContext.getContentResolver().unregisterContentObserver(mFadeOutContentObserver); } } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java index 9ae6034c4d6ff..ab05c2a273ad4 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java @@ -82,8 +82,10 @@ public class AccessibilityFloatingMenuView extends FrameLayout private int mAlignment = Alignment.RIGHT; @SizeType private int mSizeType = SizeType.SMALL; + @VisibleForTesting @ShapeType - private int mShapeType = ShapeType.OVAL; + int mShapeType = ShapeType.OVAL; + private int mTemporaryShapeType; @RadiusType private int mRadiusType = RadiusType.LEFT_HALF_OVAL; private int mMargin; @@ -185,7 +187,6 @@ public class AccessibilityFloatingMenuView extends FrameLayout updateLocationWith(mAlignment, mPercentageY); updateMarginsWith(mAlignment); - updateOffsetWith(mShapeType, mAlignment); updateInsetWith(getResources().getConfiguration().uiMode, mAlignment); @@ -228,6 +229,10 @@ public class AccessibilityFloatingMenuView extends FrameLayout setInset(0, 0); } + mTemporaryShapeType = + isMovingTowardsScreenEdge(mAlignment, currentRawX, mDownX) + ? ShapeType.HALF_OVAL + : ShapeType.OVAL; final int newWindowX = currentRawX + mRelativeToPointerDownX; final int newWindowY = currentRawY + mRelativeToPointerDownY; mCurrentLayoutParams.x = constrain(newWindowX, MIN_WINDOW_X, getMaxWindowX()); @@ -246,10 +251,19 @@ public class AccessibilityFloatingMenuView extends FrameLayout final int endY = mCurrentLayoutParams.y; snapToLocation(endX, endY); + setShapeType(mTemporaryShapeType); + // Avoid triggering the listener of the item. return true; } - updateOffsetWith(mShapeType, mAlignment); + + // Must switch the oval shape type before tapping the corresponding item in the + // list view, otherwise it can't work on it. + if (mShapeType == ShapeType.HALF_OVAL) { + setShapeType(ShapeType.OVAL); + + return true; + } fadeOut(); break; @@ -393,6 +407,11 @@ public class AccessibilityFloatingMenuView extends FrameLayout return mListView.dispatchTouchEvent(event); } + private boolean isMovingTowardsScreenEdge(@Alignment int side, int currentRawX, int downX) { + return (side == Alignment.RIGHT && currentRawX > downX) + || (side == Alignment.LEFT && downX > currentRawX); + } + private boolean hasExceededTouchSlop(int startX, int startY, int endX, int endY) { return (sq(endX - startX) + sq(endY - startY)) > mSquareScaledTouchSlop; } diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java index b177e00f14f8a..8683dd6c33bd8 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java @@ -306,6 +306,39 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { /* newWindowY = screenCenterY - offsetY */ mScreenHalfHeight - mMenuHalfHeight); } + + @Test + public void tapOnAndDragMenuToScreenSide_transformShapeHalfOval() { + mMenuView.show(); + mMenuView.onTargetsChanged(mTargets); + mMenuView.setSizeType(0); + mMenuView.setShapeType(/* oval */ 0); + final int currentWindowX = mMenuView.mCurrentLayoutParams.x; + final int currentWindowY = mMenuView.mCurrentLayoutParams.y; + final MotionEvent downEvent = + mMotionEventHelper.obtainMotionEvent(0, 1, + MotionEvent.ACTION_DOWN, + currentWindowX + /* offsetXToMenuCenterX */ mMenuHalfWidth, + currentWindowY + /* offsetYToMenuCenterY */ mMenuHalfHeight); + final MotionEvent moveEvent = + mMotionEventHelper.obtainMotionEvent(2, 3, + MotionEvent.ACTION_MOVE, + /* downX */(currentWindowX + mMenuHalfWidth) + + /* offsetXToScreenRightSide */ mMenuHalfWidth, + /* downY */ (currentWindowY + mMenuHalfHeight)); + final MotionEvent upEvent = + mMotionEventHelper.obtainMotionEvent(4, 5, + MotionEvent.ACTION_UP, + /* downX */(currentWindowX + mMenuHalfWidth) + + /* offsetXToScreenRightSide */ mMenuHalfWidth, + /* downY */ (currentWindowY + mMenuHalfHeight)); + mListView.dispatchTouchEvent(downEvent); + mListView.dispatchTouchEvent(moveEvent); + mListView.dispatchTouchEvent(upEvent); + + assertThat(mMenuView.mShapeType).isEqualTo(/* halfOval */ 1); + } + @After public void tearDown() { mInterceptMotionEvent = null;