diff options
| author | 2021-01-19 14:39:01 +0800 | |
|---|---|---|
| committer | 2021-03-19 11:35:09 +0800 | |
| commit | 1b38ff82bcec4d8dc7ba7159f9ed76762f53aa18 (patch) | |
| tree | 92354f9364caa00193f672140535d8a87ead8783 | |
| parent | cd10a1bc49d10401135b27570bda0d240dda48de (diff) | |
Add new floating action menu for Accessibility targets. (2/n)
Patch action:
1. Update the style depends on the settings icon and size key.
2. Under half circle shape mode, the menu will enlarge touch area.
Cherry picked from commit c26ac8c638f5cf7235d9fb18b374479d93fa99e3
Bug: 173958541
Test: atest AccessibilityFloatingMenuTest AccessibilityFloatingMenuViewTest AccessibilityTargetAdapterTest
Change-Id: Iec53ef71d7e0abe5c7619d4e5f67862ca56dfd1f
Merged-In: Iec53ef71d7e0abe5c7619d4e5f67862ca56dfd1f
9 files changed, 456 insertions, 59 deletions
diff --git a/packages/SystemUI/res/drawable/accessibility_floating_menu_background.xml b/packages/SystemUI/res/drawable/accessibility_floating_menu_background.xml index 675d36f83093..ef67e512d95d 100644 --- a/packages/SystemUI/res/drawable/accessibility_floating_menu_background.xml +++ b/packages/SystemUI/res/drawable/accessibility_floating_menu_background.xml @@ -21,9 +21,9 @@ <item android:id="@+id/menu_background_item"> <shape android:shape="rectangle"> <corners - android:bottomLeftRadius="@dimen/accessibility_floating_menu_single_radius" + android:bottomLeftRadius="@dimen/accessibility_floating_menu_small_single_radius" android:bottomRightRadius="0dp" - android:topLeftRadius="@dimen/accessibility_floating_menu_single_radius" + android:topLeftRadius="@dimen/accessibility_floating_menu_small_single_radius" android:topRightRadius="0dp"/> <solid android:color="@color/accessibility_floating_menu_background"/> diff --git a/packages/SystemUI/res/layout/accessibility_floating_menu_item.xml b/packages/SystemUI/res/layout/accessibility_floating_menu_item.xml index 376b29d2f369..f7357b27af5f 100644 --- a/packages/SystemUI/res/layout/accessibility_floating_menu_item.xml +++ b/packages/SystemUI/res/layout/accessibility_floating_menu_item.xml @@ -19,14 +19,15 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" - android:padding="@dimen/accessibility_floating_menu_padding" + android:paddingStart="@dimen/accessibility_floating_menu_padding" + android:paddingEnd="@dimen/accessibility_floating_menu_padding" android:orientation="vertical" android:gravity="center"> <View android:id="@+id/icon_view" - android:layout_width="@dimen/accessibility_floating_menu_width_height" - android:layout_height="@dimen/accessibility_floating_menu_width_height"/> + android:layout_width="@dimen/accessibility_floating_menu_small_width_height" + android:layout_height="@dimen/accessibility_floating_menu_small_width_height"/> <View android:id="@+id/transparent_divider" diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 033e606d77d8..b050945068f2 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1362,9 +1362,12 @@ <dimen name="accessibility_floating_menu_stroke_inset">-2dp</dimen> <dimen name="accessibility_floating_menu_margin">16dp</dimen> <dimen name="accessibility_floating_menu_padding">6dp</dimen> - <dimen name="accessibility_floating_menu_width_height">36dp</dimen> - <dimen name="accessibility_floating_menu_single_radius">25dp</dimen> - <dimen name="accessibility_floating_menu_multiple_radius">20dp</dimen> + <dimen name="accessibility_floating_menu_small_width_height">36dp</dimen> + <dimen name="accessibility_floating_menu_small_single_radius">25dp</dimen> + <dimen name="accessibility_floating_menu_small_multiple_radius">20dp</dimen> + <dimen name="accessibility_floating_menu_large_width_height">56dp</dimen> + <dimen name="accessibility_floating_menu_large_single_radius">33dp</dimen> + <dimen name="accessibility_floating_menu_large_multiple_radius">35dp</dimen> <dimen name="rounded_slider_height">44dp</dimen> <!-- rounded_slider_height / 2 --> 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 f5356c1e48eb..b25a76a59ba8 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java @@ -16,9 +16,13 @@ package com.android.systemui.accessibility.floatingmenu; +import static android.provider.Settings.Secure.ACCESSIBILITY_FLOATING_MENU_ICON_TYPE; +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.accessibility.floatingmenu.AccessibilityFloatingMenuView.ShapeType; +import static com.android.systemui.accessibility.floatingmenu.AccessibilityFloatingMenuView.SizeType; import android.content.Context; import android.database.ContentObserver; @@ -44,6 +48,22 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu { } }; + private final ContentObserver mSizeContentObserver = + new ContentObserver(new Handler(Looper.getMainLooper())) { + @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)); + } + }; + public AccessibilityFloatingMenu(Context context) { mContext = context; mMenuView = new AccessibilityFloatingMenuView(context); @@ -66,13 +86,12 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu { return; } - mMenuView.onTargetsChanged(getTargets(mContext, ACCESSIBILITY_BUTTON)); mMenuView.show(); + mMenuView.onTargetsChanged(getTargets(mContext, ACCESSIBILITY_BUTTON)); + mMenuView.setSizeType(getSizeType(mContext)); + mMenuView.setShapeType(getShapeType(mContext)); - mContext.getContentResolver().registerContentObserver( - Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS), - /* notifyForDescendants */ false, mContentObserver, - UserHandle.USER_CURRENT); + registerContentObservers(); } @Override @@ -83,6 +102,38 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu { mMenuView.hide(); + unregisterContentObservers(); + } + + private static int getSizeType(Context context) { + return Settings.Secure.getInt( + context.getContentResolver(), ACCESSIBILITY_FLOATING_MENU_SIZE, SizeType.SMALL); + } + + private static int getShapeType(Context context) { + return Settings.Secure.getInt( + context.getContentResolver(), ACCESSIBILITY_FLOATING_MENU_ICON_TYPE, + ShapeType.CIRCLE); + } + + private void registerContentObservers() { + mContext.getContentResolver().registerContentObserver( + Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_BUTTON_TARGETS), + /* notifyForDescendants */ false, mContentObserver, + UserHandle.USER_CURRENT); + mContext.getContentResolver().registerContentObserver( + 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); + } + + private void unregisterContentObservers() { mContext.getContentResolver().unregisterContentObserver(mContentObserver); + mContext.getContentResolver().unregisterContentObserver(mSizeContentObserver); + mContext.getContentResolver().unregisterContentObserver(mShapeContentObserver); } } 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 b393a892e9b7..9f147ee93617 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java @@ -16,15 +16,18 @@ package com.android.systemui.accessibility.floatingmenu; +import android.annotation.IntDef; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.PixelFormat; +import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; import android.util.DisplayMetrics; import android.view.Gravity; +import android.view.MotionEvent; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.FrameLayout; @@ -34,8 +37,11 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.android.internal.accessibility.dialog.AccessibilityTarget; +import com.android.internal.annotations.VisibleForTesting; import com.android.systemui.R; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; @@ -50,21 +56,59 @@ public class AccessibilityFloatingMenuView extends FrameLayout { private static final float DEFAULT_LOCATION_Y_PERCENTAGE = 0.8f; private static final int INDEX_MENU_ITEM = 0; private boolean mIsShowing; - private RecyclerView mListView; + @SizeType + private int mSizeType = SizeType.SMALL; + private int mMargin; + private int mPadding; + private int mScreenHeight; + private int mScreenWidth; + private int mIconWidth; + private int mIconHeight; + private final RecyclerView mListView; + private final AccessibilityTargetAdapter mAdapter; private final WindowManager.LayoutParams mLayoutParams; private final WindowManager mWindowManager; - private final AccessibilityTargetAdapter mAdapter; private final List<AccessibilityTarget> mTargets = new ArrayList<>(); + @IntDef({ + SizeType.SMALL, + SizeType.LARGE + }) + @Retention(RetentionPolicy.SOURCE) + @interface SizeType { + int SMALL = 0; + int LARGE = 1; + } + + @IntDef({ + ShapeType.CIRCLE, + ShapeType.HALF_CIRCLE + }) + @Retention(RetentionPolicy.SOURCE) + @interface ShapeType { + int CIRCLE = 0; + int HALF_CIRCLE = 1; + } + public AccessibilityFloatingMenuView(Context context) { + this(context, new RecyclerView(context)); + } + + @VisibleForTesting + AccessibilityFloatingMenuView(Context context, + RecyclerView listView) { super(context); + mListView = listView; mWindowManager = context.getSystemService(WindowManager.class); mLayoutParams = createDefaultLayoutParams(); mAdapter = new AccessibilityTargetAdapter(mTargets); - initListView(context, mAdapter); - updateStroke(); + updateDimensions(); + initListView(); + + final int uiMode = context.getResources().getConfiguration().uiMode; + updateStrokeWith(uiMode); } void show() { @@ -94,41 +138,100 @@ public class AccessibilityFloatingMenuView extends FrameLayout { mTargets.addAll(newTargets); mAdapter.notifyDataSetChanged(); - final boolean hasMoreItems = mAdapter.getItemCount() > 1; - final int resId = hasMoreItems - ? R.dimen.accessibility_floating_menu_multiple_radius - : R.dimen.accessibility_floating_menu_single_radius; - setRadius(resId); + updateRadiusWith(mSizeType, mTargets.size()); + } + + void setSizeType(@SizeType int newSizeType) { + mSizeType = newSizeType; + + updateIconSizeWith(newSizeType); + updateRadiusWith(newSizeType, mTargets.size()); + + // When the icon sized changed, the menu size and location will be impacted. + updateLocation(); + } + + void setShapeType(@ShapeType int newShapeType) { + final boolean isCircleShape = + newShapeType == ShapeType.CIRCLE; + final float offset = + isCircleShape + ? 0 + : getLayoutWidth() / 2.0f; + mListView.animate().translationX(offset); + + setOnTouchListener( + isCircleShape + ? null + : (view, event) -> onTouched(event)); + } + + private boolean onTouched(MotionEvent event) { + final int currentX = (int) event.getX(); + final int currentY = (int) event.getY(); + + final int menuHalfWidth = getLayoutWidth() / 2; + final Rect touchDelegateBounds = + new Rect(mMargin, mMargin, mMargin + menuHalfWidth, mMargin + getLayoutHeight()); + if (touchDelegateBounds.contains(currentX, currentY)) { + // In order to correspond to the correct item of list view. + event.setLocation(currentX - mMargin, currentY - mMargin); + return mListView.dispatchTouchEvent(event); + } + + return false; } - private void setRadius(@DimenRes int radiusResId) { - final float radius = getResources().getDimension(radiusResId); + private void setRadius(float radius) { final float[] radii = new float[]{radius, radius, 0.0f, 0.0f, 0.0f, 0.0f, radius, radius}; getMenuGradientDrawable().setCornerRadii(radii); } - private void initListView(Context context, AccessibilityTargetAdapter adapter) { - final Resources res = context.getResources(); - final int margin = + private void updateDimensions() { + final Resources res = getResources(); + final DisplayMetrics dm = res.getDisplayMetrics(); + mScreenWidth = dm.widthPixels; + mScreenHeight = dm.heightPixels; + mMargin = res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_margin); - final int elevation = - res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_elevation); + mPadding = + res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_padding); + } + + private void updateIconSizeWith(@SizeType int sizeType) { + final Resources res = getResources(); + final int iconResId = + sizeType == SizeType.SMALL + ? R.dimen.accessibility_floating_menu_small_width_height + : R.dimen.accessibility_floating_menu_large_width_height; + mIconWidth = res.getDimensionPixelSize(iconResId); + mIconHeight = mIconWidth; + + mAdapter.setIconWidthHeight(mIconWidth); + mAdapter.notifyDataSetChanged(); + } + + private void initListView() { final Drawable listViewBackground = - context.getDrawable(R.drawable.accessibility_floating_menu_background); + getContext().getDrawable(R.drawable.accessibility_floating_menu_background); + final LinearLayoutManager layoutManager = new LinearLayoutManager(getContext()); + mListView.setBackground(listViewBackground); + mListView.setAdapter(mAdapter); + mListView.setLayoutManager(layoutManager); + updateListView(); + + addView(mListView); + } - mListView = new RecyclerView(context); - final LinearLayoutManager layoutManager = new LinearLayoutManager(context); + private void updateListView() { + final int elevation = + getResources().getDimensionPixelSize(R.dimen.accessibility_floating_menu_elevation); final LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - layoutParams.setMarginsRelative(margin, margin, /* end= */ 0, margin); + layoutParams.setMarginsRelative(mMargin, mMargin, /* end= */ 0, mMargin); mListView.setLayoutParams(layoutParams); mListView.setElevation(elevation); - mListView.setBackground(listViewBackground); - mListView.setAdapter(adapter); - mListView.setLayoutManager(layoutManager); - - addView(mListView); } private WindowManager.LayoutParams createDefaultLayoutParams() { @@ -150,9 +253,12 @@ public class AccessibilityFloatingMenuView extends FrameLayout { protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - updateLocation(); + updateDimensions(); + updateListView(); + updateIconSizeWith(mSizeType); updateColor(); - updateStroke(); + updateStrokeWith(newConfig.uiMode); + updateLocation(); } private LayerDrawable getMenuLayerDrawable() { @@ -163,10 +269,12 @@ public class AccessibilityFloatingMenuView extends FrameLayout { return (GradientDrawable) getMenuLayerDrawable().getDrawable(INDEX_MENU_ITEM); } + /** + * Updates the floating menu to be fixed at the side of the screen. + */ private void updateLocation() { - final DisplayMetrics dm = getResources().getDisplayMetrics(); - mLayoutParams.x = dm.widthPixels; - mLayoutParams.y = (int) (dm.heightPixels * DEFAULT_LOCATION_Y_PERCENTAGE); + mLayoutParams.x = mScreenWidth - mMargin - getLayoutWidth(); + mLayoutParams.y = (int) (mScreenHeight * DEFAULT_LOCATION_Y_PERCENTAGE); mWindowManager.updateViewLayout(this, mLayoutParams); } @@ -175,10 +283,10 @@ public class AccessibilityFloatingMenuView extends FrameLayout { getMenuGradientDrawable().setColor(getResources().getColor(menuColorResId)); } - private void updateStroke() { + private void updateStrokeWith(int uiMode) { final Resources res = getResources(); final boolean isNightMode = - (res.getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) + (uiMode & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES; final int inset = @@ -192,4 +300,34 @@ public class AccessibilityFloatingMenuView extends FrameLayout { final int strokeColor = res.getColor(R.color.accessibility_floating_menu_stroke_dark); getMenuGradientDrawable().setStroke(strokeWidth, strokeColor); } + + private void updateRadiusWith(@SizeType int sizeType, int itemCount) { + setRadius(getResources().getDimensionPixelSize(getRadiusResId(sizeType, itemCount))); + } + + private @DimenRes int getRadiusResId(@SizeType int sizeType, int itemCount) { + return sizeType == SizeType.SMALL + ? getSmallSizeResIdWith(itemCount) + : getLargeSizeResIdWith(itemCount); + } + + private int getSmallSizeResIdWith(int itemCount) { + return itemCount > 1 + ? R.dimen.accessibility_floating_menu_small_multiple_radius + : R.dimen.accessibility_floating_menu_small_single_radius; + } + + private int getLargeSizeResIdWith(int itemCount) { + return itemCount > 1 + ? R.dimen.accessibility_floating_menu_large_multiple_radius + : R.dimen.accessibility_floating_menu_large_single_radius; + } + + private int getLayoutWidth() { + return mPadding * 2 + mIconWidth; + } + + private int getLayoutHeight() { + return (mPadding + mIconHeight) * mTargets.size() + mPadding; + } } diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java index 8b586c54034d..bb4038e92ff4 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java @@ -16,10 +16,17 @@ package com.android.systemui.accessibility.floatingmenu; +import static android.view.View.GONE; + +import static com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ItemType.FIRST_ITEM; +import static com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ItemType.LAST_ITEM; +import static com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ItemType.REGULAR_ITEM; + import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView.Adapter; @@ -28,40 +35,70 @@ import com.android.internal.accessibility.dialog.AccessibilityTarget; import com.android.systemui.R; import com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ViewHolder; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.List; /** * An adapter which shows the set of accessibility targets that can be performed. */ public class AccessibilityTargetAdapter extends Adapter<ViewHolder> { - + private int mIconWidthHeight; private final List<AccessibilityTarget> mTargets; + + @IntDef({ + FIRST_ITEM, + REGULAR_ITEM, + LAST_ITEM + }) + @Retention(RetentionPolicy.SOURCE) + @interface ItemType { + int FIRST_ITEM = 0; + int REGULAR_ITEM = 1; + int LAST_ITEM = 2; + } + public AccessibilityTargetAdapter(List<AccessibilityTarget> targets) { mTargets = targets; } @NonNull @Override - public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int i) { + public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, @ItemType int itemType) { final View root = LayoutInflater.from(parent.getContext()).inflate( R.layout.accessibility_floating_menu_item, parent, /* attachToRoot= */ false); + if (itemType == FIRST_ITEM) { + return new TopViewHolder(root); + } + + if (itemType == LAST_ITEM) { + return new BottomViewHolder(root); + } + return new ViewHolder(root); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.mIconView.setBackground(mTargets.get(position).getIcon()); - - final boolean isFirstItem = (position == 0); - final boolean isLastItem = (position == (getItemCount() - 1)); - final int padding = holder.itemView.getPaddingStart(); - final int paddingTop = isFirstItem ? padding : 0; - final int paddingBottom = isLastItem ? padding : 0; - holder.itemView.setPaddingRelative(padding, paddingTop, padding, paddingBottom); + holder.updateIconWidthHeight(mIconWidthHeight); holder.itemView.setOnClickListener((v) -> mTargets.get(position).onSelected()); - holder.mDivider.setVisibility(isLastItem ? View.GONE : View.VISIBLE); + } + + @ItemType + @Override + public int getItemViewType(int position) { + if (position == 0) { + return FIRST_ITEM; + } + + if (position == (getItemCount() - 1)) { + return LAST_ITEM; + } + + return REGULAR_ITEM; } @Override @@ -69,6 +106,10 @@ public class AccessibilityTargetAdapter extends Adapter<ViewHolder> { return mTargets.size(); } + public void setIconWidthHeight(int iconWidthHeight) { + mIconWidthHeight = iconWidthHeight; + } + static class ViewHolder extends RecyclerView.ViewHolder { final View mIconView; final View mDivider; @@ -78,5 +119,32 @@ public class AccessibilityTargetAdapter extends Adapter<ViewHolder> { mIconView = itemView.findViewById(R.id.icon_view); mDivider = itemView.findViewById(R.id.transparent_divider); } + + void updateIconWidthHeight(int newValue) { + final ViewGroup.LayoutParams layoutParams = mIconView.getLayoutParams(); + if (layoutParams.width == newValue) { + return; + } + layoutParams.width = newValue; + layoutParams.height = newValue; + mIconView.setLayoutParams(layoutParams); + } + } + + static class TopViewHolder extends ViewHolder { + TopViewHolder(View itemView) { + super(itemView); + final int padding = itemView.getPaddingStart(); + itemView.setPaddingRelative(padding, padding, padding, 0); + } + } + + static class BottomViewHolder extends ViewHolder { + BottomViewHolder(View itemView) { + super(itemView); + mDivider.setVisibility(GONE); + final int padding = itemView.getPaddingStart(); + itemView.setPaddingRelative(padding, 0, padding, padding); + } } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuTest.java index 0489871578cf..337d97e1dc0b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuTest.java @@ -22,6 +22,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import android.content.Context; import android.testing.AndroidTestingRunner; @@ -30,6 +31,7 @@ import android.view.accessibility.AccessibilityManager; import androidx.test.filters.SmallTest; +import com.android.internal.accessibility.dialog.AccessibilityTarget; import com.android.systemui.SysuiTestCase; import org.junit.After; @@ -58,6 +60,9 @@ public class AccessibilityFloatingMenuTest extends SysuiTestCase { public void initMenu() { MockitoAnnotations.initMocks(this); + final List<AccessibilityTarget> mTargets = new ArrayList<>(); + mTargets.add(mock(AccessibilityTarget.class)); + final List<String> assignedTargets = new ArrayList<>(); mContext.addMockSystemService(Context.ACCESSIBILITY_SERVICE, mAccessibilityManager); assignedTargets.add(MAGNIFICATION_CONTROLLER_NAME); 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 583a68bcbbac..9ff697cc9957 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 @@ -16,23 +16,29 @@ package com.android.systemui.accessibility.floatingmenu; - import static com.google.common.truth.Truth.assertThat; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.content.Context; +import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; import android.view.View; +import android.view.ViewPropertyAnimator; import android.view.WindowManager; +import androidx.recyclerview.widget.RecyclerView; import androidx.test.filters.SmallTest; import com.android.internal.accessibility.dialog.AccessibilityTarget; @@ -51,12 +57,18 @@ import java.util.List; /** Tests for {@link AccessibilityFloatingMenuView}. */ @SmallTest @RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { private AccessibilityFloatingMenuView mMenuView; @Mock private WindowManager mWindowManager; + @Mock + private ViewPropertyAnimator mAnimator; + + private RecyclerView mListView; + private final List<AccessibilityTarget> mTargets = new ArrayList<>(); @Before @@ -69,6 +81,7 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); mTargets.add(mock(AccessibilityTarget.class)); + mListView = spy(new RecyclerView(mContext)); mMenuView = new AccessibilityFloatingMenuView(mContext); } @@ -117,10 +130,10 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { @Test public void updateListViewRadius_singleTarget_matchResult() { final float radius = - getContext().getResources().getDimension( - R.dimen.accessibility_floating_menu_single_radius); + getContext().getResources().getDimensionPixelSize( + R.dimen.accessibility_floating_menu_small_single_radius); final float[] expectedRadii = - new float[] {radius, radius, 0.0f, 0.0f, 0.0f, 0.0f, radius, radius}; + new float[]{radius, radius, 0.0f, 0.0f, 0.0f, 0.0f, radius, radius}; mMenuView.onTargetsChanged(mTargets); final View view = mMenuView.getChildAt(0); @@ -131,4 +144,37 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { assertThat(actualRadii).isEqualTo(expectedRadii); } + + @Test + public void setSizeType_largeSize_matchResult() { + final int shapeType = 2; + final float radius = getContext().getResources().getDimensionPixelSize( + R.dimen.accessibility_floating_menu_large_single_radius); + final float[] expectedRadii = + new float[]{radius, radius, 0.0f, 0.0f, 0.0f, 0.0f, radius, radius}; + final Drawable listViewBackground = + mContext.getDrawable(R.drawable.accessibility_floating_menu_background); + mListView = spy(new RecyclerView(mContext)); + mListView.setBackground(listViewBackground); + + mMenuView = new AccessibilityFloatingMenuView(mContext, mListView); + mMenuView.setSizeType(shapeType); + final LayerDrawable layerDrawable = + (LayerDrawable) mListView.getBackground(); + final GradientDrawable gradientDrawable = + (GradientDrawable) layerDrawable.getDrawable(0); + + assertThat(gradientDrawable.getCornerRadii()).isEqualTo(expectedRadii); + } + + @Test + public void setShapeType_halfCircle_translationX() { + final int shapeType = 2; + doReturn(mAnimator).when(mListView).animate(); + + mMenuView = new AccessibilityFloatingMenuView(mContext, mListView); + mMenuView.setShapeType(shapeType); + + verify(mAnimator).translationX(anyFloat()); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java new file mode 100644 index 000000000000..899625eee7d9 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java @@ -0,0 +1,85 @@ +/* + * 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 com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.when; + +import android.graphics.drawable.Drawable; +import android.testing.AndroidTestingRunner; +import android.view.LayoutInflater; +import android.view.View; + +import androidx.test.filters.SmallTest; + +import com.android.internal.accessibility.dialog.AccessibilityTarget; +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ViewHolder; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.util.ArrayList; +import java.util.List; + +/** Tests for {@link AccessibilityTargetAdapter}. */ +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class AccessibilityTargetAdapterTest extends SysuiTestCase { + @Mock + private AccessibilityTarget mAccessibilityTarget; + + @Mock + private Drawable mIcon; + + @Mock + private Drawable.ConstantState mConstantState; + + private ViewHolder mViewHolder; + private AccessibilityTargetAdapter mAdapter; + private final List<AccessibilityTarget> mTargets = new ArrayList<>(); + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mTargets.add(mAccessibilityTarget); + mAdapter = new AccessibilityTargetAdapter(mTargets); + + final View root = LayoutInflater.from(mContext).inflate( + R.layout.accessibility_floating_menu_item, null); + mViewHolder = new ViewHolder(root); + when(mAccessibilityTarget.getIcon()).thenReturn(mIcon); + when(mIcon.getConstantState()).thenReturn(mConstantState); + } + + @Test + public void onBindViewHolder_setIconWidthHeight_matchResult() { + final int iconWidthHeight = 50; + mAdapter.setIconWidthHeight(iconWidthHeight); + + mAdapter.onBindViewHolder(mViewHolder, 0); + final int actualIconWith = mViewHolder.mIconView.getLayoutParams().width; + + assertThat(actualIconWith).isEqualTo(iconWidthHeight); + } +} |