Fix indexing in cast and zen mode settings

- Fragment should either not implement serach provider or return a valid
  xml. Search provider with 0 resource is invalid.

Change-Id: Ie87c739bf72c926cecf48d271c6c2d72459787c4
Fixes: 69864274
Test: robotests
This commit is contained in:
Fan Zhang
2017-11-28 16:52:53 -08:00
parent 6a68f306d7
commit 1ae1e17199
9 changed files with 108 additions and 55 deletions

View File

@@ -16,6 +16,9 @@
package com.android.settings.search;
import static com.google.common.truth.Truth.assertWithMessage;
import android.provider.SearchIndexableResource;
import android.util.ArraySet;
import android.util.Log;
@@ -23,13 +26,13 @@ import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.core.codeinspection.CodeInspector;
import com.android.settings.dashboard.DashboardFragmentSearchIndexProviderInspector;
import org.robolectric.RuntimeEnvironment;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static com.google.common.truth.Truth.assertWithMessage;
/**
* {@link CodeInspector} to ensure fragments implement search components correctly.
*/
@@ -49,6 +52,9 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
"Class containing " + DatabaseIndexingManager.FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER
+ " must be added to " + SearchIndexableResources.class.getName()
+ " but these are not: \n";
private static final String NOT_PROVIDING_VALID_RESOURCE_ERROR =
"SearchIndexableProvider must either provide no resource to index, or valid ones. "
+ "But the followings contain resource with xml id = 0\n";
private final List<String> notImplementingIndexableGrandfatherList;
private final List<String> notImplementingIndexProviderGrandfatherList;
@@ -77,6 +83,7 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
final Set<String> notImplementingIndexProvider = new ArraySet<>();
final Set<String> notInSearchProviderRegistry = new ArraySet<>();
final Set<String> notSharingPreferenceControllers = new ArraySet<>();
final Set<String> notProvidingValidResource = new ArraySet<>();
for (Class clazz : mClasses) {
if (!isConcreteSettingsClass(clazz)) {
@@ -119,6 +126,10 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
notInSearchProviderRegistry.add(className);
}
}
// Search provider must either don't provider resource xml, or provide valid ones.
if (!hasValidResourceFromProvider(clazz)) {
notProvidingValidResource.add(className);
}
}
// Build error messages
@@ -131,6 +142,8 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
notSharingPreferenceControllers);
final String notInProviderRegistryError =
buildErrorMessage(NOT_IN_INDEXABLE_PROVIDER_REGISTRY, notInSearchProviderRegistry);
final String notProvidingValidResourceError = buildErrorMessage(
NOT_PROVIDING_VALID_RESOURCE_ERROR, notProvidingValidResource);
assertWithMessage(indexableError)
.that(notImplementingIndexable)
.isEmpty();
@@ -143,6 +156,9 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
assertWithMessage(notInProviderRegistryError)
.that(notInSearchProviderRegistry)
.isEmpty();
assertWithMessage(notProvidingValidResourceError)
.that(notProvidingValidResource)
.isEmpty();
assertNoObsoleteInGrandfatherList("grandfather_not_implementing_indexable",
notImplementingIndexableGrandfatherList);
assertNoObsoleteInGrandfatherList("grandfather_not_implementing_index_provider",
@@ -168,6 +184,28 @@ public class SearchIndexProviderCodeInspector extends CodeInspector {
}
}
private boolean hasValidResourceFromProvider(Class clazz) {
try {
final Indexable.SearchIndexProvider provider =
DatabaseIndexingUtils.getSearchIndexProvider(clazz);
final List<SearchIndexableResource> resources = provider.getXmlResourcesToIndex(
RuntimeEnvironment.application, true /* enabled */);
if (resources == null) {
// No resource, that's fine.
return true;
}
for (SearchIndexableResource res : resources) {
if (res.xmlResId == 0) {
// Invalid resource
return false;
}
}
} catch (Exception e) {
// Ignore.
}
return true;
}
private String buildErrorMessage(String errorSummary, Set<String> errorClasses) {
final StringBuilder error = new StringBuilder(errorSummary);
for (String c : errorClasses) {