diff --git a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java index e0b01103ae73e..4f97d210a1546 100644 --- a/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java +++ b/core/java/com/android/internal/accessibility/AccessibilityShortcutController.java @@ -91,6 +91,10 @@ public class AccessibilityShortcutController { public static final ComponentName ACCESSIBILITY_BUTTON_COMPONENT_NAME = new ComponentName("com.android.server.accessibility", "AccessibilityButton"); + // The component name for the sub setting of Hearing aids in Accessibility settings + public static final ComponentName ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME = + new ComponentName("com.android.server.accessibility", "HearingAids"); + public static final ComponentName COLOR_INVERSION_TILE_COMPONENT_NAME = new ComponentName("com.android.server.accessibility", "ColorInversionTile"); public static final ComponentName DALTONIZER_TILE_COMPONENT_NAME = @@ -104,7 +108,7 @@ public class AccessibilityShortcutController { .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) .setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY) .build(); - private static Map sFrameworkShortcutFeaturesMap; + private static Map sFrameworkShortcutFeaturesMap; private final Context mContext; private final Handler mHandler; @@ -133,10 +137,10 @@ public class AccessibilityShortcutController { * @return An immutable map from placeholder component names to feature * info for toggling a framework feature */ - public static Map + public static Map getFrameworkShortcutFeaturesMap() { if (sFrameworkShortcutFeaturesMap == null) { - Map featuresMap = new ArrayMap<>(4); + Map featuresMap = new ArrayMap<>(4); featuresMap.put(COLOR_INVERSION_COMPONENT_NAME, new ToggleableFrameworkFeatureInfo( Settings.Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED, @@ -157,6 +161,8 @@ public class AccessibilityShortcutController { Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, "1" /* Value to enable */, "0" /* Value to disable */, R.string.reduce_bright_colors_feature_name)); + featuresMap.put(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME, + new LaunchableFrameworkFeatureInfo(R.string.hearing_aids_feature_name)); sFrameworkShortcutFeaturesMap = Collections.unmodifiableMap(featuresMap); } return sFrameworkShortcutFeaturesMap; @@ -391,7 +397,7 @@ public class AccessibilityShortcutController { if (targetComponentName == null) { return null; } - final ToggleableFrameworkFeatureInfo frameworkFeatureInfo = + final FrameworkFeatureInfo frameworkFeatureInfo = getFrameworkShortcutFeaturesMap().get(targetComponentName); if (frameworkFeatureInfo != null) { return frameworkFeatureInfo.getLabel(mContext); @@ -670,15 +676,13 @@ public class AccessibilityShortcutController { /** * Immutable class to hold info about framework features that can be controlled by shortcut */ - public static class ToggleableFrameworkFeatureInfo { + public abstract static class FrameworkFeatureInfo { private final String mSettingKey; private final String mSettingOnValue; private final String mSettingOffValue; private final int mLabelStringResourceId; - // These go to the settings wrapper - private int mIconDrawableId; - ToggleableFrameworkFeatureInfo(String settingKey, String settingOnValue, + FrameworkFeatureInfo(String settingKey, String settingOnValue, String settingOffValue, int labelStringResourceId) { mSettingKey = settingKey; mSettingOnValue = settingOnValue; @@ -696,7 +700,7 @@ public class AccessibilityShortcutController { /** * @return The value to write to settings to turn the feature on */ - public String getSettingOnValue() { + public String getSettingOnValue() { return mSettingOnValue; } @@ -711,6 +715,29 @@ public class AccessibilityShortcutController { return context.getString(mLabelStringResourceId); } } + /** + * Immutable class to hold framework features that have on/off state settings key and can be + * controlled by shortcut. + */ + public static class ToggleableFrameworkFeatureInfo extends FrameworkFeatureInfo { + + ToggleableFrameworkFeatureInfo(String settingKey, String settingOnValue, + String settingOffValue, int labelStringResourceId) { + super(settingKey, settingOnValue, settingOffValue, labelStringResourceId); + } + } + + /** + * Immutable class to hold framework features that don't have settings key and can be controlled + * by shortcut. + */ + public static class LaunchableFrameworkFeatureInfo extends FrameworkFeatureInfo { + + LaunchableFrameworkFeatureInfo(int labelStringResourceId) { + super(/* settingKey= */ null, /* settingOnValue= */ null, /* settingOffValue= */ null, + labelStringResourceId); + } + } // Class to allow mocking of static framework calls public static class FrameworkObjectProvider { diff --git a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java index fc2c8cca9796b..b5455f25ef280 100644 --- a/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java +++ b/core/java/com/android/internal/accessibility/dialog/AccessibilityTargetHelper.java @@ -18,6 +18,7 @@ package com.android.internal.accessibility.dialog; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_BUTTON; +import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME; import static com.android.internal.accessibility.AccessibilityShortcutController.MAGNIFICATION_CONTROLLER_NAME; @@ -250,11 +251,21 @@ public final class AccessibilityTargetHelper { context.getDrawable(R.drawable.ic_accessibility_reduce_bright_colors), Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED); + final InvisibleToggleAllowListingFeatureTarget hearingAids = + new InvisibleToggleAllowListingFeatureTarget(context, + shortcutType, + isShortcutContained(context, shortcutType, + ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString()), + ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString(), + context.getString(R.string.hearing_aids_feature_name), + context.getDrawable(R.drawable.ic_accessibility_hearing_aid), + /* key= */ null); targets.add(magnification); targets.add(daltonizer); targets.add(colorInversion); targets.add(oneHandedMode); targets.add(reduceBrightColors); + targets.add(hearingAids); return targets; } diff --git a/core/res/res/drawable/ic_accessibility_hearing_aid.xml b/core/res/res/drawable/ic_accessibility_hearing_aid.xml new file mode 100644 index 0000000000000..e5ffeb0274fc3 --- /dev/null +++ b/core/res/res/drawable/ic_accessibility_hearing_aid.xml @@ -0,0 +1,24 @@ + + + + + + + + diff --git a/core/res/res/drawable/ic_accessibility_hearing_aid_foreground.xml b/core/res/res/drawable/ic_accessibility_hearing_aid_foreground.xml new file mode 100644 index 0000000000000..7ced79594f501 --- /dev/null +++ b/core/res/res/drawable/ic_accessibility_hearing_aid_foreground.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 388bc956a7d66..b754440df8036 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -4715,6 +4715,9 @@ Extra dim + + Hearing devices + Held volume keys. %1$s turned on. diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index af29b233ba834..11d30f5ac2e01 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3517,12 +3517,13 @@ + + - 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 6baf3056be320..a68c39225ce37 100644 --- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java +++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java @@ -21,6 +21,12 @@ import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SC import static android.provider.Settings.Secure.ACCESSIBILITY_SHORTCUT_TARGET_SERVICE; import static android.view.accessibility.AccessibilityManager.ACCESSIBILITY_SHORTCUT_KEY; +import static com.android.internal.accessibility.AccessibilityShortcutController.ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME; +import static com.android.internal.accessibility.AccessibilityShortcutController.COLOR_INVERSION_COMPONENT_NAME; +import static com.android.internal.accessibility.AccessibilityShortcutController.DALTONIZER_COMPONENT_NAME; +import static com.android.internal.accessibility.AccessibilityShortcutController.ONE_HANDED_COMPONENT_NAME; +import static com.android.internal.accessibility.AccessibilityShortcutController.REDUCE_BRIGHT_COLORS_COMPONENT_NAME; + import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertTrue; @@ -90,7 +96,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; - @RunWith(AndroidJUnit4.class) public class AccessibilityShortcutControllerTest { private static final String SERVICE_NAME_STRING = "fake.package/fake.service.name"; @@ -429,7 +434,7 @@ public class AccessibilityShortcutControllerTest { @Test public void getFrameworkFeatureMap_shouldBeNonNullAndUnmodifiable() { - Map + Map frameworkFeatureMap = AccessibilityShortcutController.getFrameworkShortcutFeaturesMap(); assertTrue("Framework features not supported", frameworkFeatureMap.size() > 0); @@ -442,6 +447,19 @@ public class AccessibilityShortcutControllerTest { } } + @Test + public void getFrameworkFeatureMap_containsExpectedKey() { + Map + frameworkFeatureMap = + AccessibilityShortcutController.getFrameworkShortcutFeaturesMap(); + + assertTrue(frameworkFeatureMap.containsKey(COLOR_INVERSION_COMPONENT_NAME)); + assertTrue(frameworkFeatureMap.containsKey(DALTONIZER_COMPONENT_NAME)); + assertTrue(frameworkFeatureMap.containsKey(ONE_HANDED_COMPONENT_NAME)); + assertTrue(frameworkFeatureMap.containsKey(REDUCE_BRIGHT_COLORS_COMPONENT_NAME)); + assertTrue(frameworkFeatureMap.containsKey(ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME)); + } + @Test public void testOnAccessibilityShortcut_forServiceWithNoSummary_doesNotCrash() throws Exception { diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 1183d6b96b02c..2956f447dcc50 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -131,7 +131,7 @@ import android.view.inputmethod.EditorInfo; import com.android.internal.R; import com.android.internal.accessibility.AccessibilityShortcutController; -import com.android.internal.accessibility.AccessibilityShortcutController.ToggleableFrameworkFeatureInfo; +import com.android.internal.accessibility.AccessibilityShortcutController.FrameworkFeatureInfo; import com.android.internal.accessibility.dialog.AccessibilityButtonChooserActivity; import com.android.internal.accessibility.dialog.AccessibilityShortcutChooserActivity; import com.android.internal.annotations.GuardedBy; @@ -3257,13 +3257,12 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub private boolean performAccessibilityFrameworkFeature(ComponentName assignedTarget, @ShortcutType int shortcutType) { - final Map frameworkFeatureMap = + final Map frameworkFeatureMap = AccessibilityShortcutController.getFrameworkShortcutFeaturesMap(); if (!frameworkFeatureMap.containsKey(assignedTarget)) { return false; } - // Toggle the requested framework feature - final ToggleableFrameworkFeatureInfo featureInfo = frameworkFeatureMap.get(assignedTarget); + final FrameworkFeatureInfo featureInfo = frameworkFeatureMap.get(assignedTarget); final SettingStringHelper setting = new SettingStringHelper(mContext.getContentResolver(), featureInfo.getSettingKey(), mCurrentUserId); // Assuming that the default state will be to have the feature off