summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java15
-rw-r--r--core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java6
-rw-r--r--core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java6
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java27
8 files changed, 103 insertions, 11 deletions
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
index d84175ed1e7c..5b0abd389e7d 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
@@ -24,6 +24,7 @@ import static com.android.internal.accessibility.util.ShortcutUtils.optInValueTo
import static com.android.internal.accessibility.util.ShortcutUtils.optOutValueFromSettings;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.View;
@@ -33,6 +34,7 @@ import android.view.accessibility.AccessibilityManager.ShortcutType;
import com.android.internal.accessibility.common.ShortcutConstants;
import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
import com.android.internal.accessibility.dialog.TargetAdapter.ViewHolder;
+import com.android.internal.annotations.VisibleForTesting;
/**
* Abstract base class for creating various target related to accessibility service,
@@ -51,7 +53,8 @@ public abstract class AccessibilityTarget implements TargetOperations, OnTargetS
private Drawable mIcon;
private String mKey;
- AccessibilityTarget(Context context, @ShortcutType int shortcutType,
+ @VisibleForTesting
+ public AccessibilityTarget(Context context, @ShortcutType int shortcutType,
@AccessibilityFragmentType int fragmentType, boolean isShortcutSwitched, String id,
CharSequence label, Drawable icon, String key) {
mContext = context;
@@ -103,6 +106,16 @@ public abstract class AccessibilityTarget implements TargetOperations, OnTargetS
}
}
+ /**
+ * Gets the state description of this feature target.
+ *
+ * @return the state description
+ */
+ @Nullable
+ public CharSequence getStateDescription() {
+ return null;
+ }
+
public void setShortcutEnabled(boolean enabled) {
mShortcutEnabled = enabled;
}
diff --git a/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java b/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java
index 239e531dbfb8..469d10ff98aa 100644
--- a/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/ToggleAccessibilityServiceTarget.java
@@ -51,10 +51,14 @@ class ToggleAccessibilityServiceTarget extends AccessibilityServiceTarget {
final boolean isEditMenuMode =
shortcutMenuMode == ShortcutMenuMode.EDIT;
holder.mStatusView.setVisibility(isEditMenuMode ? View.GONE : View.VISIBLE);
+ holder.mStatusView.setText(getStateDescription());
+ }
+ @Override
+ public CharSequence getStateDescription() {
final int statusResId = isAccessibilityServiceEnabled(getContext(), getId())
? R.string.accessibility_shortcut_menu_item_status_on
: R.string.accessibility_shortcut_menu_item_status_off;
- holder.mStatusView.setText(getContext().getString(statusResId));
+ return getContext().getString(statusResId);
}
}
diff --git a/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java b/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java
index 38aac708de15..ebdaed6dbe39 100644
--- a/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/ToggleAllowListingFeatureTarget.java
@@ -48,11 +48,15 @@ class ToggleAllowListingFeatureTarget extends AccessibilityTarget {
final boolean isEditMenuMode =
shortcutMenuMode == ShortcutMenuMode.EDIT;
holder.mStatusView.setVisibility(isEditMenuMode ? View.GONE : View.VISIBLE);
+ holder.mStatusView.setText(getStateDescription());
+ }
+ @Override
+ public CharSequence getStateDescription() {
final int statusResId = isFeatureEnabled()
? R.string.accessibility_shortcut_menu_item_status_on
: R.string.accessibility_shortcut_menu_item_status_off;
- holder.mStatusView.setText(getContext().getString(statusResId));
+ return getContext().getString(statusResId);
}
private boolean isFeatureEnabled() {
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index c117069f794b..e7d886d1c550 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2727,6 +2727,8 @@
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half">Move to edge and hide</string>
<!-- Action in accessibility menu to move the accessibility floating button out the edge and show. [CHAR LIMIT=30]-->
<string name="accessibility_floating_button_action_move_out_edge_and_show">Move out edge and show</string>
+ <!-- Action in accessibility menu to toggle on/off the accessibility feature. [CHAR LIMIT=30]-->
+ <string name="accessibility_floating_button_action_double_tap_to_toggle">toggle</string>
<!-- Device Controls strings -->
<!-- Device Controls empty state, title [CHAR LIMIT=30] -->
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 7b4ce61d2cfe..3b3bad3b255f 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenu.java
@@ -70,9 +70,16 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu {
}
};
+ private final ContentObserver mEnabledA11yServicesContentObserver =
+ new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ mMenuView.onEnabledFeaturesChanged();
+ }
+ };
+
public AccessibilityFloatingMenu(Context context) {
- mContext = context;
- mMenuView = new AccessibilityFloatingMenuView(context);
+ this(context, new AccessibilityFloatingMenuView(context));
}
@VisibleForTesting
@@ -153,11 +160,17 @@ public class AccessibilityFloatingMenu implements IAccessibilityFloatingMenu {
Settings.Secure.getUriFor(Settings.Secure.ACCESSIBILITY_FLOATING_MENU_OPACITY),
/* notifyForDescendants */ false, mFadeOutContentObserver,
UserHandle.USER_CURRENT);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES),
+ /* notifyForDescendants */ false,
+ mEnabledA11yServicesContentObserver, UserHandle.USER_CURRENT);
}
private void unregisterContentObservers() {
mContext.getContentResolver().unregisterContentObserver(mContentObserver);
mContext.getContentResolver().unregisterContentObserver(mSizeContentObserver);
mContext.getContentResolver().unregisterContentObserver(mFadeOutContentObserver);
+ mContext.getContentResolver().unregisterContentObserver(
+ mEnabledA11yServicesContentObserver);
}
}
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 5502a20ce398..934e20dfbd05 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java
@@ -24,6 +24,7 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.content.Context;
+import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.PixelFormat;
@@ -105,6 +106,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout
private float mRadius;
private float mPercentageY = LOCATION_Y_PERCENTAGE;
private float mSquareScaledTouchSlop;
+ private final Configuration mLastConfiguration;
private final RecyclerView mListView;
private final AccessibilityTargetAdapter mAdapter;
private float mFadeOutValue;
@@ -202,6 +204,8 @@ public class AccessibilityFloatingMenuView extends FrameLayout
}
});
+ mLastConfiguration = new Configuration(getResources().getConfiguration());
+
updateDimensions();
initListView();
updateStrokeWith(getResources().getConfiguration().uiMode, mAlignment);
@@ -368,7 +372,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout
mTargets.clear();
mTargets.addAll(newTargets);
- mAdapter.notifyDataSetChanged();
+ onEnabledFeaturesChanged();
updateRadiusWith(mSizeType, mRadiusType, mTargets.size());
updateScrollModeWith(hasExceededMaxLayoutHeight());
@@ -416,6 +420,10 @@ public class AccessibilityFloatingMenuView extends FrameLayout
setAlpha(mIsFadeEffectEnabled ? mFadeOutValue : /* completely opaque */ 1.0f);
}
+ void onEnabledFeaturesChanged() {
+ mAdapter.notifyDataSetChanged();
+ }
+
@VisibleForTesting
void fadeIn() {
if (!mIsFadeEffectEnabled) {
@@ -601,13 +609,17 @@ public class AccessibilityFloatingMenuView extends FrameLayout
params.gravity = Gravity.START | Gravity.TOP;
params.x = getMaxWindowX();
params.y = (int) (getMaxWindowY() * mPercentageY);
-
+ updateAccessibilityTitle(params);
return params;
}
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
+ final int diff = newConfig.diff(mLastConfiguration);
+ if ((diff & ActivityInfo.CONFIG_LOCALE) != 0) {
+ updateAccessibilityTitle(mCurrentLayoutParams);
+ }
updateDimensions();
updateListView();
@@ -616,6 +628,8 @@ public class AccessibilityFloatingMenuView extends FrameLayout
updateStrokeWith(newConfig.uiMode, mAlignment);
updateLocationWith(mAlignment, mPercentageY);
updateScrollModeWith(hasExceededMaxLayoutHeight());
+
+ mLastConfiguration.setTo(newConfig);
}
@VisibleForTesting
@@ -724,6 +738,11 @@ public class AccessibilityFloatingMenuView extends FrameLayout
setInset(insetLeft, insetRight);
}
+ private void updateAccessibilityTitle(WindowManager.LayoutParams params) {
+ params.accessibilityTitle = getResources().getString(
+ com.android.internal.R.string.accessibility_select_shortcut_menu_title);
+ }
+
private void setInset(int left, int right) {
final LayerDrawable layerDrawable = getMenuLayerDrawable();
if (layerDrawable.getLayerInsetLeft(INDEX_MENU_ITEM) == left
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 fd0c4ef0a5be..76106e7c2cf1 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapter.java
@@ -24,9 +24,12 @@ import android.view.ViewGroup;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.Adapter;
+import com.android.internal.accessibility.common.ShortcutConstants.AccessibilityFragmentType;
import com.android.internal.accessibility.dialog.AccessibilityTarget;
import com.android.systemui.R;
import com.android.systemui.accessibility.floatingmenu.AccessibilityTargetAdapter.ViewHolder;
@@ -78,9 +81,20 @@ public class AccessibilityTargetAdapter extends Adapter<ViewHolder> {
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
- holder.mIconView.setBackground(mTargets.get(position).getIcon());
+ final AccessibilityTarget target = mTargets.get(position);
+ holder.mIconView.setBackground(target.getIcon());
holder.updateIconWidthHeight(mIconWidthHeight);
- holder.itemView.setOnClickListener((v) -> mTargets.get(position).onSelected());
+ holder.itemView.setOnClickListener((v) -> target.onSelected());
+ holder.itemView.setStateDescription(target.getStateDescription());
+ holder.itemView.setContentDescription(target.getLabel());
+
+ final String clickHint = target.getFragmentType() == AccessibilityFragmentType.TOGGLE
+ ? holder.itemView.getResources().getString(
+ R.string.accessibility_floating_button_action_double_tap_to_toggle)
+ : null;
+ ViewCompat.replaceAccessibilityAction(holder.itemView,
+ AccessibilityNodeInfoCompat.AccessibilityActionCompat.ACTION_CLICK,
+ clickHint, /* command= */ null);
}
@ItemType
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
index 899625eee7d9..afd5f77f7a4c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityTargetAdapterTest.java
@@ -65,9 +65,9 @@ public class AccessibilityTargetAdapterTest extends SysuiTestCase {
mTargets.add(mAccessibilityTarget);
mAdapter = new AccessibilityTargetAdapter(mTargets);
- final View root = LayoutInflater.from(mContext).inflate(
+ final View rootView = LayoutInflater.from(mContext).inflate(
R.layout.accessibility_floating_menu_item, null);
- mViewHolder = new ViewHolder(root);
+ mViewHolder = new ViewHolder(rootView);
when(mAccessibilityTarget.getIcon()).thenReturn(mIcon);
when(mIcon.getConstantState()).thenReturn(mConstantState);
}
@@ -82,4 +82,27 @@ public class AccessibilityTargetAdapterTest extends SysuiTestCase {
assertThat(actualIconWith).isEqualTo(iconWidthHeight);
}
+
+ @Test
+ public void getContentDescription_invisibleToggleTarget_descriptionWithoutState() {
+ when(mAccessibilityTarget.getFragmentType()).thenReturn(/* InvisibleToggle */ 1);
+ when(mAccessibilityTarget.getLabel()).thenReturn("testLabel");
+ when(mAccessibilityTarget.getStateDescription()).thenReturn("testState");
+
+ mAdapter.onBindViewHolder(mViewHolder, 0);
+
+ assertThat(mViewHolder.itemView.getContentDescription().toString().contentEquals(
+ "testLabel")).isTrue();
+ }
+
+ @Test
+ public void getStateDescription_toggleTarget_switchOff_stateOffText() {
+ when(mAccessibilityTarget.getFragmentType()).thenReturn(/* Toggle */ 2);
+ when(mAccessibilityTarget.getStateDescription()).thenReturn("testState");
+
+ mAdapter.onBindViewHolder(mViewHolder, 0);
+
+ assertThat(mViewHolder.itemView.getStateDescription().toString().contentEquals(
+ "testState")).isTrue();
+ }
}