diff --git a/src/com/android/settings/accessibility/AccessibilityActivityPreference.java b/src/com/android/settings/accessibility/AccessibilityActivityPreference.java index 914d9cf3f84..a8e456d3e35 100644 --- a/src/com/android/settings/accessibility/AccessibilityActivityPreference.java +++ b/src/com/android/settings/accessibility/AccessibilityActivityPreference.java @@ -26,6 +26,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.Log; +import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import com.android.settings.R; @@ -101,6 +102,11 @@ public class AccessibilityActivityPreference extends RestrictedPreference { return mLabel; } + @NonNull + public ComponentName getComponentName() { + return mComponentName; + } + private Drawable getA11yActivityIcon() { ActivityInfo activityInfo = mA11yShortcutInfo.getActivityInfo(); Drawable serviceIcon; diff --git a/src/com/android/settings/accessibility/AccessibilitySearchFeatureProvider.java b/src/com/android/settings/accessibility/AccessibilitySearchFeatureProvider.java index 6aa8c841ed1..6a0b5e216b9 100644 --- a/src/com/android/settings/accessibility/AccessibilitySearchFeatureProvider.java +++ b/src/com/android/settings/accessibility/AccessibilitySearchFeatureProvider.java @@ -16,8 +16,12 @@ package com.android.settings.accessibility; +import android.content.ComponentName; import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.android.settingslib.search.SearchIndexableRaw; import java.util.List; @@ -28,10 +32,22 @@ import java.util.List; public interface AccessibilitySearchFeatureProvider { /** - * Returns a list of raw data for indexing. See {@link SearchIndexableRaw} + * Returns accessibility features to be searched where the accessibility features are always on + * the device and their feature names won't change. * * @param context a valid context {@link Context} instance - * @return a list of {@link SearchIndexableRaw} references. Can be null. + * @return a list of {@link SearchIndexableRaw} references */ + @Nullable List getSearchIndexableRawData(Context context); + + /** + * Returns synonyms of the Accessibility component that is used for search. + * + * @param context the context that is used for grabbing resources + * @param componentName the ComponentName of the accessibility feature + * @return a comma separated synonyms e.g. "wifi, wi-fi, network connection" + */ + @NonNull + String getSynonymsForComponent(@NonNull Context context, @NonNull ComponentName componentName); } diff --git a/src/com/android/settings/accessibility/AccessibilitySearchFeatureProviderImpl.java b/src/com/android/settings/accessibility/AccessibilitySearchFeatureProviderImpl.java index c358af11d06..94594a1a292 100644 --- a/src/com/android/settings/accessibility/AccessibilitySearchFeatureProviderImpl.java +++ b/src/com/android/settings/accessibility/AccessibilitySearchFeatureProviderImpl.java @@ -16,8 +16,12 @@ package com.android.settings.accessibility; +import android.content.ComponentName; import android.content.Context; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import com.android.settingslib.search.SearchIndexableRaw; import java.util.List; @@ -27,8 +31,16 @@ import java.util.List; */ public class AccessibilitySearchFeatureProviderImpl implements AccessibilitySearchFeatureProvider { + @Nullable @Override public List getSearchIndexableRawData(Context context) { return null; } + + @NonNull + @Override + public String getSynonymsForComponent(@NonNull Context context, + @NonNull ComponentName componentName) { + return ""; + } } diff --git a/src/com/android/settings/accessibility/AccessibilityServicePreference.java b/src/com/android/settings/accessibility/AccessibilityServicePreference.java index c1dfae80fb7..8a22d820af9 100644 --- a/src/com/android/settings/accessibility/AccessibilityServicePreference.java +++ b/src/com/android/settings/accessibility/AccessibilityServicePreference.java @@ -26,6 +26,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.util.Log; +import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import com.android.settings.R; @@ -95,6 +96,11 @@ public class AccessibilityServicePreference extends RestrictedPreference { super.performClick(); } + @NonNull + public ComponentName getComponentName() { + return mComponentName; + } + private Drawable getA11yServiceIcon() { ResolveInfo resolveInfo = mA11yServiceInfo.getResolveInfo(); Drawable serviceIcon; diff --git a/src/com/android/settings/accessibility/AccessibilitySettings.java b/src/com/android/settings/accessibility/AccessibilitySettings.java index 8de49365060..db8f9379afe 100644 --- a/src/com/android/settings/accessibility/AccessibilitySettings.java +++ b/src/com/android/settings/accessibility/AccessibilitySettings.java @@ -473,7 +473,7 @@ public class AccessibilitySettings extends DashboardFragment implements * @param installedShortcutList A list of installed {@link AccessibilityShortcutInfo}s. * @param installedServiceList A list of installed {@link AccessibilityServiceInfo}s. */ - private List getInstalledAccessibilityPreferences(Context context, + private static List getInstalledAccessibilityPreferences(Context context, List installedShortcutList, List installedServiceList) { final RestrictedPreferenceHelper preferenceHelper = new RestrictedPreferenceHelper(context); @@ -623,6 +623,51 @@ public class AccessibilitySettings extends DashboardFragment implements .getAccessibilitySearchFeatureProvider().getSearchIndexableRawData( context); } + + @Override + public List getDynamicRawDataToIndex(Context context, + boolean enabled) { + List dynamicRawData = super.getDynamicRawDataToIndex( + context, enabled); + if (dynamicRawData == null) { + dynamicRawData = new ArrayList<>(); + } + if (!Flags.fixA11ySettingsSearch()) { + return dynamicRawData; + } + + AccessibilityManager a11yManager = context.getSystemService( + AccessibilityManager.class); + AccessibilitySearchFeatureProvider a11ySearchFeatureProvider = + FeatureFactory.getFeatureFactory() + .getAccessibilitySearchFeatureProvider(); + List installedA11yFeaturesPref = + AccessibilitySettings.getInstalledAccessibilityPreferences( + context, + a11yManager.getInstalledAccessibilityShortcutListAsUser( + context, UserHandle.myUserId()), + a11yManager.getInstalledAccessibilityServiceList() + ); + for (RestrictedPreference pref : installedA11yFeaturesPref) { + SearchIndexableRaw indexableRaw = new SearchIndexableRaw(context); + indexableRaw.key = pref.getKey(); + indexableRaw.title = pref.getTitle().toString(); + @NonNull String synonyms = ""; + if (pref instanceof AccessibilityServicePreference) { + synonyms = a11ySearchFeatureProvider.getSynonymsForComponent( + context, + ((AccessibilityServicePreference) pref).getComponentName()); + } else if (pref instanceof AccessibilityActivityPreference) { + synonyms = a11ySearchFeatureProvider.getSynonymsForComponent( + context, + ((AccessibilityActivityPreference) pref).getComponentName()); + } + indexableRaw.keywords = synonyms; + dynamicRawData.add(indexableRaw); + } + + return dynamicRawData; + } }; @Override diff --git a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java index 3982dc0c68c..36578a90e25 100644 --- a/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java +++ b/tests/robotests/src/com/android/settings/accessibility/AccessibilitySettingsTest.java @@ -42,7 +42,6 @@ import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.Settings; import android.view.accessibility.AccessibilityManager; -import android.view.accessibility.Flags; import androidx.fragment.app.Fragment; import androidx.test.core.app.ApplicationProvider; @@ -50,6 +49,7 @@ import androidx.test.core.app.ApplicationProvider; import com.android.internal.accessibility.util.AccessibilityUtils; import com.android.settings.R; import com.android.settings.SettingsActivity; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settings.testutils.XmlTestUtils; import com.android.settings.testutils.shadow.ShadowAccessibilityManager; import com.android.settings.testutils.shadow.ShadowApplicationPackageManager; @@ -78,6 +78,7 @@ import org.robolectric.android.controller.ActivityController; import org.robolectric.annotation.Config; import org.robolectric.shadow.api.Shadow; import org.robolectric.shadows.ShadowContentResolver; +import org.robolectric.shadows.ShadowLooper; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; @@ -155,6 +156,53 @@ public class AccessibilitySettingsTest { assertThat(indexableRawList).isNull(); } + @DisableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + @Test + public void getDynamicRawDataToIndex_hasInstalledA11yFeatures_flagOff_returnEmpty() { + mShadowAccessibilityManager.setInstalledAccessibilityServiceList( + List.of(mServiceInfo)); + mShadowAccessibilityManager.setInstalledAccessibilityShortcutListAsUser( + List.of(getMockAccessibilityShortcutInfo())); + + assertThat(AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER.getDynamicRawDataToIndex( + mContext, /* enabled= */ true)) + .isEmpty(); + } + + @EnableFlags(Flags.FLAG_FIX_A11Y_SETTINGS_SEARCH) + @Test + public void getDynamicRawDataToIndex_hasInstalledA11yFeatures_flagOn_returnRawDataForInstalledA11yFeatures() { + mShadowAccessibilityManager.setInstalledAccessibilityServiceList( + List.of(mServiceInfo)); + mShadowAccessibilityManager.setInstalledAccessibilityShortcutListAsUser( + List.of(getMockAccessibilityShortcutInfo())); + final AccessibilitySearchFeatureProvider featureProvider = + FakeFeatureFactory.setupForTest().getAccessibilitySearchFeatureProvider(); + final String synonyms = "fake keyword1, fake keyword2"; + when(featureProvider.getSynonymsForComponent(mContext, ACTIVITY_COMPONENT_NAME)) + .thenReturn(""); + when(featureProvider.getSynonymsForComponent(mContext, SERVICE_COMPONENT_NAME)) + .thenReturn(synonyms); + + final List indexableRawDataList = + AccessibilitySettings.SEARCH_INDEX_DATA_PROVIDER.getDynamicRawDataToIndex( + mContext, /* enabled= */ true); + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); + + assertThat(indexableRawDataList).hasSize(2); + SearchIndexableRaw a11yActivityIndexableData = indexableRawDataList.get(0); + assertThat(a11yActivityIndexableData.key).isEqualTo( + ACTIVITY_COMPONENT_NAME.flattenToString()); + assertThat(a11yActivityIndexableData.title).isEqualTo(DEFAULT_LABEL); + assertThat(a11yActivityIndexableData.keywords).isEmpty(); + + SearchIndexableRaw a11yServiceIndexableData = indexableRawDataList.get(1); + assertThat(a11yServiceIndexableData.key).isEqualTo( + SERVICE_COMPONENT_NAME.flattenToString()); + assertThat(a11yServiceIndexableData.title).isEqualTo(DEFAULT_LABEL); + assertThat(a11yServiceIndexableData.keywords).isEqualTo(synonyms); + } + @Test public void getServiceSummary_serviceCrash_showsStopped() { mServiceInfo.crashed = true; @@ -328,7 +376,7 @@ public class AccessibilitySettingsTest { } @Test - @DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + @DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) public void onCreate_flagDisabled_haveRegisterToSpecificUrisAndActions() { setupFragment(); @@ -341,7 +389,7 @@ public class AccessibilitySettingsTest { } @Test - @EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT) + @EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT) public void onCreate_flagEnabled_haveRegisterToSpecificUrisAndActions() { setupFragment(); @@ -415,7 +463,7 @@ public class AccessibilitySettingsTest { } @Test - @EnableFlags(com.android.settings.accessibility.Flags.FLAG_CHECK_PREBUNDLED_IS_PREINSTALLED) + @EnableFlags(Flags.FLAG_CHECK_PREBUNDLED_IS_PREINSTALLED) public void testNonPreinstalledApp_IncludedInDownloadedCategory() { mShadowAccessibilityManager.setInstalledAccessibilityServiceList( List.of(getMockAccessibilityServiceInfo(