Loading src/com/android/settings/accessibility/AccessibilitySettings.java +8 −35 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.accessibilityservice.AccessibilityShortcutInfo; import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Context; import android.content.pm.ServiceInfo; import android.hardware.input.InputManager; import android.os.Bundle; import android.os.Handler; Loading @@ -31,7 +30,6 @@ import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Pair; import android.view.InputDevice; import android.view.accessibility.AccessibilityManager; Loading Loading @@ -59,8 +57,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** Activity with the accessibility settings. */ @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) Loading Loading @@ -415,14 +411,14 @@ public class AccessibilitySettings extends DashboardFragment implements final List<AccessibilityShortcutInfo> installedShortcutList = a11yManager.getInstalledAccessibilityShortcutListAsUser(getPrefContext(), UserHandle.myUserId()); final List<AccessibilityServiceInfo> modifiableInstalledServiceList = new ArrayList<>(a11yManager.getInstalledAccessibilityServiceList()); final List<AccessibilityServiceInfo> installedServiceList = a11yManager.getInstalledAccessibilityServiceList(); final List<RestrictedPreference> preferenceList = getInstalledAccessibilityPreferences( getPrefContext(), installedShortcutList, modifiableInstalledServiceList); getPrefContext(), installedShortcutList, installedServiceList); if (Flags.checkPrebundledIsPreinstalled()) { removeNonPreinstalledComponents(mPreBundledServiceComponentToCategoryMap, installedShortcutList, modifiableInstalledServiceList); installedShortcutList, installedServiceList); } final PreferenceCategory downloadedServicesCategory = Loading Loading @@ -475,30 +471,17 @@ public class AccessibilitySettings extends DashboardFragment implements * matching package name and label as an entry in {@code installedShortcutList}. * * @param installedShortcutList A list of installed {@link AccessibilityShortcutInfo}s. * @param modifiableInstalledServiceList A modifiable list of installed * {@link AccessibilityServiceInfo}s. * @param installedServiceList A list of installed {@link AccessibilityServiceInfo}s. */ private List<RestrictedPreference> getInstalledAccessibilityPreferences(Context context, List<AccessibilityShortcutInfo> installedShortcutList, List<AccessibilityServiceInfo> modifiableInstalledServiceList) { List<AccessibilityServiceInfo> installedServiceList) { final RestrictedPreferenceHelper preferenceHelper = new RestrictedPreferenceHelper(context); final List<AccessibilityActivityPreference> activityList = preferenceHelper.createAccessibilityActivityPreferenceList(installedShortcutList); final Set<Pair<String, CharSequence>> packageLabelPairs = activityList.stream() .map(a11yActivityPref -> new Pair<>( a11yActivityPref.getPackageName(), a11yActivityPref.getLabel()) ).collect(Collectors.toSet()); // Remove duplicate A11yServices that are already shown as A11yActivities. if (!packageLabelPairs.isEmpty()) { modifiableInstalledServiceList.removeIf( target -> containsPackageAndLabelInList(packageLabelPairs, target)); } final List<RestrictedPreference> serviceList = preferenceHelper.createAccessibilityServicePreferenceList( modifiableInstalledServiceList); preferenceHelper.createAccessibilityServicePreferenceList(installedServiceList); final List<RestrictedPreference> preferenceList = new ArrayList<>(); preferenceList.addAll(activityList); Loading @@ -523,16 +506,6 @@ public class AccessibilitySettings extends DashboardFragment implements } } private boolean containsPackageAndLabelInList( Set<Pair<String, CharSequence>> packageLabelPairs, AccessibilityServiceInfo targetServiceInfo) { final ServiceInfo serviceInfo = targetServiceInfo.getResolveInfo().serviceInfo; final String servicePackageName = serviceInfo.packageName; final CharSequence serviceLabel = serviceInfo.loadLabel(getPackageManager()); return packageLabelPairs.contains(new Pair<>(servicePackageName, serviceLabel)); } private void initializePreBundledServicesMapFromArray(String categoryKey, int key) { String[] services = getResources().getStringArray(key); PreferenceCategory category = mCategoryToPrefCategoryMap.get(categoryKey); Loading tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java +58 −8 Original line number Diff line number Diff line Loading @@ -26,10 +26,13 @@ import static org.robolectric.Shadows.shadowOf; import static java.util.Collections.singletonList; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityShortcutInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.database.ContentObserver; Loading @@ -48,6 +51,7 @@ import com.android.internal.accessibility.util.AccessibilityUtils; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.ShadowAccessibilityManager; import com.android.settings.testutils.shadow.ShadowApplicationPackageManager; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; Loading @@ -73,7 +77,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowAccessibilityManager; import org.robolectric.shadows.ShadowContentResolver; import org.xmlpull.v1.XmlPullParserException; Loading @@ -85,6 +88,7 @@ import java.util.List; /** Test for {@link AccessibilitySettings}. */ @RunWith(RobolectricTestRunner.class) @Config(shadows = { ShadowAccessibilityManager.class, ShadowBluetoothAdapter.class, ShadowUserManager.class, ShadowColorDisplayManager.class, Loading @@ -93,8 +97,10 @@ import java.util.List; }) public class AccessibilitySettingsTest { private static final String PACKAGE_NAME = "com.android.test"; private static final String CLASS_NAME = PACKAGE_NAME + ".test_a11y_service"; private static final ComponentName COMPONENT_NAME = new ComponentName(PACKAGE_NAME, CLASS_NAME); private static final ComponentName SERVICE_COMPONENT_NAME = new ComponentName(PACKAGE_NAME, PACKAGE_NAME + ".test_a11y_service"); private static final ComponentName ACTIVITY_COMPONENT_NAME = new ComponentName(PACKAGE_NAME, PACKAGE_NAME + ".test_a11y_activity"); private static final String EMPTY_STRING = ""; private static final String DEFAULT_SUMMARY = "default summary"; private static final String DEFAULT_DESCRIPTION = "default description"; Loading @@ -108,7 +114,7 @@ public class AccessibilitySettingsTest { private final Context mContext = ApplicationProvider.getApplicationContext(); @Spy private final AccessibilityServiceInfo mServiceInfo = getMockAccessibilityServiceInfo( new ComponentName(PACKAGE_NAME, CLASS_NAME)); SERVICE_COMPONENT_NAME); private ShadowAccessibilityManager mShadowAccessibilityManager; @Mock private LocalBluetoothManager mLocalBluetoothManager; Loading @@ -117,7 +123,8 @@ public class AccessibilitySettingsTest { @Before public void setup() { mShadowAccessibilityManager = Shadow.extract(AccessibilityManager.getInstance(mContext)); mShadowAccessibilityManager = Shadow.extract( mContext.getSystemService(AccessibilityManager.class)); mShadowAccessibilityManager.setInstalledAccessibilityServiceList(new ArrayList<>()); mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat); ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager; Loading Loading @@ -369,7 +376,7 @@ public class AccessibilitySettingsTest { mFragment.onContentChanged(); RestrictedPreference preference = mFragment.getPreferenceScreen().findPreference( COMPONENT_NAME.flattenToString()); SERVICE_COMPONENT_NAME.flattenToString()); assertThat(preference).isNotNull(); Loading @@ -389,7 +396,7 @@ public class AccessibilitySettingsTest { mFragment.onResume(); RestrictedPreference preference = mFragment.getPreferenceScreen().findPreference( COMPONENT_NAME.flattenToString()); SERVICE_COMPONENT_NAME.flattenToString()); assertThat(preference).isNotNull(); Loading Loading @@ -430,6 +437,36 @@ public class AccessibilitySettingsTest { assertThat(pref).isNull(); } @Test public void testSameNamedServiceAndActivity_bothPreferencesExist() { final PackageManager pm = mContext.getPackageManager(); AccessibilityServiceInfo a11yServiceInfo = mServiceInfo; AccessibilityShortcutInfo a11yShortcutInfo = getMockAccessibilityShortcutInfo(); // Ensure the test service and activity have the same package name and label. // Before this change, any service and activity with the same package name and // label would cause the service to be hidden. assertThat(a11yServiceInfo.getComponentName()) .isNotEqualTo(a11yShortcutInfo.getComponentName()); assertThat(a11yServiceInfo.getComponentName().getPackageName()) .isEqualTo(a11yShortcutInfo.getComponentName().getPackageName()); assertThat(a11yServiceInfo.getResolveInfo().serviceInfo.loadLabel(pm)) .isEqualTo(a11yShortcutInfo.getActivityInfo().loadLabel(pm)); // Prepare A11yManager with the test service and activity. mShadowAccessibilityManager.setInstalledAccessibilityServiceList( List.of(mServiceInfo)); mShadowAccessibilityManager.setInstalledAccessibilityShortcutListAsUser( List.of(getMockAccessibilityShortcutInfo())); setupFragment(); // Both service and activity preferences should exist on the page. RestrictedPreference servicePref = mFragment.getPreferenceScreen().findPreference( a11yServiceInfo.getComponentName().flattenToString()); RestrictedPreference activityPref = mFragment.getPreferenceScreen().findPreference( a11yShortcutInfo.getComponentName().flattenToString()); assertThat(servicePref).isNotNull(); assertThat(activityPref).isNotNull(); } private String getPreferenceCategory(ComponentName componentName) { return mFragment.mServicePreferenceToPreferenceCategoryMap.get( mFragment.getPreferenceScreen().findPreference( Loading @@ -444,11 +481,12 @@ public class AccessibilitySettingsTest { boolean isSystemApp) { final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class); when(applicationInfo.isSystemApp()).thenReturn(isSystemApp); final ServiceInfo serviceInfo = new ServiceInfo(); final ServiceInfo serviceInfo = Mockito.spy(new ServiceInfo()); applicationInfo.packageName = componentName.getPackageName(); serviceInfo.packageName = componentName.getPackageName(); serviceInfo.name = componentName.getClassName(); serviceInfo.applicationInfo = applicationInfo; when(serviceInfo.loadLabel(any())).thenReturn(DEFAULT_LABEL); final ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.serviceInfo = serviceInfo; Loading @@ -464,6 +502,18 @@ public class AccessibilitySettingsTest { return null; } private AccessibilityShortcutInfo getMockAccessibilityShortcutInfo() { AccessibilityShortcutInfo mockInfo = Mockito.mock(AccessibilityShortcutInfo.class); final ActivityInfo activityInfo = Mockito.mock(ActivityInfo.class); activityInfo.applicationInfo = new ApplicationInfo(); when(mockInfo.getActivityInfo()).thenReturn(activityInfo); when(activityInfo.loadLabel(any())).thenReturn(DEFAULT_LABEL); when(mockInfo.loadSummary(any())).thenReturn(DEFAULT_SUMMARY); when(mockInfo.loadDescription(any())).thenReturn(DEFAULT_DESCRIPTION); when(mockInfo.getComponentName()).thenReturn(ACTIVITY_COMPONENT_NAME); return mockInfo; } private void setInvisibleToggleFragmentType(AccessibilityServiceInfo info) { info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON; Loading tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManager.java +23 −1 Original line number Diff line number Diff line Loading @@ -16,15 +16,18 @@ package com.android.settings.testutils.shadow; import android.accessibilityservice.AccessibilityShortcutInfo; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ComponentName; import android.content.Context; import android.util.ArrayMap; import android.view.accessibility.AccessibilityManager; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import java.util.List; import java.util.Map; /** Loading @@ -33,9 +36,10 @@ import java.util.Map; @Implements(AccessibilityManager.class) public class ShadowAccessibilityManager extends org.robolectric.shadows.ShadowAccessibilityManager { private Map<ComponentName, ComponentName> mA11yFeatureToTileMap = new ArrayMap<>(); private List<AccessibilityShortcutInfo> mInstalledAccessibilityShortcutList = List.of(); /** * Implements a hidden method {@link AccessibilityManager.getA11yFeatureToTileMap} * Implements a hidden method {@link AccessibilityManager#getA11yFeatureToTileMap} */ @Implementation public Map<ComponentName, ComponentName> getA11yFeatureToTileMap(@UserIdInt int userId) { Loading @@ -49,4 +53,22 @@ public class ShadowAccessibilityManager extends org.robolectric.shadows.ShadowAc @NonNull Map<ComponentName, ComponentName> a11yFeatureToTileMap) { mA11yFeatureToTileMap = a11yFeatureToTileMap; } /** * Implements the hidden method * {@link AccessibilityManager#getInstalledAccessibilityShortcutListAsUser}. */ @Implementation public List<AccessibilityShortcutInfo> getInstalledAccessibilityShortcutListAsUser( @NonNull Context context, @UserIdInt int userId) { return mInstalledAccessibilityShortcutList; } /** * Sets the value to be returned by {@link #getInstalledAccessibilityShortcutListAsUser}. */ public void setInstalledAccessibilityShortcutListAsUser( @NonNull List<AccessibilityShortcutInfo> installedAccessibilityShortcutList) { mInstalledAccessibilityShortcutList = installedAccessibilityShortcutList; } } Loading
src/com/android/settings/accessibility/AccessibilitySettings.java +8 −35 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.accessibilityservice.AccessibilityShortcutInfo; import android.app.settings.SettingsEnums; import android.content.ComponentName; import android.content.Context; import android.content.pm.ServiceInfo; import android.hardware.input.InputManager; import android.os.Bundle; import android.os.Handler; Loading @@ -31,7 +30,6 @@ import android.os.UserHandle; import android.provider.Settings; import android.text.TextUtils; import android.util.ArrayMap; import android.util.Pair; import android.view.InputDevice; import android.view.accessibility.AccessibilityManager; Loading Loading @@ -59,8 +57,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; /** Activity with the accessibility settings. */ @SearchIndexable(forTarget = SearchIndexable.ALL & ~SearchIndexable.ARC) Loading Loading @@ -415,14 +411,14 @@ public class AccessibilitySettings extends DashboardFragment implements final List<AccessibilityShortcutInfo> installedShortcutList = a11yManager.getInstalledAccessibilityShortcutListAsUser(getPrefContext(), UserHandle.myUserId()); final List<AccessibilityServiceInfo> modifiableInstalledServiceList = new ArrayList<>(a11yManager.getInstalledAccessibilityServiceList()); final List<AccessibilityServiceInfo> installedServiceList = a11yManager.getInstalledAccessibilityServiceList(); final List<RestrictedPreference> preferenceList = getInstalledAccessibilityPreferences( getPrefContext(), installedShortcutList, modifiableInstalledServiceList); getPrefContext(), installedShortcutList, installedServiceList); if (Flags.checkPrebundledIsPreinstalled()) { removeNonPreinstalledComponents(mPreBundledServiceComponentToCategoryMap, installedShortcutList, modifiableInstalledServiceList); installedShortcutList, installedServiceList); } final PreferenceCategory downloadedServicesCategory = Loading Loading @@ -475,30 +471,17 @@ public class AccessibilitySettings extends DashboardFragment implements * matching package name and label as an entry in {@code installedShortcutList}. * * @param installedShortcutList A list of installed {@link AccessibilityShortcutInfo}s. * @param modifiableInstalledServiceList A modifiable list of installed * {@link AccessibilityServiceInfo}s. * @param installedServiceList A list of installed {@link AccessibilityServiceInfo}s. */ private List<RestrictedPreference> getInstalledAccessibilityPreferences(Context context, List<AccessibilityShortcutInfo> installedShortcutList, List<AccessibilityServiceInfo> modifiableInstalledServiceList) { List<AccessibilityServiceInfo> installedServiceList) { final RestrictedPreferenceHelper preferenceHelper = new RestrictedPreferenceHelper(context); final List<AccessibilityActivityPreference> activityList = preferenceHelper.createAccessibilityActivityPreferenceList(installedShortcutList); final Set<Pair<String, CharSequence>> packageLabelPairs = activityList.stream() .map(a11yActivityPref -> new Pair<>( a11yActivityPref.getPackageName(), a11yActivityPref.getLabel()) ).collect(Collectors.toSet()); // Remove duplicate A11yServices that are already shown as A11yActivities. if (!packageLabelPairs.isEmpty()) { modifiableInstalledServiceList.removeIf( target -> containsPackageAndLabelInList(packageLabelPairs, target)); } final List<RestrictedPreference> serviceList = preferenceHelper.createAccessibilityServicePreferenceList( modifiableInstalledServiceList); preferenceHelper.createAccessibilityServicePreferenceList(installedServiceList); final List<RestrictedPreference> preferenceList = new ArrayList<>(); preferenceList.addAll(activityList); Loading @@ -523,16 +506,6 @@ public class AccessibilitySettings extends DashboardFragment implements } } private boolean containsPackageAndLabelInList( Set<Pair<String, CharSequence>> packageLabelPairs, AccessibilityServiceInfo targetServiceInfo) { final ServiceInfo serviceInfo = targetServiceInfo.getResolveInfo().serviceInfo; final String servicePackageName = serviceInfo.packageName; final CharSequence serviceLabel = serviceInfo.loadLabel(getPackageManager()); return packageLabelPairs.contains(new Pair<>(servicePackageName, serviceLabel)); } private void initializePreBundledServicesMapFromArray(String categoryKey, int key) { String[] services = getResources().getStringArray(key); PreferenceCategory category = mCategoryToPrefCategoryMap.get(categoryKey); Loading
tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java +58 −8 Original line number Diff line number Diff line Loading @@ -26,10 +26,13 @@ import static org.robolectric.Shadows.shadowOf; import static java.util.Collections.singletonList; import android.accessibilityservice.AccessibilityServiceInfo; import android.accessibilityservice.AccessibilityShortcutInfo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ServiceInfo; import android.database.ContentObserver; Loading @@ -48,6 +51,7 @@ import com.android.internal.accessibility.util.AccessibilityUtils; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.ShadowAccessibilityManager; import com.android.settings.testutils.shadow.ShadowApplicationPackageManager; import com.android.settings.testutils.shadow.ShadowBluetoothAdapter; import com.android.settings.testutils.shadow.ShadowBluetoothUtils; Loading @@ -73,7 +77,6 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowAccessibilityManager; import org.robolectric.shadows.ShadowContentResolver; import org.xmlpull.v1.XmlPullParserException; Loading @@ -85,6 +88,7 @@ import java.util.List; /** Test for {@link AccessibilitySettings}. */ @RunWith(RobolectricTestRunner.class) @Config(shadows = { ShadowAccessibilityManager.class, ShadowBluetoothAdapter.class, ShadowUserManager.class, ShadowColorDisplayManager.class, Loading @@ -93,8 +97,10 @@ import java.util.List; }) public class AccessibilitySettingsTest { private static final String PACKAGE_NAME = "com.android.test"; private static final String CLASS_NAME = PACKAGE_NAME + ".test_a11y_service"; private static final ComponentName COMPONENT_NAME = new ComponentName(PACKAGE_NAME, CLASS_NAME); private static final ComponentName SERVICE_COMPONENT_NAME = new ComponentName(PACKAGE_NAME, PACKAGE_NAME + ".test_a11y_service"); private static final ComponentName ACTIVITY_COMPONENT_NAME = new ComponentName(PACKAGE_NAME, PACKAGE_NAME + ".test_a11y_activity"); private static final String EMPTY_STRING = ""; private static final String DEFAULT_SUMMARY = "default summary"; private static final String DEFAULT_DESCRIPTION = "default description"; Loading @@ -108,7 +114,7 @@ public class AccessibilitySettingsTest { private final Context mContext = ApplicationProvider.getApplicationContext(); @Spy private final AccessibilityServiceInfo mServiceInfo = getMockAccessibilityServiceInfo( new ComponentName(PACKAGE_NAME, CLASS_NAME)); SERVICE_COMPONENT_NAME); private ShadowAccessibilityManager mShadowAccessibilityManager; @Mock private LocalBluetoothManager mLocalBluetoothManager; Loading @@ -117,7 +123,8 @@ public class AccessibilitySettingsTest { @Before public void setup() { mShadowAccessibilityManager = Shadow.extract(AccessibilityManager.getInstance(mContext)); mShadowAccessibilityManager = Shadow.extract( mContext.getSystemService(AccessibilityManager.class)); mShadowAccessibilityManager.setInstalledAccessibilityServiceList(new ArrayList<>()); mContext.setTheme(androidx.appcompat.R.style.Theme_AppCompat); ShadowBluetoothUtils.sLocalBluetoothManager = mLocalBluetoothManager; Loading Loading @@ -369,7 +376,7 @@ public class AccessibilitySettingsTest { mFragment.onContentChanged(); RestrictedPreference preference = mFragment.getPreferenceScreen().findPreference( COMPONENT_NAME.flattenToString()); SERVICE_COMPONENT_NAME.flattenToString()); assertThat(preference).isNotNull(); Loading @@ -389,7 +396,7 @@ public class AccessibilitySettingsTest { mFragment.onResume(); RestrictedPreference preference = mFragment.getPreferenceScreen().findPreference( COMPONENT_NAME.flattenToString()); SERVICE_COMPONENT_NAME.flattenToString()); assertThat(preference).isNotNull(); Loading Loading @@ -430,6 +437,36 @@ public class AccessibilitySettingsTest { assertThat(pref).isNull(); } @Test public void testSameNamedServiceAndActivity_bothPreferencesExist() { final PackageManager pm = mContext.getPackageManager(); AccessibilityServiceInfo a11yServiceInfo = mServiceInfo; AccessibilityShortcutInfo a11yShortcutInfo = getMockAccessibilityShortcutInfo(); // Ensure the test service and activity have the same package name and label. // Before this change, any service and activity with the same package name and // label would cause the service to be hidden. assertThat(a11yServiceInfo.getComponentName()) .isNotEqualTo(a11yShortcutInfo.getComponentName()); assertThat(a11yServiceInfo.getComponentName().getPackageName()) .isEqualTo(a11yShortcutInfo.getComponentName().getPackageName()); assertThat(a11yServiceInfo.getResolveInfo().serviceInfo.loadLabel(pm)) .isEqualTo(a11yShortcutInfo.getActivityInfo().loadLabel(pm)); // Prepare A11yManager with the test service and activity. mShadowAccessibilityManager.setInstalledAccessibilityServiceList( List.of(mServiceInfo)); mShadowAccessibilityManager.setInstalledAccessibilityShortcutListAsUser( List.of(getMockAccessibilityShortcutInfo())); setupFragment(); // Both service and activity preferences should exist on the page. RestrictedPreference servicePref = mFragment.getPreferenceScreen().findPreference( a11yServiceInfo.getComponentName().flattenToString()); RestrictedPreference activityPref = mFragment.getPreferenceScreen().findPreference( a11yShortcutInfo.getComponentName().flattenToString()); assertThat(servicePref).isNotNull(); assertThat(activityPref).isNotNull(); } private String getPreferenceCategory(ComponentName componentName) { return mFragment.mServicePreferenceToPreferenceCategoryMap.get( mFragment.getPreferenceScreen().findPreference( Loading @@ -444,11 +481,12 @@ public class AccessibilitySettingsTest { boolean isSystemApp) { final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class); when(applicationInfo.isSystemApp()).thenReturn(isSystemApp); final ServiceInfo serviceInfo = new ServiceInfo(); final ServiceInfo serviceInfo = Mockito.spy(new ServiceInfo()); applicationInfo.packageName = componentName.getPackageName(); serviceInfo.packageName = componentName.getPackageName(); serviceInfo.name = componentName.getClassName(); serviceInfo.applicationInfo = applicationInfo; when(serviceInfo.loadLabel(any())).thenReturn(DEFAULT_LABEL); final ResolveInfo resolveInfo = new ResolveInfo(); resolveInfo.serviceInfo = serviceInfo; Loading @@ -464,6 +502,18 @@ public class AccessibilitySettingsTest { return null; } private AccessibilityShortcutInfo getMockAccessibilityShortcutInfo() { AccessibilityShortcutInfo mockInfo = Mockito.mock(AccessibilityShortcutInfo.class); final ActivityInfo activityInfo = Mockito.mock(ActivityInfo.class); activityInfo.applicationInfo = new ApplicationInfo(); when(mockInfo.getActivityInfo()).thenReturn(activityInfo); when(activityInfo.loadLabel(any())).thenReturn(DEFAULT_LABEL); when(mockInfo.loadSummary(any())).thenReturn(DEFAULT_SUMMARY); when(mockInfo.loadDescription(any())).thenReturn(DEFAULT_DESCRIPTION); when(mockInfo.getComponentName()).thenReturn(ACTIVITY_COMPONENT_NAME); return mockInfo; } private void setInvisibleToggleFragmentType(AccessibilityServiceInfo info) { info.getResolveInfo().serviceInfo.applicationInfo.targetSdkVersion = Build.VERSION_CODES.R; info.flags |= AccessibilityServiceInfo.FLAG_REQUEST_ACCESSIBILITY_BUTTON; Loading
tests/robotests/src/com/android/settings/testutils/shadow/ShadowAccessibilityManager.java +23 −1 Original line number Diff line number Diff line Loading @@ -16,15 +16,18 @@ package com.android.settings.testutils.shadow; import android.accessibilityservice.AccessibilityShortcutInfo; import android.annotation.NonNull; import android.annotation.UserIdInt; import android.content.ComponentName; import android.content.Context; import android.util.ArrayMap; import android.view.accessibility.AccessibilityManager; import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; import java.util.List; import java.util.Map; /** Loading @@ -33,9 +36,10 @@ import java.util.Map; @Implements(AccessibilityManager.class) public class ShadowAccessibilityManager extends org.robolectric.shadows.ShadowAccessibilityManager { private Map<ComponentName, ComponentName> mA11yFeatureToTileMap = new ArrayMap<>(); private List<AccessibilityShortcutInfo> mInstalledAccessibilityShortcutList = List.of(); /** * Implements a hidden method {@link AccessibilityManager.getA11yFeatureToTileMap} * Implements a hidden method {@link AccessibilityManager#getA11yFeatureToTileMap} */ @Implementation public Map<ComponentName, ComponentName> getA11yFeatureToTileMap(@UserIdInt int userId) { Loading @@ -49,4 +53,22 @@ public class ShadowAccessibilityManager extends org.robolectric.shadows.ShadowAc @NonNull Map<ComponentName, ComponentName> a11yFeatureToTileMap) { mA11yFeatureToTileMap = a11yFeatureToTileMap; } /** * Implements the hidden method * {@link AccessibilityManager#getInstalledAccessibilityShortcutListAsUser}. */ @Implementation public List<AccessibilityShortcutInfo> getInstalledAccessibilityShortcutListAsUser( @NonNull Context context, @UserIdInt int userId) { return mInstalledAccessibilityShortcutList; } /** * Sets the value to be returned by {@link #getInstalledAccessibilityShortcutListAsUser}. */ public void setInstalledAccessibilityShortcutListAsUser( @NonNull List<AccessibilityShortcutInfo> installedAccessibilityShortcutList) { mInstalledAccessibilityShortcutList = installedAccessibilityShortcutList; } }