Provide installed a11y services/activities from dynamicRawData for search
Bug: 354076686 Flag: com.android.settings.accessibility.fix_a11y_settings_search Test: Search Project Relate and verify the item shows up in the search result Test: Search Talkback with keywords, verify the Talkback shows up in the search result Test: atest AccessibilitySettingsTest Change-Id: I258ecb0928308b7cde30c12104408e11cc25ecd5
This commit is contained in:
@@ -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;
|
||||
|
@@ -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<SearchIndexableRaw> 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);
|
||||
}
|
||||
|
@@ -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<SearchIndexableRaw> getSearchIndexableRawData(Context context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getSynonymsForComponent(@NonNull Context context,
|
||||
@NonNull ComponentName componentName) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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<RestrictedPreference> getInstalledAccessibilityPreferences(Context context,
|
||||
private static List<RestrictedPreference> getInstalledAccessibilityPreferences(Context context,
|
||||
List<AccessibilityShortcutInfo> installedShortcutList,
|
||||
List<AccessibilityServiceInfo> installedServiceList) {
|
||||
final RestrictedPreferenceHelper preferenceHelper = new RestrictedPreferenceHelper(context);
|
||||
@@ -623,6 +623,51 @@ public class AccessibilitySettings extends DashboardFragment implements
|
||||
.getAccessibilitySearchFeatureProvider().getSearchIndexableRawData(
|
||||
context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SearchIndexableRaw> getDynamicRawDataToIndex(Context context,
|
||||
boolean enabled) {
|
||||
List<SearchIndexableRaw> 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<RestrictedPreference> 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
|
||||
|
@@ -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<SearchIndexableRaw> 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(
|
||||
|
Reference in New Issue
Block a user