[Hearing device shortcut] setup hearing aid shortcut resources

* Add ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME for shortcut id
* Setup InvisibleToggleAllowListingFeatureTarget for non-state shortcut feature
* Setup adaptive icon for shortcut drawable

Bug: 237625815
Test: atest AccessibilityShortcutControllerTest
Test: Add hearing device shortcut then to verify it shows on different
type of the accessibility shortcuts

Change-Id: I6d9a10122637778b5df6341b4dbfd2066c3c9075
This commit is contained in:
jasonwshsu
2022-12-09 01:58:01 +08:00
parent 7a298821a1
commit 728ace0881
8 changed files with 124 additions and 16 deletions

View File

@@ -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<ComponentName, ToggleableFrameworkFeatureInfo> sFrameworkShortcutFeaturesMap;
private static Map<ComponentName, FrameworkFeatureInfo> 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<ComponentName, ToggleableFrameworkFeatureInfo>
public static Map<ComponentName, FrameworkFeatureInfo>
getFrameworkShortcutFeaturesMap() {
if (sFrameworkShortcutFeaturesMap == null) {
Map<ComponentName, ToggleableFrameworkFeatureInfo> featuresMap = new ArrayMap<>(4);
Map<ComponentName, FrameworkFeatureInfo> 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 {

View File

@@ -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;
}

View File

@@ -0,0 +1,24 @@
<!--
Copyright (C) 2022 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.
-->
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/accessibility_feature_background" />
<foreground>
<inset
android:drawable="@drawable/ic_accessibility_hearing_aid_foreground"
android:inset="@dimen/accessibility_icon_foreground_padding_ratio" />
</foreground>
</adaptive-icon>

View File

@@ -0,0 +1,25 @@
<!--
Copyright (C) 2022 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.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#ffffff"
android:pathData="M17,20c-0.29,0 -0.56,-0.06 -0.76,-0.15 -0.71,-0.37 -1.21,-0.88 -1.71,-2.38 -0.51,-1.56 -1.47,-2.29 -2.39,-3 -0.79,-0.61 -1.61,-1.24 -2.32,-2.53C9.29,10.98 9,9.93 9,9c0,-2.8 2.2,-5 5,-5s5,2.2 5,5h2c0,-3.93 -3.07,-7 -7,-7S7,5.07 7,9c0,1.26 0.38,2.65 1.07,3.9 0.91,1.65 1.98,2.48 2.85,3.15 0.81,0.62 1.39,1.07 1.71,2.05 0.6,1.82 1.37,2.84 2.73,3.55 0.51,0.23 1.07,0.35 1.64,0.35 2.21,0 4,-1.79 4,-4h-2c0,1.1 -0.9,2 -2,2zM7.64,2.64L6.22,1.22C4.23,3.21 3,5.96 3,9s1.23,5.79 3.22,7.78l1.41,-1.41C6.01,13.74 5,11.49 5,9s1.01,-4.74 2.64,-6.36zM11.5,9c0,1.38 1.12,2.5 2.5,2.5s2.5,-1.12 2.5,-2.5 -1.12,-2.5 -2.5,-2.5 -2.5,1.12 -2.5,2.5z"/>
</vector>

View File

@@ -4715,6 +4715,9 @@
<!-- Title of Reduce Brightness feature, shown in the warning dialog about the accessibility shortcut. [CHAR LIMIT=none] -->
<string name="reduce_bright_colors_feature_name">Extra dim</string>
<!-- Title of hearing aids feature, shown in the warning dialog about the accessibility shortcut. [CHAR LIMIT=none] -->
<string name="hearing_aids_feature_name">Hearing devices</string>
<!-- Text in toast to alert the user that the accessibility shortcut turned on an accessibility service. [CHAR LIMIT=none] -->
<string name="accessibility_shortcut_enabling_service">Held volume keys. <xliff:g id="service_name" example="TalkBack">%1$s</xliff:g> turned on.</string>

View File

@@ -3517,12 +3517,13 @@
<java-symbol type="drawable" name="ic_accessibility_color_inversion" />
<java-symbol type="drawable" name="ic_accessibility_color_correction" />
<java-symbol type="drawable" name="ic_accessibility_hearing_aid" />
<java-symbol type="drawable" name="ic_accessibility_magnification" />
<java-symbol type="drawable" name="ic_accessibility_reduce_bright_colors" />
<java-symbol type="drawable" name="ic_accessibility_one_handed" />
<java-symbol type="string" name="hearing_aids_feature_name" />
<java-symbol type="string" name="reduce_bright_colors_feature_name" />
<java-symbol type="string" name="one_handed_mode_feature_name" />
<!-- com.android.internal.widget.RecyclerView -->

View File

@@ -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<ComponentName, AccessibilityShortcutController.ToggleableFrameworkFeatureInfo>
Map<ComponentName, AccessibilityShortcutController.FrameworkFeatureInfo>
frameworkFeatureMap =
AccessibilityShortcutController.getFrameworkShortcutFeaturesMap();
assertTrue("Framework features not supported", frameworkFeatureMap.size() > 0);
@@ -442,6 +447,19 @@ public class AccessibilityShortcutControllerTest {
}
}
@Test
public void getFrameworkFeatureMap_containsExpectedKey() {
Map<ComponentName, AccessibilityShortcutController.FrameworkFeatureInfo>
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 {

View File

@@ -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<ComponentName, ToggleableFrameworkFeatureInfo> frameworkFeatureMap =
final Map<ComponentName, FrameworkFeatureInfo> 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