Merge "Disabling elements on the A11y Shortcut setting subpage" into main

This commit is contained in:
Riley Jones
2025-01-28 13:24:42 -08:00
committed by Android (Google) Code Review
9 changed files with 205 additions and 26 deletions

View File

@@ -5722,6 +5722,8 @@
<string name="accessibility_shortcut_edit_screen_title">Edit accessibility shortcuts</string> <string name="accessibility_shortcut_edit_screen_title">Edit accessibility shortcuts</string>
<!-- Prompt for editing the shortcuts of multiple accessibility features. [CHAR LIMIT=NONE] --> <!-- Prompt for editing the shortcuts of multiple accessibility features. [CHAR LIMIT=NONE] -->
<string name="accessibility_shortcut_edit_screen_prompt">Choose your shortcut for %1$s</string> <string name="accessibility_shortcut_edit_screen_prompt">Choose your shortcut for %1$s</string>
<!-- Summary to display when a shortcut setting is disabled, due to the shortcut being unassigned -->
<string name="accessibility_shortcut_unassigned_setting_unavailable_summary">To use this, turn on the %1$s shortcut on an accessibility feature\'s page</string>
<!-- Button text for the accessibility dialog continue to the next screen for hearing aid. [CHAR LIMIT=32] --> <!-- Button text for the accessibility dialog continue to the next screen for hearing aid. [CHAR LIMIT=32] -->
<string name="accessibility_hearingaid_instruction_continue_button">Continue</string> <string name="accessibility_hearingaid_instruction_continue_button">Continue</string>

View File

@@ -19,7 +19,8 @@
xmlns:settings="http://schemas.android.com/apk/res-auto" xmlns:settings="http://schemas.android.com/apk/res-auto"
android:key="accessibility_shortcuts_settings" android:key="accessibility_shortcuts_settings"
android:persistent="false" android:persistent="false"
android:title="@string/accessibility_shortcuts_settings_title"> android:title="@string/accessibility_shortcuts_settings_title"
settings:searchable="false">
<Preference <Preference
android:fragment="com.android.settings.accessibility.AccessibilityButtonFragment" android:fragment="com.android.settings.accessibility.AccessibilityButtonFragment"
@@ -33,5 +34,5 @@
android:persistent="false" android:persistent="false"
android:title="@string/accessibility_shortcut_service_on_lock_screen_title" android:title="@string/accessibility_shortcut_service_on_lock_screen_title"
android:summary="@string/accessibility_shortcut_description" android:summary="@string/accessibility_shortcut_description"
settings:controller="com.android.settings.accessibility.AccessibilityShortcutPreferenceController"/> settings:controller="com.android.settings.accessibility.HardwareShortcutFromLockscreenPreferenceController"/>
</PreferenceScreen> </PreferenceScreen>

View File

@@ -16,9 +16,14 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import android.app.settings.SettingsEnums; import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import android.os.Bundle;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.os.Bundle;
import android.provider.Settings;
import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.dashboard.DashboardFragment; import com.android.settings.dashboard.DashboardFragment;
import com.android.settings.search.BaseSearchIndexProvider; import com.android.settings.search.BaseSearchIndexProvider;
@@ -61,5 +66,13 @@ public class AccessibilityButtonFragment extends DashboardFragment {
} }
public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER = public static final BaseSearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
new BaseSearchIndexProvider(R.xml.accessibility_button_settings); new BaseSearchIndexProvider(R.xml.accessibility_button_settings) {
@Override
protected boolean isPageSearchEnabled(Context context) {
// Page should be unsearchable if there are no active button targets
String targets = Settings.Secure.getStringForUser(context.getContentResolver(),
ShortcutUtils.convertToKey(SOFTWARE), context.getUserId());
return targets != null && !targets.isEmpty();
}
};
} }

View File

@@ -16,9 +16,13 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
@@ -32,14 +36,39 @@ import java.util.List;
* Preference controller for accessibility button preference. * Preference controller for accessibility button preference.
*/ */
public class AccessibilityButtonPreferenceController extends BasePreferenceController { public class AccessibilityButtonPreferenceController extends BasePreferenceController {
public AccessibilityButtonPreferenceController(Context context, String key) { public AccessibilityButtonPreferenceController(Context context, String key) {
super(context, key); super(context, key);
} }
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
if (!com.android.settings.accessibility.Flags.fixA11ySettingsSearch()) {
return AVAILABLE; return AVAILABLE;
} else {
if (mContext.getSystemService(AccessibilityManager.class)
.getAccessibilityShortcutTargets(SOFTWARE).isEmpty()) {
return DISABLED_DEPENDENT_SETTING;
} else {
return AVAILABLE;
}
}
}
@Override
public void updateState(@NonNull Preference preference) {
super.updateState(preference);
refreshSummary(preference);
}
@Override
public @NonNull CharSequence getSummary() {
if (getAvailabilityStatus() == AVAILABLE) {
return "";
} else {
return mContext.getString(
R.string.accessibility_shortcut_unassigned_setting_unavailable_summary,
AccessibilityUtil.getShortcutSummaryList(mContext, SOFTWARE));
}
} }
@Override @Override
@@ -47,7 +76,6 @@ public class AccessibilityButtonPreferenceController extends BasePreferenceContr
super.displayPreference(screen); super.displayPreference(screen);
final Preference preference = screen.findPreference(getPreferenceKey()); final Preference preference = screen.findPreference(getPreferenceKey());
preference.setTitle(getPreferenceTitleResource()); preference.setTitle(getPreferenceTitleResource());
} }
@Override @Override

View File

@@ -15,6 +15,7 @@
*/ */
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
@@ -22,16 +23,21 @@ import android.content.ContentResolver;
import android.content.Context; import android.content.Context;
import android.os.UserHandle; import android.os.UserHandle;
import android.provider.Settings; import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
import androidx.annotation.NonNull;
import androidx.preference.Preference;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.core.TogglePreferenceController; import com.android.settings.core.TogglePreferenceController;
/** /**
* Settings page for accessibility shortcut * Setting to allow the hardware shortcut to turn on from the lock screen
*/ */
public class AccessibilityShortcutPreferenceController extends TogglePreferenceController { public class HardwareShortcutFromLockscreenPreferenceController
extends TogglePreferenceController {
public AccessibilityShortcutPreferenceController(Context context, String preferenceKey) { public HardwareShortcutFromLockscreenPreferenceController(
Context context, String preferenceKey) {
super(context, preferenceKey); super(context, preferenceKey);
} }
@@ -56,7 +62,33 @@ public class AccessibilityShortcutPreferenceController extends TogglePreferenceC
@Override @Override
public int getAvailabilityStatus() { public int getAvailabilityStatus() {
if (!com.android.settings.accessibility.Flags.fixA11ySettingsSearch()) {
return AVAILABLE; return AVAILABLE;
} else {
if (mContext.getSystemService(AccessibilityManager.class)
.getAccessibilityShortcutTargets(HARDWARE).isEmpty()) {
return DISABLED_DEPENDENT_SETTING;
} else {
return AVAILABLE;
}
}
}
@Override
public void updateState(@NonNull Preference preference) {
super.updateState(preference);
refreshSummary(preference);
}
@Override
public @NonNull CharSequence getSummary() {
if (getAvailabilityStatus() == AVAILABLE) {
return mContext.getString(R.string.accessibility_shortcut_description);
} else {
return mContext.getString(
R.string.accessibility_shortcut_unassigned_setting_unavailable_summary,
AccessibilityUtil.getShortcutSummaryList(mContext, HARDWARE));
}
} }
@Override @Override

View File

@@ -19,6 +19,8 @@ package com.android.settings.accessibility;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.spy; import static org.mockito.Mockito.spy;
@@ -39,6 +41,7 @@ import androidx.preference.PreferenceManager;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import com.android.internal.accessibility.util.ShortcutUtils;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.XmlTestUtils;
import com.android.settings.testutils.shadow.ShadowFragment; import com.android.settings.testutils.shadow.ShadowFragment;
@@ -132,6 +135,7 @@ public class AccessibilityButtonFragmentTest {
} }
@Test @Test
@DisableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
public void getNonIndexableKeys_existInXmlLayout() { public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext); .getNonIndexableKeys(mContext);
@@ -139,7 +143,38 @@ public class AccessibilityButtonFragmentTest {
XmlTestUtils.getKeysFromPreferenceXml(mContext, XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_button_settings); R.xml.accessibility_button_settings);
assertThat(keys).containsAtLeastElementsIn(niks); assertThat(keys).isNotNull();
assertThat(niks).containsAtLeastElementsIn(keys);
}
@Test
@EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
public void getNonIndexableKeys_noTargets_doesNotExistInXmlLayout() {
Settings.Secure.putStringForUser(mContext.getContentResolver(),
ShortcutUtils.convertToKey(SOFTWARE), "", mContext.getUserId());
final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext,
R.xml.accessibility_button_settings);
assertThat(keys).isNotNull();
assertThat(niks).containsAtLeastElementsIn(keys);
}
@Test
@EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
public void getNonIndexableKeys_hasTargets_expectedKeys() {
Settings.Secure.putStringForUser(mContext.getContentResolver(),
ShortcutUtils.convertToKey(SOFTWARE), "Foo", mContext.getUserId());
final List<String> niks = AccessibilityButtonFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext);
// Some keys should show up anyway, as they're flagged as unsearchable in the xml.
assertThat(niks).containsAtLeast(
"accessibility_button_preview",
"accessibility_button_footer",
"accessibility_button_or_gesture");
} }
private static class TestAccessibilityButtonFragment extends AccessibilityButtonFragment { private static class TestAccessibilityButtonFragment extends AccessibilityButtonFragment {

View File

@@ -20,6 +20,10 @@ import static android.provider.Settings.Secure.NAVIGATION_MODE;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_2BUTTON;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL; import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_GESTURAL;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.SOFTWARE;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@@ -31,12 +35,15 @@ import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule; import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Flags; import android.provider.Flags;
import android.provider.Settings; import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
import androidx.preference.Preference; import androidx.preference.Preference;
import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceScreen;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowAccessibilityManager;
import com.android.settingslib.search.SearchIndexableRaw; import com.android.settingslib.search.SearchIndexableRaw;
import org.junit.Before; import org.junit.Before;
@@ -48,11 +55,17 @@ import org.mockito.Spy;
import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule; import org.mockito.junit.MockitoRule;
import org.robolectric.RobolectricTestRunner; import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** Tests for {@link AccessibilityButtonPreferenceController}. */ /** Tests for {@link AccessibilityButtonPreferenceController}. */
@Config(shadows = {
SettingsShadowResources.class,
com.android.settings.testutils.shadow.ShadowAccessibilityManager.class
})
@RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class)
public class AccessibilityButtonPreferenceControllerTest { public class AccessibilityButtonPreferenceControllerTest {
@@ -68,9 +81,12 @@ public class AccessibilityButtonPreferenceControllerTest {
private PreferenceScreen mScreen; private PreferenceScreen mScreen;
private Preference mPreference; private Preference mPreference;
private AccessibilityButtonPreferenceController mController; private AccessibilityButtonPreferenceController mController;
private ShadowAccessibilityManager mShadowAccessibilityManager;
@Before @Before
public void setUp() { public void setUp() {
mShadowAccessibilityManager = Shadow.extract(
mContext.getSystemService(AccessibilityManager.class));
mController = new AccessibilityButtonPreferenceController(mContext, "test_key"); mController = new AccessibilityButtonPreferenceController(mContext, "test_key");
mPreference = new Preference(mContext); mPreference = new Preference(mContext);
mPreference.setKey("test_key"); mPreference.setKey("test_key");
@@ -163,4 +179,20 @@ public class AccessibilityButtonPreferenceControllerTest {
assertThat(raw.screenTitle).isEqualTo( assertThat(raw.screenTitle).isEqualTo(
mResources.getString(R.string.accessibility_shortcuts_settings_title)); mResources.getString(R.string.accessibility_shortcuts_settings_title));
} }
@Test
@EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
public void getAvailabilityStatus_settingEmpty_disabled() {
mShadowAccessibilityManager.setAccessibilityShortcutTargets(SOFTWARE, List.of());
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
}
@Test
@EnableFlags(com.android.settings.accessibility.Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
public void getAvailabilityStatus_settingNotEmpty_available() {
mShadowAccessibilityManager.setAccessibilityShortcutTargets(SOFTWARE, List.of("Foo"));
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2020 The Android Open Source Project * Copyright (C) 2024 The Android Open Source Project
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,36 +16,57 @@
package com.android.settings.accessibility; package com.android.settings.accessibility;
import static com.android.internal.accessibility.common.ShortcutConstants.UserShortcutType.HARDWARE;
import static com.android.settings.accessibility.AccessibilityUtil.State.OFF; import static com.android.settings.accessibility.AccessibilityUtil.State.OFF;
import static com.android.settings.accessibility.AccessibilityUtil.State.ON; import static com.android.settings.accessibility.AccessibilityUtil.State.ON;
import static com.android.settings.core.BasePreferenceController.AVAILABLE;
import androidx.test.core.app.ApplicationProvider; import static com.android.settings.core.BasePreferenceController.DISABLED_DEPENDENT_SETTING;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertThat;
import android.content.Context; import android.content.Context;
import android.os.UserHandle; import android.os.UserHandle;
import android.platform.test.annotations.EnableFlags;
import android.platform.test.flag.junit.SetFlagsRule;
import android.provider.Settings; import android.provider.Settings;
import android.view.accessibility.AccessibilityManager;
import androidx.preference.SwitchPreference; import androidx.preference.SwitchPreference;
import androidx.test.core.app.ApplicationProvider;
import com.android.settings.testutils.shadow.SettingsShadowResources;
import com.android.settings.testutils.shadow.ShadowAccessibilityManager;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow;
@RunWith(AndroidJUnit4.class) import java.util.List;
public class AccessibilityShortcutPreferenceControllerTest {
private Context mContext; @Config(shadows = {
SettingsShadowResources.class,
com.android.settings.testutils.shadow.ShadowAccessibilityManager.class
})
@RunWith(RobolectricTestRunner.class)
public class HardwareShortcutFromLockscreenPreferenceControllerTest {
@Rule
public SetFlagsRule mSetFlagsRule = new SetFlagsRule();
private Context mContext = ApplicationProvider.getApplicationContext();
private SwitchPreference mPreference; private SwitchPreference mPreference;
private AccessibilityShortcutPreferenceController mController; private HardwareShortcutFromLockscreenPreferenceController mController;
private ShadowAccessibilityManager mShadowAccessibilityManager;
@Before @Before
public void setUp() { public void setUp() {
mContext = ApplicationProvider.getApplicationContext(); mShadowAccessibilityManager = Shadow.extract(
mContext.getSystemService(AccessibilityManager.class));
mPreference = new SwitchPreference(mContext); mPreference = new SwitchPreference(mContext);
mController = new AccessibilityShortcutPreferenceController(mContext, mController = new HardwareShortcutFromLockscreenPreferenceController(mContext,
"accessibility_shortcut_preference"); "accessibility_shortcut_preference");
} }
@@ -89,4 +110,20 @@ public class AccessibilityShortcutPreferenceControllerTest {
Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, ON, Settings.Secure.ACCESSIBILITY_SHORTCUT_ON_LOCK_SCREEN, ON,
UserHandle.USER_CURRENT)).isEqualTo(OFF); UserHandle.USER_CURRENT)).isEqualTo(OFF);
} }
@Test
@EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
public void getAvailabilityStatus_settingEmpty_disabled() {
mShadowAccessibilityManager.setAccessibilityShortcutTargets(HARDWARE, List.of());
assertThat(mController.getAvailabilityStatus()).isEqualTo(DISABLED_DEPENDENT_SETTING);
}
@Test
@EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH)
public void getAvailabilityStatus_settingNotEmpty_available() {
mShadowAccessibilityManager.setAccessibilityShortcutTargets(HARDWARE, List.of("Foo"));
assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE);
}
} }

View File

@@ -28,7 +28,6 @@ import android.content.Context;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.accessibility.ShortcutsSettingsFragment;
import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.XmlTestUtils;
import org.junit.Before; import org.junit.Before;
@@ -79,7 +78,7 @@ public class ColorContrastFragmentTest {
@Test @Test
public void getNonIndexableKeys_existInXmlLayout() { public void getNonIndexableKeys_existInXmlLayout() {
final List<String> niks = final List<String> niks =
ShortcutsSettingsFragment.SEARCH_INDEX_DATA_PROVIDER ColorContrastFragment.SEARCH_INDEX_DATA_PROVIDER
.getNonIndexableKeys(mContext); .getNonIndexableKeys(mContext);
final List<String> keys = final List<String> keys =
XmlTestUtils.getKeysFromPreferenceXml(mContext, XmlTestUtils.getKeysFromPreferenceXml(mContext,