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.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -101,6 +102,11 @@ public class AccessibilityActivityPreference extends RestrictedPreference {
|
|||||||
return mLabel;
|
return mLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public ComponentName getComponentName() {
|
||||||
|
return mComponentName;
|
||||||
|
}
|
||||||
|
|
||||||
private Drawable getA11yActivityIcon() {
|
private Drawable getA11yActivityIcon() {
|
||||||
ActivityInfo activityInfo = mA11yShortcutInfo.getActivityInfo();
|
ActivityInfo activityInfo = mA11yShortcutInfo.getActivityInfo();
|
||||||
Drawable serviceIcon;
|
Drawable serviceIcon;
|
||||||
|
@@ -16,8 +16,12 @@
|
|||||||
|
|
||||||
package com.android.settings.accessibility;
|
package com.android.settings.accessibility;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.settingslib.search.SearchIndexableRaw;
|
import com.android.settingslib.search.SearchIndexableRaw;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -28,10 +32,22 @@ import java.util.List;
|
|||||||
public interface AccessibilitySearchFeatureProvider {
|
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
|
* @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);
|
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;
|
package com.android.settings.accessibility;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.android.settingslib.search.SearchIndexableRaw;
|
import com.android.settingslib.search.SearchIndexableRaw;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -27,8 +31,16 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class AccessibilitySearchFeatureProviderImpl implements AccessibilitySearchFeatureProvider {
|
public class AccessibilitySearchFeatureProviderImpl implements AccessibilitySearchFeatureProvider {
|
||||||
|
|
||||||
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public List<SearchIndexableRaw> getSearchIndexableRawData(Context context) {
|
public List<SearchIndexableRaw> getSearchIndexableRawData(Context context) {
|
||||||
return null;
|
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.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
@@ -95,6 +96,11 @@ public class AccessibilityServicePreference extends RestrictedPreference {
|
|||||||
super.performClick();
|
super.performClick();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public ComponentName getComponentName() {
|
||||||
|
return mComponentName;
|
||||||
|
}
|
||||||
|
|
||||||
private Drawable getA11yServiceIcon() {
|
private Drawable getA11yServiceIcon() {
|
||||||
ResolveInfo resolveInfo = mA11yServiceInfo.getResolveInfo();
|
ResolveInfo resolveInfo = mA11yServiceInfo.getResolveInfo();
|
||||||
Drawable serviceIcon;
|
Drawable serviceIcon;
|
||||||
|
@@ -473,7 +473,7 @@ public class AccessibilitySettings extends DashboardFragment implements
|
|||||||
* @param installedShortcutList A list of installed {@link AccessibilityShortcutInfo}s.
|
* @param installedShortcutList A list of installed {@link AccessibilityShortcutInfo}s.
|
||||||
* @param installedServiceList A list of installed {@link AccessibilityServiceInfo}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<AccessibilityShortcutInfo> installedShortcutList,
|
||||||
List<AccessibilityServiceInfo> installedServiceList) {
|
List<AccessibilityServiceInfo> installedServiceList) {
|
||||||
final RestrictedPreferenceHelper preferenceHelper = new RestrictedPreferenceHelper(context);
|
final RestrictedPreferenceHelper preferenceHelper = new RestrictedPreferenceHelper(context);
|
||||||
@@ -623,6 +623,51 @@ public class AccessibilitySettings extends DashboardFragment implements
|
|||||||
.getAccessibilitySearchFeatureProvider().getSearchIndexableRawData(
|
.getAccessibilitySearchFeatureProvider().getSearchIndexableRawData(
|
||||||
context);
|
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
|
@Override
|
||||||
|
@@ -42,7 +42,6 @@ import android.platform.test.annotations.EnableFlags;
|
|||||||
import android.platform.test.flag.junit.SetFlagsRule;
|
import android.platform.test.flag.junit.SetFlagsRule;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.view.accessibility.AccessibilityManager;
|
import android.view.accessibility.AccessibilityManager;
|
||||||
import android.view.accessibility.Flags;
|
|
||||||
|
|
||||||
import androidx.fragment.app.Fragment;
|
import androidx.fragment.app.Fragment;
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
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.internal.accessibility.util.AccessibilityUtils;
|
||||||
import com.android.settings.R;
|
import com.android.settings.R;
|
||||||
import com.android.settings.SettingsActivity;
|
import com.android.settings.SettingsActivity;
|
||||||
|
import com.android.settings.testutils.FakeFeatureFactory;
|
||||||
import com.android.settings.testutils.XmlTestUtils;
|
import com.android.settings.testutils.XmlTestUtils;
|
||||||
import com.android.settings.testutils.shadow.ShadowAccessibilityManager;
|
import com.android.settings.testutils.shadow.ShadowAccessibilityManager;
|
||||||
import com.android.settings.testutils.shadow.ShadowApplicationPackageManager;
|
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.annotation.Config;
|
||||||
import org.robolectric.shadow.api.Shadow;
|
import org.robolectric.shadow.api.Shadow;
|
||||||
import org.robolectric.shadows.ShadowContentResolver;
|
import org.robolectric.shadows.ShadowContentResolver;
|
||||||
|
import org.robolectric.shadows.ShadowLooper;
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -155,6 +156,53 @@ public class AccessibilitySettingsTest {
|
|||||||
assertThat(indexableRawList).isNull();
|
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
|
@Test
|
||||||
public void getServiceSummary_serviceCrash_showsStopped() {
|
public void getServiceSummary_serviceCrash_showsStopped() {
|
||||||
mServiceInfo.crashed = true;
|
mServiceInfo.crashed = true;
|
||||||
@@ -328,7 +376,7 @@ public class AccessibilitySettingsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DisableFlags(Flags.FLAG_A11Y_QS_SHORTCUT)
|
@DisableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
|
||||||
public void onCreate_flagDisabled_haveRegisterToSpecificUrisAndActions() {
|
public void onCreate_flagDisabled_haveRegisterToSpecificUrisAndActions() {
|
||||||
setupFragment();
|
setupFragment();
|
||||||
|
|
||||||
@@ -341,7 +389,7 @@ public class AccessibilitySettingsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFlags(Flags.FLAG_A11Y_QS_SHORTCUT)
|
@EnableFlags(android.view.accessibility.Flags.FLAG_A11Y_QS_SHORTCUT)
|
||||||
public void onCreate_flagEnabled_haveRegisterToSpecificUrisAndActions() {
|
public void onCreate_flagEnabled_haveRegisterToSpecificUrisAndActions() {
|
||||||
setupFragment();
|
setupFragment();
|
||||||
|
|
||||||
@@ -415,7 +463,7 @@ public class AccessibilitySettingsTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@EnableFlags(com.android.settings.accessibility.Flags.FLAG_CHECK_PREBUNDLED_IS_PREINSTALLED)
|
@EnableFlags(Flags.FLAG_CHECK_PREBUNDLED_IS_PREINSTALLED)
|
||||||
public void testNonPreinstalledApp_IncludedInDownloadedCategory() {
|
public void testNonPreinstalledApp_IncludedInDownloadedCategory() {
|
||||||
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(
|
mShadowAccessibilityManager.setInstalledAccessibilityServiceList(
|
||||||
List.of(getMockAccessibilityServiceInfo(
|
List.of(getMockAccessibilityServiceInfo(
|
||||||
|
Reference in New Issue
Block a user