summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Peter_Liang <peterliang@google.com> 2021-01-19 14:39:01 +0800
committer Peter_Liang <peterliang@google.com> 2021-03-19 11:35:09 +0800
commit1b38ff82bcec4d8dc7ba7159f9ed76762f53aa18 (patch)
tree92354f9364caa00193f672140535d8a87ead8783
parentcd10a1bc49d10401135b27570bda0d240dda48de (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
-rw-r--r--packages/SystemUI/res/drawable/accessibility_floating_menu_background.xml4
-rw-r--r--packages/SystemUI/res/layout/accessibility_floating_menu_item.xml7
-rw-r--r--packages/SystemUI/res/values/dimens.xml9
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java61
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java202
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java88
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java54
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java85
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);
+ }
+}