summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/layout/accessibility_floating_menu_tooltip.xml11
-rw-r--r--packages/SystemUI/src/com/android/systemui/Prefs.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DockTooltipView.java50
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MigrationTooltipView.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DockTooltipViewTest.java105
8 files changed, 275 insertions, 26 deletions
diff --git a/packages/SystemUI/res/layout/accessibility_floating_menu_tooltip.xml b/packages/SystemUI/res/layout/accessibility_floating_menu_tooltip.xml
index 601198bb7e09..5e7b7e16dbdc 100644
--- a/packages/SystemUI/res/layout/accessibility_floating_menu_tooltip.xml
+++ b/packages/SystemUI/res/layout/accessibility_floating_menu_tooltip.xml
@@ -22,6 +22,14 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
+ <View
+ android:id="@+id/arrow_left"
+ android:layout_width="@dimen/accessibility_floating_tooltip_arrow_width"
+ android:layout_height="@dimen/accessibility_floating_tooltip_arrow_height"
+ android:layout_marginRight="@dimen/accessibility_floating_tooltip_arrow_margin"
+ android:visibility="gone"
+ android:layout_gravity="center_vertical"/>
+
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
@@ -35,9 +43,10 @@
android:textSize="@dimen/accessibility_floating_tooltip_font_size"/>
<View
- android:id="@+id/arrow"
+ android:id="@+id/arrow_right"
android:layout_width="@dimen/accessibility_floating_tooltip_arrow_width"
android:layout_height="@dimen/accessibility_floating_tooltip_arrow_height"
android:layout_marginLeft="@dimen/accessibility_floating_tooltip_arrow_margin"
+ android:visibility="gone"
android:layout_gravity="center_vertical"/>
</LinearLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index 7f183798709c..bf09975bb034 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -73,7 +73,8 @@ public final class Prefs {
Key.TOUCHED_RINGER_TOGGLE,
Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP,
Key.HAS_SEEN_REVERSE_BOTTOM_SHEET,
- Key.CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT
+ Key.CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT,
+ Key.HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP
})
// TODO: annotate these with their types so {@link PrefsCommandLine} can know how to set them
public @interface Key {
@@ -122,6 +123,8 @@ public final class Prefs {
String HAS_SEEN_ODI_CAPTIONS_TOOLTIP = "HasSeenODICaptionsTooltip";
String HAS_SEEN_REVERSE_BOTTOM_SHEET = "HasSeenReverseBottomSheet";
String CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT = "ControlsStructureSwipeTooltipCount";
+ String HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP =
+ "HasSeenAccessibilityFloatingMenuDockTooltip";
}
public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
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 fd10684e6fca..ee6276813512 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
@@ -24,6 +24,7 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_FLOATING_MENU_SIZE;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON;
import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
+import static com.android.systemui.Prefs.Key.HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP;
import static com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuView.ShapeType;
import static com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuView.SizeType;
@@ -35,6 +36,7 @@ import android.os.UserHandle;
import android.provider.Settings;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.Prefs;
/**
* Contains logic for an accessibility floating menu view.
@@ -46,6 +48,7 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu {
private final Context mContext;
private final AccessibilityFloatingMenuView mMenuView;
private final MigrationTooltipView mMigrationTooltipView;
+ private final DockTooltipView mDockTooltipView;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final ContentObserver mContentObserver =
@@ -90,6 +93,7 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu {
mContext = context;
mMenuView = menuView;
mMigrationTooltipView = new MigrationTooltipView(mContext, mMenuView);
+ mDockTooltipView = new DockTooltipView(mContext, mMenuView);
}
@Override
@@ -109,6 +113,7 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu {
getOpacityValue(mContext));
mMenuView.setSizeType(getSizeType(mContext));
mMenuView.setShapeType(getShapeType(mContext));
+ mMenuView.setOnDragEndListener(this::showDockTooltipIfNecessary);
showMigrationTooltipIfNecessary();
@@ -123,6 +128,7 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu {
mMenuView.hide();
mMigrationTooltipView.hide();
+ mDockTooltipView.hide();
unregisterContentObservers();
}
@@ -144,6 +150,21 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu {
DEFAULT_MIGRATION_TOOLTIP_PROMPT_IS_DISABLED) == /* enabled */ 1;
}
+ /**
+ * Shows tooltip when user drags accessibility floating menu for the first time.
+ */
+ private void showDockTooltipIfNecessary() {
+ if (!Prefs.get(mContext).getBoolean(
+ HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP, false)) {
+ // if the menu is an oval, the user has already dragged it out, so show the tooltip.
+ if (mMenuView.isOvalShape()) {
+ mDockTooltipView.show();
+ }
+
+ Prefs.putBoolean(mContext, HAS_SEEN_ACCESSIBILITY_FLOATING_MENU_DOCK_TOOLTIP, true);
+ }
+ }
+
private static boolean isFadeEffectEnabled(Context context) {
return Settings.Secure.getInt(
context.getContentResolver(), ACCESSIBILITY_FLOATING_MENU_FADE_ENABLED,
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 96a4a2aa91ba..49e6b47b3b79 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -19,6 +19,8 @@ package com.android.systemui.accessibility.floatingmenu;
import static android.util.MathUtils.constrain;
import static android.util.MathUtils.sq;
+import static java.util.Objects.requireNonNull;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -43,7 +45,9 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
+import android.view.animation.Animation;
import android.view.animation.OvershootInterpolator;
+import android.view.animation.TranslateAnimation;
import android.widget.FrameLayout;
import androidx.annotation.DimenRes;
@@ -60,6 +64,7 @@ import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Optional;
/**
* Accessibility floating menu is used for the actions of accessibility features, it's also the
@@ -78,6 +83,10 @@ public class AccessibilityFloatingMenuView extends FrameLayout
private static final int MIN_WINDOW_Y = 0;
private static final float LOCATION_Y_PERCENTAGE = 0.8f;
+ private static final int ANIMATION_START_OFFSET = 600;
+ private static final int ANIMATION_DURATION_MS = 600;
+ private static final float ANIMATION_TO_X_VALUE = 0.5f;
+
private boolean mIsFadeEffectEnabled;
private boolean mIsShowing;
private boolean mIsDownInEnlargedTouchArea;
@@ -107,6 +116,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout
private float mPercentageY = LOCATION_Y_PERCENTAGE;
private float mSquareScaledTouchSlop;
private final Configuration mLastConfiguration;
+ private Optional<OnDragEndListener> mOnDragEndListener = Optional.empty();
private final RecyclerView mListView;
private final AccessibilityTargetAdapter mAdapter;
private float mFadeOutValue;
@@ -161,6 +171,17 @@ public class AccessibilityFloatingMenuView extends FrameLayout
int RIGHT = 1;
}
+ /**
+ * Interface for a callback to be invoked when the floating menu was dragging.
+ */
+ interface OnDragEndListener {
+
+ /**
+ * Invoked when the floating menu has dragged end.
+ */
+ void onDragEnd();
+ }
+
public AccessibilityFloatingMenuView(Context context) {
this(context, new RecyclerView(context));
}
@@ -201,6 +222,8 @@ public class AccessibilityFloatingMenuView extends FrameLayout
updateRadiusWith(mSizeType, mRadiusType, mTargets.size());
fadeOut();
+
+ mOnDragEndListener.ifPresent(OnDragEndListener::onDragEnd);
}
});
@@ -266,7 +289,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout
// 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) {
+ if (!isOvalShape()) {
setShapeType(ShapeType.OVAL);
return true;
@@ -363,6 +386,10 @@ public class AccessibilityFloatingMenuView extends FrameLayout
return mIsShowing;
}
+ boolean isOvalShape() {
+ return mShapeType == ShapeType.OVAL;
+ }
+
void onTargetsChanged(List<AccessibilityTarget> newTargets) {
fadeIn();
@@ -407,6 +434,35 @@ public class AccessibilityFloatingMenuView extends FrameLayout
fadeOut();
}
+ public void setOnDragEndListener(OnDragEndListener onDragListener) {
+ mOnDragEndListener = Optional.ofNullable(onDragListener);
+ }
+
+ void startTranslateXAnimation() {
+ fadeIn();
+
+ final float toXValue = mAlignment == Alignment.RIGHT
+ ? ANIMATION_TO_X_VALUE
+ : -ANIMATION_TO_X_VALUE;
+ final TranslateAnimation animation =
+ new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0,
+ Animation.RELATIVE_TO_SELF, toXValue,
+ Animation.RELATIVE_TO_SELF, 0,
+ Animation.RELATIVE_TO_SELF, 0);
+ animation.setDuration(ANIMATION_DURATION_MS);
+ animation.setRepeatMode(Animation.REVERSE);
+ animation.setInterpolator(new OvershootInterpolator());
+ animation.setRepeatCount(Animation.INFINITE);
+ animation.setStartOffset(ANIMATION_START_OFFSET);
+ mListView.startAnimation(animation);
+ }
+
+ void stopTranslateXAnimation() {
+ mListView.clearAnimation();
+
+ fadeOut();
+ }
+
Rect getWindowLocationOnScreen() {
final int left = mCurrentLayoutParams.x;
final int top = mCurrentLayoutParams.y;
@@ -536,11 +592,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout
}
private Handler createUiHandler() {
- final Looper looper = Looper.myLooper();
- if (looper == null) {
- throw new IllegalArgumentException("looper must not be null");
- }
- return new Handler(looper);
+ return new Handler(requireNonNull(Looper.myLooper(), "looper must not be null"));
}
private void updateDimensions() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java
index a5d5f1267eaa..1abf559d6846 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipView.java
@@ -66,7 +66,6 @@ class BaseTooltipView extends FrameLayout {
private int mArrowCornerRadius;
private int mScreenWidth;
private boolean mIsShowing;
- private View mArrowView;
private TextView mTextView;
private final WindowManager.LayoutParams mCurrentLayoutParams;
private final WindowManager mWindowManager;
@@ -87,12 +86,11 @@ class BaseTooltipView extends FrameLayout {
super.onConfigurationChanged(newConfig);
updateDimensions();
-
updateTextView();
- updateArrow();
mAnchorView.onConfigurationChanged(newConfig);
final Rect anchorViewLocation = mAnchorView.getWindowLocationOnScreen();
+ updateArrowWith(anchorViewLocation);
updateWidthWith(anchorViewLocation);
updateLocationWith(anchorViewLocation);
@@ -132,6 +130,7 @@ class BaseTooltipView extends FrameLayout {
mIsShowing = true;
final Rect anchorViewLocation = mAnchorView.getWindowLocationOnScreen();
+ updateArrowWith(anchorViewLocation);
updateWidthWith(anchorViewLocation);
updateLocationWith(anchorViewLocation);
@@ -164,9 +163,6 @@ class BaseTooltipView extends FrameLayout {
LayoutInflater.from(getContext()).inflate(
R.layout.accessibility_floating_menu_tooltip, this, false);
- mArrowView = contentView.findViewById(R.id.arrow);
- drawArrow(mArrowView);
-
mTextView = contentView.findViewById(R.id.text);
addView(contentView);
@@ -220,17 +216,23 @@ class BaseTooltipView extends FrameLayout {
gradientDrawable.setCornerRadius(mTextViewCornerRadius);
}
- private void updateArrow() {
- final ShapeDrawable shapeDrawable = (ShapeDrawable) mArrowView.getBackground();
- final Paint paint = shapeDrawable.getPaint();
- paint.setPathEffect(new CornerPathEffect(mArrowCornerRadius));
+ private void updateArrowWith(Rect anchorViewLocation) {
+ final boolean isAnchorViewOnLeft = isAnchorViewOnLeft(anchorViewLocation);
+ final View arrowView = findViewById(isAnchorViewOnLeft
+ ? R.id.arrow_left
+ : R.id.arrow_right);
+ arrowView.setVisibility(VISIBLE);
+ drawArrow(arrowView, isAnchorViewOnLeft);
final LinearLayout.LayoutParams layoutParams =
- (LinearLayout.LayoutParams) mArrowView.getLayoutParams();
+ (LinearLayout.LayoutParams) arrowView.getLayoutParams();
layoutParams.width = mArrowWidth;
layoutParams.height = mArrowHeight;
- layoutParams.setMargins(mArrowMargin, 0, 0, 0);
- mArrowView.setLayoutParams(layoutParams);
+
+ final int leftMargin = isAnchorViewOnLeft ? 0 : mArrowMargin;
+ final int rightMargin = isAnchorViewOnLeft ? mArrowMargin : 0;
+ layoutParams.setMargins(leftMargin, 0, rightMargin, 0);
+ arrowView.setLayoutParams(layoutParams);
}
private void updateWidthWith(Rect anchorViewLocation) {
@@ -240,17 +242,19 @@ class BaseTooltipView extends FrameLayout {
}
private void updateLocationWith(Rect anchorViewLocation) {
- mCurrentLayoutParams.x =
- mScreenWidth - getWindowWidthWith(anchorViewLocation) - anchorViewLocation.width();
+ mCurrentLayoutParams.x = isAnchorViewOnLeft(anchorViewLocation)
+ ? anchorViewLocation.width()
+ : mScreenWidth - getWindowWidthWith(anchorViewLocation)
+ - anchorViewLocation.width();
mCurrentLayoutParams.y =
anchorViewLocation.centerY() - (getTextHeightWith(anchorViewLocation) / 2);
}
- private void drawArrow(View view) {
+ private void drawArrow(View view, boolean isPointingLeft) {
final ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
final TriangleShape triangleShape =
- TriangleShape.createHorizontal(layoutParams.width, layoutParams.height,
- false);
+ TriangleShape.createHorizontal(layoutParams.width, layoutParams.height,
+ isPointingLeft);
final ShapeDrawable arrowDrawable = new ShapeDrawable(triangleShape);
final Paint arrowPaint = arrowDrawable.getPaint();
arrowPaint.setColor(Utils.getColorAttrDefaultColor(getContext(),
@@ -260,6 +264,10 @@ class BaseTooltipView extends FrameLayout {
view.setBackground(arrowDrawable);
}
+ private boolean isAnchorViewOnLeft(Rect anchorViewLocation) {
+ return anchorViewLocation.left < (mScreenWidth / 2);
+ }
+
private int getTextWidthWith(Rect anchorViewLocation) {
final int widthSpec =
MeasureSpec.makeMeasureSpec(getAvailableTextWidthWith(anchorViewLocation), AT_MOST);
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DockTooltipView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DockTooltipView.java
new file mode 100644
index 000000000000..49056a6039ec
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/DockTooltipView.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.floatingmenu;
+
+import android.content.Context;
+
+import com.android.systemui.R;
+
+/**
+ * Dock tooltip view that shows the info about moving the Accessibility button to the edge to hide.
+ */
+class DockTooltipView extends BaseTooltipView {
+ private final AccessibilityFloatingMenuView mAnchorView;
+
+ DockTooltipView(Context context, AccessibilityFloatingMenuView anchorView) {
+ super(context, anchorView);
+ mAnchorView = anchorView;
+
+ setDescription(
+ getContext().getText(R.string.accessibility_floating_button_docking_tooltip));
+ }
+
+ @Override
+ void hide() {
+ super.hide();
+
+ mAnchorView.stopTranslateXAnimation();
+ }
+
+ @Override
+ void show() {
+ super.show();
+
+ mAnchorView.startTranslateXAnimation();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MigrationTooltipView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MigrationTooltipView.java
index 3829330f5235..e4f3e3145998 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MigrationTooltipView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MigrationTooltipView.java
@@ -37,6 +37,7 @@ class MigrationTooltipView extends BaseTooltipView {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Intent.EXTRA_COMPONENT_NAME,
ACCESSIBILITY_BUTTON_COMPONENT_NAME.flattenToShortString());
+
final AnnotationLinkSpan.LinkInfo linkInfo = new AnnotationLinkSpan.LinkInfo(
AnnotationLinkSpan.LinkInfo.DEFAULT_ANNOTATION,
v -> {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DockTooltipViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DockTooltipViewTest.java
new file mode 100644
index 000000000000..41b948fb80b0
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DockTooltipViewTest.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.floatingmenu;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+import android.view.MotionEvent;
+import android.view.WindowManager;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.systemui.SysuiTestCase;
+import com.android.systemui.accessibility.MotionEventHelper;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/** Tests for {@link DockTooltipView}. */
+@SmallTest
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class DockTooltipViewTest extends SysuiTestCase {
+
+ @Mock
+ private WindowManager mWindowManager;
+
+ private AccessibilityFloatingMenuView mMenuView;
+ private DockTooltipView mDockTooltipView;
+ private final MotionEventHelper mMotionEventHelper = new MotionEventHelper();
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ final WindowManager wm = mContext.getSystemService(WindowManager.class);
+ doAnswer(invocation -> wm.getMaximumWindowMetrics()).when(
+ mWindowManager).getMaximumWindowMetrics();
+ mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager);
+
+ mMenuView = spy(new AccessibilityFloatingMenuView(mContext));
+ mDockTooltipView = new DockTooltipView(mContext, mMenuView);
+ }
+
+ @Test
+ public void showTooltip_success() {
+ mDockTooltipView.show();
+
+ verify(mMenuView).startTranslateXAnimation();
+ verify(mWindowManager).addView(eq(mDockTooltipView), any(WindowManager.LayoutParams.class));
+ }
+
+ @Test
+ public void hideTooltip_success() {
+ mDockTooltipView.show();
+ mDockTooltipView.hide();
+
+ verify(mMenuView).stopTranslateXAnimation();
+ verify(mWindowManager).removeView(mDockTooltipView);
+ }
+
+ @Test
+ public void touchOutsideWhenToolTipViewShown_stopAnimation() {
+ final MotionEvent outsideEvent =
+ mMotionEventHelper.obtainMotionEvent(/* downTime= */ 0,
+ /* eventTime= */ 1,
+ MotionEvent.ACTION_OUTSIDE,
+ /* x= */ 0,
+ /* y= */ 0);
+
+ mDockTooltipView.show();
+ mDockTooltipView.dispatchTouchEvent(outsideEvent);
+
+ verify(mMenuView).stopTranslateXAnimation();
+ }
+
+ @After
+ public void tearDown() {
+ mMotionEventHelper.recycleEvents();
+ }
+}