summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/accessibility/AccessibilityShortcutController.java45
-rw-r--r--core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java2
-rw-r--r--core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java68
-rw-r--r--core/java/com/android/internal/accessibility/util/AccessibilityUtils.java3
-rw-r--r--core/java/com/android/internal/accessibility/util/ShortcutUtils.java3
-rw-r--r--core/res/res/values/strings.xml6
-rw-r--r--core/res/res/values/symbols.xml11
-rw-r--r--core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java28
8 files changed, 125 insertions, 41 deletions
diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
index be66d0c238cc..1aae92d02aa7 100644
--- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
+++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java
@@ -19,6 +19,7 @@ package com.android.internal.accessibility;
import static android.view.WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG;
import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY;
+import static com.android.internal.accessibility.dialog.AccessibilityTargetHelper.getTargets;
import static com.android.internal.util.ArrayUtils.convertToLongArray;
import android.accessibilityservice.AccessibilityServiceInfo;
@@ -52,6 +53,7 @@ import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;
import com.android.internal.R;
+import com.android.internal.accessibility.dialog.AccessibilityTarget;
import com.android.internal.util.function.pooled.PooledLambda;
import java.lang.annotation.Retention;
@@ -264,16 +266,21 @@ public class AccessibilityShortcutController {
}
private AlertDialog createShortcutWarningDialog(int userId) {
- final String warningMessage = mContext.getString(
- R.string.accessibility_shortcut_toogle_warning);
+ List<AccessibilityTarget> targets = getTargets(mContext, ACCESSIBILITY_SHORTCUT_KEY);
+ if (targets.size() == 0) {
+ return null;
+ }
+
+ // Avoid non-a11y users accidentally turning shortcut on without reading this carefully.
+ // Put "don't turn on" as the primary action.
final AlertDialog alertDialog = mFrameworkObjectProvider.getAlertDialogBuilder(
// Use SystemUI context so we pick up any theme set in a vendor overlay
mFrameworkObjectProvider.getSystemUiContext())
- .setTitle(R.string.accessibility_shortcut_warning_dialog_title)
- .setMessage(warningMessage)
+ .setTitle(getShortcutWarningTitle(targets))
+ .setMessage(getShortcutWarningMessage(targets))
.setCancelable(false)
- .setPositiveButton(R.string.leave_accessibility_shortcut_on, null)
- .setNegativeButton(R.string.disable_accessibility_shortcut,
+ .setNegativeButton(R.string.accessibility_shortcut_on, null)
+ .setPositiveButton(R.string.accessibility_shortcut_off,
(DialogInterface d, int which) -> {
Settings.Secure.putStringForUser(mContext.getContentResolver(),
Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE, "",
@@ -294,6 +301,32 @@ public class AccessibilityShortcutController {
return alertDialog;
}
+ private String getShortcutWarningTitle(List<AccessibilityTarget> targets) {
+ if (targets.size() == 1) {
+ return mContext.getString(
+ R.string.accessibility_shortcut_single_service_warning_title,
+ targets.get(0).getLabel());
+ }
+ return mContext.getString(
+ R.string.accessibility_shortcut_multiple_service_warning_title);
+ }
+
+ private String getShortcutWarningMessage(List<AccessibilityTarget> targets) {
+ if (targets.size() == 1) {
+ return mContext.getString(
+ R.string.accessibility_shortcut_single_service_warning,
+ targets.get(0).getLabel());
+ }
+
+ final StringBuilder sb = new StringBuilder();
+ for (AccessibilityTarget target : targets) {
+ sb.append(mContext.getString(R.string.accessibility_shortcut_multiple_service_list,
+ target.getLabel()));
+ }
+ return mContext.getString(R.string.accessibility_shortcut_multiple_service_warning,
+ sb.toString());
+ }
+
private AccessibilityServiceInfo getInfoForTargetService() {
final ComponentName targetComponentName = getShortcutTargetComponentName();
if (targetComponentName == null) {
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
index 37871d0b5a10..d75659372a07 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTarget.java
@@ -38,7 +38,7 @@ import com.android.internal.accessibility.dialog.TargetAdapter.ViewHolder;
* Abstract base class for creating various target related to accessibility service,
* accessibility activity, and white listing feature.
*/
-abstract class AccessibilityTarget implements TargetOperations, OnTargetSelectedListener,
+public abstract class AccessibilityTarget implements TargetOperations, OnTargetSelectedListener,
OnTargetCheckedChangeListener {
private Context mContext;
@ShortcutType
diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
index f63cbe0dcd9e..60a102adcf7a 100644
--- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
+++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java
@@ -53,19 +53,61 @@ import java.util.Locale;
/**
* Collection of utilities for accessibility target.
*/
-final class AccessibilityTargetHelper {
+public final class AccessibilityTargetHelper {
private AccessibilityTargetHelper() {}
- static List<AccessibilityTarget> getTargets(Context context,
+ /**
+ * Returns list of {@link AccessibilityTarget} of assigned accessibility shortcuts from
+ * {@link AccessibilityManager#getAccessibilityShortcutTargets} including accessibility
+ * feature's package name, component id, etc.
+ *
+ * @param context The context of the application.
+ * @param shortcutType The shortcut type.
+ * @return The list of {@link AccessibilityTarget}.
+ * @hide
+ */
+ public static List<AccessibilityTarget> getTargets(Context context,
@ShortcutType int shortcutType) {
- final List<AccessibilityTarget> targets = getInstalledTargets(context, shortcutType);
- final AccessibilityManager ams = context.getSystemService(AccessibilityManager.class);
- final List<String> requiredTargets = ams.getAccessibilityShortcutTargets(shortcutType);
- targets.removeIf(target -> !requiredTargets.contains(target.getId()));
-
- return targets;
+ // List all accessibility target
+ final List<AccessibilityTarget> installedTargets = getInstalledTargets(context,
+ shortcutType);
+
+ // List accessibility shortcut target
+ final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
+ final List<String> assignedTargets = am.getAccessibilityShortcutTargets(shortcutType);
+
+ // Get the list of accessibility shortcut target in all accessibility target
+ final List<AccessibilityTarget> results = new ArrayList<>();
+ for (String assignedTarget : assignedTargets) {
+ for (AccessibilityTarget installedTarget : installedTargets) {
+ if (!MAGNIFICATION_CONTROLLER_NAME.contentEquals(assignedTarget)) {
+ final ComponentName assignedTargetComponentName =
+ ComponentName.unflattenFromString(assignedTarget);
+ final ComponentName targetComponentName = ComponentName.unflattenFromString(
+ installedTarget.getId());
+ if (assignedTargetComponentName.equals(targetComponentName)) {
+ results.add(installedTarget);
+ continue;
+ }
+ }
+ if (assignedTarget.contentEquals(installedTarget.getId())) {
+ results.add(installedTarget);
+ }
+ }
+ }
+ return results;
}
+ /**
+ * Returns list of {@link AccessibilityTarget} of the installed accessibility service,
+ * accessibility activity, and white listing feature including accessibility feature's package
+ * name, component id, etc.
+ *
+ * @param context The context of the application.
+ * @param shortcutType The shortcut type.
+ * @return The list of {@link AccessibilityTarget}.
+ */
static List<AccessibilityTarget> getInstalledTargets(Context context,
@ShortcutType int shortcutType) {
final List<AccessibilityTarget> targets = new ArrayList<>();
@@ -110,9 +152,10 @@ final class AccessibilityTargetHelper {
private static List<AccessibilityTarget> getAccessibilityServiceTargets(Context context,
@ShortcutType int shortcutType) {
- final AccessibilityManager ams = context.getSystemService(AccessibilityManager.class);
+ final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
final List<AccessibilityServiceInfo> installedServices =
- ams.getInstalledAccessibilityServiceList();
+ am.getInstalledAccessibilityServiceList();
if (installedServices == null) {
return Collections.emptyList();
}
@@ -136,9 +179,10 @@ final class AccessibilityTargetHelper {
private static List<AccessibilityTarget> getAccessibilityActivityTargets(Context context,
@ShortcutType int shortcutType) {
- final AccessibilityManager ams = context.getSystemService(AccessibilityManager.class);
+ final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
final List<AccessibilityShortcutInfo> installedServices =
- ams.getInstalledAccessibilityShortcutListAsUser(context,
+ am.getInstalledAccessibilityShortcutListAsUser(context,
ActivityManager.getCurrentUser());
if (installedServices == null) {
return Collections.emptyList();
diff --git a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
index e50b010d691a..9ee0b0ea1891 100644
--- a/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
+++ b/core/java/com/android/internal/accessibility/util/AccessibilityUtils.java
@@ -142,7 +142,8 @@ public final class AccessibilityUtils {
*/
public static boolean isAccessibilityServiceEnabled(Context context,
@NonNull String componentId) {
- final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
+ final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
final List<AccessibilityServiceInfo> enabledServices =
am.getEnabledAccessibilityServiceList(AccessibilityServiceInfo.FEEDBACK_ALL_MASK);
diff --git a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
index 100422f5660d..31ccb6c32bab 100644
--- a/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
+++ b/core/java/com/android/internal/accessibility/util/ShortcutUtils.java
@@ -137,7 +137,8 @@ public final class ShortcutUtils {
*/
public static boolean isShortcutContained(Context context, @ShortcutType int shortcutType,
@NonNull String componentId) {
- final AccessibilityManager am = context.getSystemService(AccessibilityManager.class);
+ final AccessibilityManager am = (AccessibilityManager) context.getSystemService(
+ Context.ACCESSIBILITY_SERVICE);
final List<String> requiredTargets = am.getAccessibilityShortcutTargets(shortcutType);
return requiredTargets.contains(componentId);
}
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 35a7857b839f..f3f3d47df4a7 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4390,12 +4390,6 @@
<!-- Used in multiple service warning to list current features. [CHAR LIMIT=none] -->
<string name="accessibility_shortcut_multiple_service_list">\t• <xliff:g id="service" example="TalkBack">%1$s</xliff:g>\n</string>
- <!-- Dialog title for dialog shown when the TalkBack shortcut is activated, and we want to confirm that the user understands what's going to happen. [CHAR LIMIT=none] -->
- <string name="accessibility_shortcut_talkback_warning_title">Turn on TalkBack?</string>
-
- <!-- Message shown in dialog when user is in the process of enabling the TalkBack via the volume buttons shortcut for the first time. [CHAR LIMIT=none] -->
- <string name="accessibility_shortcut_talkback_warning">Holding down both volume keys for a few seconds turns on TalkBack, a screen reader that is helpful for people who are blind or have low vision. TalkBack completely changes how your device works.\n\nYou can change this shortcut to another feature in Settings > Accessibility.</string>
-
<!-- Dialog title for dialog shown when this accessibility shortcut is activated, and we want to confirm that the user understands what's going to happen. [CHAR LIMIT=none] -->
<string name="accessibility_shortcut_single_service_warning_title">Turn on <xliff:g id="service" example="TalkBack">%1$s</xliff:g>?</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9a7f07f14cb1..3b6beec5cbcd 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3217,12 +3217,15 @@
<java-symbol type="integer" name="config_debugSystemServerPssThresholdBytes" />
<!-- Accessibility Shortcut -->
- <java-symbol type="string" name="accessibility_shortcut_warning_dialog_title" />
- <java-symbol type="string" name="accessibility_shortcut_toogle_warning" />
+ <java-symbol type="string" name="accessibility_shortcut_single_service_warning_title" />
+ <java-symbol type="string" name="accessibility_shortcut_single_service_warning" />
+ <java-symbol type="string" name="accessibility_shortcut_multiple_service_warning_title" />
+ <java-symbol type="string" name="accessibility_shortcut_multiple_service_warning" />
+ <java-symbol type="string" name="accessibility_shortcut_multiple_service_list" />
+ <java-symbol type="string" name="accessibility_shortcut_on" />
+ <java-symbol type="string" name="accessibility_shortcut_off" />
<java-symbol type="string" name="accessibility_shortcut_enabling_service" />
<java-symbol type="string" name="accessibility_shortcut_disabling_service" />
- <java-symbol type="string" name="disable_accessibility_shortcut" />
- <java-symbol type="string" name="leave_accessibility_shortcut_on" />
<java-symbol type="string" name="color_inversion_feature_name" />
<java-symbol type="string" name="color_correction_feature_name" />
<java-symbol type="string" name="config_defaultAccessibilityService" />
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index b21504c73772..c17c36eba2dc 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -93,6 +93,7 @@ import java.util.Set;
@RunWith(AndroidJUnit4.class)
public class AccessibilityShortcutControllerTest {
private static final String SERVICE_NAME_STRING = "fake.package/fake.service.name";
+ private static final CharSequence PACKAGE_NAME_STRING = "Service name";
private static final String SERVICE_NAME_SUMMARY = "Summary";
private static final long VIBRATOR_PATTERN_1 = 100L;
private static final long VIBRATOR_PATTERN_2 = 150L;
@@ -150,6 +151,8 @@ public class AccessibilityShortcutControllerTest {
new AccessibilityManager(mHandler, mAccessibilityManagerService, 0);
when(mFrameworkObjectProvider.getAccessibilityManagerInstance(mContext))
.thenReturn(accessibilityManager);
+ when(mContext.getSystemService(Context.ACCESSIBILITY_SERVICE))
+ .thenReturn(accessibilityManager);
when(mFrameworkObjectProvider.getAlertDialogBuilder(mContext))
.thenReturn(mAlertDialogBuilder);
when(mFrameworkObjectProvider.makeToastFromText(eq(mContext), anyObject(), anyInt()))
@@ -166,13 +169,13 @@ public class AccessibilityShortcutControllerTest {
ResolveInfo resolveInfo = mock(ResolveInfo.class);
resolveInfo.serviceInfo = mock(ServiceInfo.class);
resolveInfo.serviceInfo.applicationInfo = mApplicationInfo;
- when(resolveInfo.loadLabel(anyObject())).thenReturn("Service name");
+ when(resolveInfo.loadLabel(anyObject())).thenReturn(PACKAGE_NAME_STRING);
when(mServiceInfo.getResolveInfo()).thenReturn(resolveInfo);
when(mServiceInfo.getComponentName())
.thenReturn(ComponentName.unflattenFromString(SERVICE_NAME_STRING));
when(mServiceInfo.loadSummary(any())).thenReturn(SERVICE_NAME_SUMMARY);
- when(mAlertDialogBuilder.setTitle(anyInt())).thenReturn(mAlertDialogBuilder);
+ when(mAlertDialogBuilder.setTitle(anyObject())).thenReturn(mAlertDialogBuilder);
when(mAlertDialogBuilder.setCancelable(anyBoolean())).thenReturn(mAlertDialogBuilder);
when(mAlertDialogBuilder.setMessage(anyObject())).thenReturn(mAlertDialogBuilder);
when(mAlertDialogBuilder.setPositiveButton(anyInt(), anyObject()))
@@ -324,7 +327,8 @@ public class AccessibilityShortcutControllerTest {
assertEquals(1, Settings.Secure.getInt(
mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0));
- verify(mResources).getString(R.string.accessibility_shortcut_toogle_warning);
+ verify(mResources).getString(
+ R.string.accessibility_shortcut_single_service_warning_title, PACKAGE_NAME_STRING);
verify(mAlertDialog).show();
verify(mAccessibilityManagerService, atLeastOnce()).getInstalledAccessibilityServiceList(
anyInt());
@@ -376,16 +380,20 @@ public class AccessibilityShortcutControllerTest {
ArgumentCaptor<DialogInterface.OnClickListener> captor =
ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
- verify(mAlertDialogBuilder).setNegativeButton(eq(R.string.disable_accessibility_shortcut),
+ verify(mAlertDialogBuilder).setPositiveButton(eq(R.string.accessibility_shortcut_off),
captor.capture());
- // Call the button callback
- captor.getValue().onClick(null, 0);
+ // Call the button callback, if one exists
+ if (captor.getValue() != null) {
+ captor.getValue().onClick(null, 0);
+ }
assertTrue(TextUtils.isEmpty(
Settings.Secure.getString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE)));
+ assertEquals(0, Settings.Secure.getInt(
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN));
}
@Test
- public void testClickingLeaveOnButtonInDialog_shouldLeaveShortcutReady() throws Exception {
+ public void testClickingTurnOnButtonInDialog_shouldLeaveShortcutReady() throws Exception {
configureShortcutEnabled(ENABLED_EXCEPT_LOCK_SCREEN);
configureValidShortcutService();
Settings.Secure.putInt(mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN, 0);
@@ -393,8 +401,8 @@ public class AccessibilityShortcutControllerTest {
ArgumentCaptor<DialogInterface.OnClickListener> captor =
ArgumentCaptor.forClass(DialogInterface.OnClickListener.class);
- verify(mAlertDialogBuilder).setPositiveButton(eq(R.string.leave_accessibility_shortcut_on),
- captor.capture());
+ verify(mAlertDialogBuilder).setNegativeButton(eq(R.string.accessibility_shortcut_on),
+ captor.capture());
// Call the button callback, if one exists
if (captor.getValue() != null) {
captor.getValue().onClick(null, 0);
@@ -402,7 +410,7 @@ public class AccessibilityShortcutControllerTest {
assertEquals(SERVICE_NAME_STRING,
Settings.Secure.getString(mContentResolver, ACCESSIBILITY_SHORTCUT_TARGET_SERVICE));
assertEquals(1, Settings.Secure.getInt(
- mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN));
+ mContentResolver, ACCESSIBILITY_SHORTCUT_DIALOG_SHOWN));
}
@Test