From 55ce64dcd9e0dfc7bca23b3aba309c9daaaf6fa3 Mon Sep 17 00:00:00 2001 From: Matthew Fritze Date: Fri, 3 Nov 2017 12:03:59 -0700 Subject: [PATCH] Move Index provider conversion into Settings provider Pre-patch, settings search provider would push all of its fragments into to search via SearchIndexableResources with an implicit contract of if the resource's xml == 0, then it was a settings fragment with an Index provider. One, implicit contract is bad. Two, it was messy at indexing time. So this patch moves htat conversion into the search index provider. Such that all of the indexables are either real Resources or Raw. Change-Id: I39f4351c03d123bb9b45edb4df7f924cfaff2b38 Fixes: 65376542 Fixes: 37741509 Test: robotests --- .../search/SearchIndexableResources.java | 29 +--- .../SettingsSearchIndexablesProvider.java | 145 ++++++++++++++---- .../search/indexing/IndexDataConverter.java | 92 +---------- .../SearchIndexProviderCodeInspector.java | 3 +- .../search/SearchIndexableResourcesTest.java | 52 +++---- .../SettingsSearchIndexablesProviderTest.java | 119 ++++++++++++++ .../indexing/IndexDataConverterTest.java | 49 ------ .../PreferenceControllerContractTest.java | 3 +- .../settings/core/UniquePreferenceTest.java | 22 +-- 9 files changed, 278 insertions(+), 236 deletions(-) create mode 100644 tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java index 69b2f9fa5d3..36e4edf9099 100644 --- a/src/com/android/settings/search/SearchIndexableResources.java +++ b/src/com/android/settings/search/SearchIndexableResources.java @@ -16,9 +16,7 @@ package com.android.settings.search; -import android.provider.SearchIndexableResource; import android.support.annotation.VisibleForTesting; -import android.support.annotation.XmlRes; import com.android.settings.DateTimeSettings; import com.android.settings.DeviceInfoSettings; @@ -88,22 +86,17 @@ import com.android.settings.wifi.ConfigureWifiSettings; import com.android.settings.wifi.WifiSettings; import java.util.Collection; -import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; public final class SearchIndexableResources { - @XmlRes - public static final int NO_RES_ID = 0; @VisibleForTesting - static final HashMap sResMap = new HashMap<>(); + static final Set sProviders = new HashSet<>(); @VisibleForTesting - static void addIndex(Class indexClass) { - String className = indexClass.getName(); - SearchIndexableResource resource = new SearchIndexableResource( - 0 /* rank */, NO_RES_ID, className, NO_RES_ID); - - sResMap.put(className, resource); + static void addIndex(Class indexClass) { + sProviders.add(indexClass); } static { @@ -178,15 +171,5 @@ public final class SearchIndexableResources { private SearchIndexableResources() { } - public static int size() { - return sResMap.size(); - } - - public static SearchIndexableResource getResourceByName(String className) { - return sResMap.get(className); - } - - public static Collection values() { - return sResMap.values(); - } + public static Collection providerValues() { return sProviders;} } \ No newline at end of file diff --git a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java index 622378b9179..968847b9b27 100644 --- a/src/com/android/settings/search/SettingsSearchIndexablesProvider.java +++ b/src/com/android/settings/search/SettingsSearchIndexablesProvider.java @@ -17,6 +17,19 @@ package com.android.settings.search; import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_CLASS_NAME; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ENTRIES; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ICON_RESID; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_ACTION; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_CLASS; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEY; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEYWORDS; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SCREEN_TITLE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_OFF; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_ON; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_TITLE; +import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_USER_ID; import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME; import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID; import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION; @@ -33,11 +46,12 @@ import android.database.Cursor; import android.database.MatrixCursor; import android.provider.SearchIndexableResource; import android.provider.SearchIndexablesProvider; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; +import java.util.ArrayList; import java.util.Collection; -import java.util.HashSet; import java.util.List; public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { @@ -60,8 +74,9 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { @Override public Cursor queryXmlResources(String[] projection) { MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS); - Collection values = SearchIndexableResources.values(); - for (SearchIndexableResource val : values) { + final List resources = + getSearchIndexableResourcesFromProvider(getContext()); + for (SearchIndexableResource val : resources) { Object[] ref = new Object[INDEXABLES_XML_RES_COLUMNS.length]; ref[COLUMN_INDEX_XML_RES_RANK] = val.rank; ref[COLUMN_INDEX_XML_RES_RESID] = val.xmlResId; @@ -72,13 +87,33 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { ref[COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS] = null; // intent target class cursor.addRow(ref); } + return cursor; } @Override public Cursor queryRawData(String[] projection) { - MatrixCursor result = new MatrixCursor(INDEXABLES_RAW_COLUMNS); - return result; + MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS); + final List raws = getSearchIndexableRawFromProvider(getContext()); + for (SearchIndexableRaw val : raws) { + Object[] ref = new Object[INDEXABLES_RAW_COLUMNS.length]; + ref[COLUMN_INDEX_RAW_TITLE] = val.title; + ref[COLUMN_INDEX_RAW_SUMMARY_ON] = val.summaryOn; + ref[COLUMN_INDEX_RAW_SUMMARY_OFF] = val.summaryOff; + ref[COLUMN_INDEX_RAW_ENTRIES] = val.entries; + ref[COLUMN_INDEX_RAW_KEYWORDS] = val.keywords; + ref[COLUMN_INDEX_RAW_SCREEN_TITLE] = val.screenTitle; + ref[COLUMN_INDEX_RAW_CLASS_NAME] = val.className; + ref[COLUMN_INDEX_RAW_ICON_RESID] = val.iconResId; + ref[COLUMN_INDEX_RAW_INTENT_ACTION] = val.intentAction; + ref[COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE] = val.intentTargetPackage; + ref[COLUMN_INDEX_RAW_INTENT_TARGET_CLASS] = val.intentTargetClass; + ref[COLUMN_INDEX_RAW_KEY] = val.key; + ref[COLUMN_INDEX_RAW_USER_ID] = val.userId; + cursor.addRow(ref); + } + + return cursor; } /** @@ -89,29 +124,24 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { @Override public Cursor queryNonIndexableKeys(String[] projection) { MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS); - final Collection values = new HashSet<>(); - final Context context = getContext(); + final List nonIndexableKeys = getNonIndexableKeysFromProvider(getContext()); + for (String nik : nonIndexableKeys) { + final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length]; + ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = nik; + cursor.addRow(ref); + } - for (SearchIndexableResource sir : SearchIndexableResources.values()) { - if (DEBUG) { - Log.d(TAG, "Getting non-indexable from " + sir.className); - } + return cursor; + } + + private List getNonIndexableKeysFromProvider(Context context) { + final Collection values = SearchIndexableResources.providerValues(); + final List nonIndexableKeys = new ArrayList<>(); + + for (Class clazz : values) { final long startTime = System.currentTimeMillis(); - final Class clazz = DatabaseIndexingUtils.getIndexableClass(sir.className); - if (clazz == null) { - Log.d(TAG, "SearchIndexableResource '" + sir.className + - "' should implement the " + Indexable.class.getName() + " interface!"); - continue; - } - - final Indexable.SearchIndexProvider provider = - DatabaseIndexingUtils.getSearchIndexProvider(clazz); - - if (provider == null) { - Log.d(TAG, "Unable to get SearchIndexableProvider from " + clazz); - continue; - } - + Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider( + clazz); List providerNonIndexableKeys = provider.getNonIndexableKeys(context); if (providerNonIndexableKeys == null || providerNonIndexableKeys.isEmpty()) { @@ -123,22 +153,71 @@ public class SettingsSearchIndexablesProvider extends SearchIndexablesProvider { } if (providerNonIndexableKeys.removeAll(INVALID_KEYS)) { - Log.v(TAG, clazz.getName() + " tried to add an empty non-indexable key"); + Log.v(TAG, provider + " tried to add an empty non-indexable key"); } + if (DEBUG) { final long totalTime = System.currentTimeMillis() - startTime; Log.d(TAG, "Non-indexables " + providerNonIndexableKeys.size() + ", total time " + totalTime); } - values.addAll(providerNonIndexableKeys); + + nonIndexableKeys.addAll(providerNonIndexableKeys); } - for (String nik : values) { + return nonIndexableKeys; + } - final Object[] ref = new Object[NON_INDEXABLES_KEYS_COLUMNS.length]; - ref[COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE] = nik; - cursor.addRow(ref); + private List getSearchIndexableResourcesFromProvider(Context context) { + Collection values = SearchIndexableResources.providerValues(); + List resourceList = new ArrayList<>(); + + for (Class clazz : values) { + Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider( + clazz); + + final List resList = + provider.getXmlResourcesToIndex(context, true); + + if (resList == null) { + continue; + } + + for (SearchIndexableResource item : resList) { + item.className = TextUtils.isEmpty(item.className) + ? clazz.getName() + : item.className; + } + + resourceList.addAll(resList); } - return cursor; + + return resourceList; + } + + private List getSearchIndexableRawFromProvider(Context context) { + final Collection values = SearchIndexableResources.providerValues(); + final List rawList = new ArrayList<>(); + + for (Class clazz : values) { + Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider( + clazz); + final List providerRaws = provider.getRawDataToIndex(context, + true /* enabled */); + + if (providerRaws == null) { + continue; + } + + for (SearchIndexableRaw raw : providerRaws) { + // The classname and intent information comes from the PreIndexData + // This will be more clear when provider conversion is done at PreIndex time. + raw.className = clazz.getName(); + + } + rawList.addAll(providerRaws); + } + + return rawList; } } diff --git a/src/com/android/settings/search/indexing/IndexDataConverter.java b/src/com/android/settings/search/indexing/IndexDataConverter.java index ab60f62f568..65fa279ee7d 100644 --- a/src/com/android/settings/search/indexing/IndexDataConverter.java +++ b/src/com/android/settings/search/indexing/IndexDataConverter.java @@ -31,7 +31,6 @@ import android.util.Xml; import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.search.DatabaseIndexingUtils; -import com.android.settings.search.Indexable; import com.android.settings.search.ResultPayload; import com.android.settings.search.SearchIndexableRaw; import com.android.settings.search.XmlParserUtils; @@ -89,21 +88,8 @@ public class IndexDataConverter { final SearchIndexableResource sir = (SearchIndexableResource) data; final Set resourceNonIndexableKeys = getNonIndexableKeysForResource(nonIndexableKeys, sir.packageName); - - if (sir.xmlResId == 0) { - // Index from provider - final Indexable.SearchIndexProvider provider = getSearchProvider(sir); - if (provider == null) { - continue; - } - indexData.addAll(convertIndexProvider(provider, sir, resourceNonIndexableKeys)); - - } else { - final List resourceData = convertResource(sir, - resourceNonIndexableKeys); - indexData.addAll(resourceData); - } - + final List resourceData = convertResource(sir, resourceNonIndexableKeys); + indexData.addAll(resourceData); } } @@ -305,84 +291,10 @@ public class IndexDataConverter { return resourceIndexData; } - private List convertIndexProvider(Indexable.SearchIndexProvider provider, - SearchIndexableResource sir, Set nonIndexableKeys) { - final List indexData = new ArrayList<>(); - - final String className = sir.className; - final String intentAction = sir.intentAction; - final String intentTargetPackage = sir.intentTargetPackage; - - // TODO (b/65376542) Move provider conversion to PreIndexTime - // TODO (b/37741509) Providers don't use general non-indexable keys - nonIndexableKeys.addAll(provider.getNonIndexableKeys(mContext)); - - final List rawList = provider.getRawDataToIndex(mContext, - true /* enabled */); - - if (rawList != null) { - for (SearchIndexableRaw raw : rawList) { - // The classname and intent information comes from the PreIndexData - // This will be more clear when provider conversion is done at PreIndex time. - raw.className = className; - raw.intentAction = intentAction; - raw.intentTargetPackage = intentTargetPackage; - - IndexData.Builder builder = convertRaw(raw, nonIndexableKeys); - if (builder != null) { - indexData.add(builder.build(mContext)); - } - } - } - - final List resList = - provider.getXmlResourcesToIndex(mContext, true); - - if (resList != null) { - for (SearchIndexableResource item : resList) { - item.className = TextUtils.isEmpty(item.className) - ? className - : item.className; - item.intentAction = TextUtils.isEmpty(item.intentAction) - ? intentAction - : item.intentAction; - item.intentTargetPackage = TextUtils.isEmpty(item.intentTargetPackage) - ? intentTargetPackage - : item.intentTargetPackage; - - indexData.addAll(convertResource(item, nonIndexableKeys)); - } - } - - return indexData; - } - private Set getNonIndexableKeysForResource(Map> nonIndexableKeys, String packageName) { return nonIndexableKeys.containsKey(packageName) ? nonIndexableKeys.get(packageName) : new HashSet<>(); } - - /** - * @return Return the {@link Indexable.SearchIndexProvider} corresponding to the - * class specified by the Class name specified by {@param sir}. - */ - private Indexable.SearchIndexProvider getSearchProvider(SearchIndexableResource sir) { - if (TextUtils.isEmpty(sir.className)) { - Log.w(LOG_TAG, "Cannot index an empty Search Provider name!"); - return null; - } - - final Class clazz = DatabaseIndexingUtils.getIndexableClass(sir.className); - if (clazz == null) { - Log.d(LOG_TAG, "SearchIndexableResource '" + sir.className + - "' should implement the " + Indexable.class.getName() + " interface!"); - return null; - } - - // Will be non null only for a Local provider implementing a - // SEARCH_INDEX_DATA_PROVIDER field - return DatabaseIndexingUtils.getSearchIndexProvider(clazz); - } } diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java index b4a91c57fba..3c51a90a51f 100644 --- a/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java +++ b/tests/robotests/src/com/android/settings/search/SearchIndexProviderCodeInspector.java @@ -114,11 +114,10 @@ public class SearchIndexProviderCodeInspector extends CodeInspector { continue; } // Must be in SearchProviderRegistry - if (SearchIndexableResources.getResourceByName(className) == null) { + if (!SearchIndexableResources.providerValues().contains(clazz)) { if (!notInSearchIndexableRegistryGrandfatherList.remove(className)) { notInSearchProviderRegistry.add(className); } - continue; } } diff --git a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java index 0e3ce502c2f..eedb324ce28 100644 --- a/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java +++ b/tests/robotests/src/com/android/settings/search/SearchIndexableResourcesTest.java @@ -17,12 +17,13 @@ package com.android.settings.search; import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE; -import static com.android.settings.search.SearchIndexableResources.NO_RES_ID; import static com.google.common.truth.Truth.assertThat; + +import static junit.framework.Assert.fail; + import static org.mockito.Mockito.spy; import android.database.Cursor; -import android.provider.SearchIndexableResource; import android.text.TextUtils; import com.android.settings.TestConfig; @@ -35,60 +36,48 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; -import java.util.HashMap; -import java.util.Map; +import java.util.HashSet; +import java.util.Set; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) public class SearchIndexableResourcesTest { - Map sResMapCopy; + Set sProviderClassCopy; @Before public void setUp() { - sResMapCopy = new HashMap<>(SearchIndexableResources.sResMap); + sProviderClassCopy = new HashSet<>(SearchIndexableResources.sProviders); } @After public void cleanUp() { - SearchIndexableResources.sResMap.clear(); - for (String key : sResMapCopy.keySet()) { - SearchIndexableResources.sResMap.put(key, sResMapCopy.get(key)); - } + SearchIndexableResources.sProviders.clear(); + SearchIndexableResources.sProviders.addAll(sProviderClassCopy); } @Test public void testAddIndex() { + final Class stringClass = java.lang.String.class; // Confirms that String.class isn't contained in SearchIndexableResources. - assertThat(SearchIndexableResources.getResourceByName("java.lang.String")).isNull(); - final int beforeCount = SearchIndexableResources.values().size(); + assertThat(SearchIndexableResources.sProviders).doesNotContain(stringClass); + final int beforeCount = SearchIndexableResources.providerValues().size(); SearchIndexableResources.addIndex(java.lang.String.class); - final SearchIndexableResource index = SearchIndexableResources - .getResourceByName("java.lang.String"); - assertThat(index).isNotNull(); - assertThat(index.className).isEqualTo("java.lang.String"); - assertThat(index.xmlResId).isEqualTo(NO_RES_ID); - assertThat(index.iconResId).isEqualTo(NO_RES_ID); - final int afterCount = SearchIndexableResources.values().size(); + assertThat(SearchIndexableResources.sProviders).contains(stringClass); + final int afterCount = SearchIndexableResources.providerValues().size(); assertThat(afterCount).isEqualTo(beforeCount + 1); } @Test public void testIndexHasWifiSettings() { - final SearchIndexableResource index = SearchIndexableResources - .getResourceByName(WifiSettings.class.getName()); - - assertThat(index).isNotNull(); - assertThat(index.className).isEqualTo(WifiSettings.class.getName()); - assertThat(index.xmlResId).isEqualTo(NO_RES_ID); - assertThat(index.iconResId).isEqualTo(NO_RES_ID); + assertThat(sProviderClassCopy).contains(WifiSettings.class); } @Test public void testNonIndexableKeys_GetsKeyFromProvider() { - SearchIndexableResources.sResMap.clear(); + SearchIndexableResources.sProviders.clear(); SearchIndexableResources.addIndex(FakeIndexProvider.class); SettingsSearchIndexablesProvider provider = spy(new SettingsSearchIndexablesProvider()); @@ -105,4 +94,13 @@ public class SearchIndexableResourcesTest { assertThat(hasTestKey).isTrue(); } + + @Test + public void testAllClassNamesHaveProviders() { + for (Class clazz: sProviderClassCopy) { + if(DatabaseIndexingUtils.getSearchIndexProvider(clazz) == null) { + fail(clazz.getName() + "is not an index provider"); + } + } + } } diff --git a/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java new file mode 100644 index 00000000000..efeaed71cd2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/search/SettingsSearchIndexablesProviderTest.java @@ -0,0 +1,119 @@ +package com.android.settings.search; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; + +import android.Manifest; +import android.content.Context; +import android.content.pm.ProviderInfo; +import android.database.Cursor; +import android.net.Uri; +import android.provider.SearchIndexablesContract; + +import com.android.settings.R; +import com.android.settings.TestConfig; +import com.android.settings.search.indexing.FakeSettingsFragment; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.HashSet; +import java.util.Set; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class SettingsSearchIndexablesProviderTest { + + private final String BASE_AUTHORITY = "com.android.settings"; + + private SettingsSearchIndexablesProvider mProvider; + + Set sProviderClasses; + Context mContext; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + + mProvider = spy(new SettingsSearchIndexablesProvider()); + ProviderInfo info = new ProviderInfo(); + info.exported = true; + info.grantUriPermissions = true; + info.authority = BASE_AUTHORITY; + info.readPermission = Manifest.permission.READ_SEARCH_INDEXABLES; + mProvider.attachInfo(mContext, info); + + sProviderClasses = new HashSet<>(SearchIndexableResources.sProviders); + SearchIndexableResources.sProviders.clear(); + SearchIndexableResources.sProviders.add(FakeSettingsFragment.class); + } + + @After + public void cleanUp() { + SearchIndexableResources.sProviders.clear(); + SearchIndexableResources.sProviders.addAll(sProviderClasses); + } + + @Test + public void testRawColumnFetched() { + Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" + + SearchIndexablesContract.INDEXABLES_RAW_PATH); + + final Cursor cursor = mProvider.query(rawUri, + SearchIndexablesContract.INDEXABLES_RAW_COLUMNS, null, null, null); + + cursor.moveToFirst(); + assertThat(cursor.getString(1)).isEqualTo(FakeSettingsFragment.TITLE); + assertThat(cursor.getString(2)).isEqualTo(FakeSettingsFragment.SUMMARY_ON); + assertThat(cursor.getString(3)).isEqualTo(FakeSettingsFragment.SUMMARY_OFF); + assertThat(cursor.getString(4)).isEqualTo(FakeSettingsFragment.ENTRIES); + assertThat(cursor.getString(5)).isEqualTo(FakeSettingsFragment.KEYWORDS); + assertThat(cursor.getString(6)).isEqualTo(FakeSettingsFragment.SCREEN_TITLE); + assertThat(cursor.getString(7)).isEqualTo(FakeSettingsFragment.CLASS_NAME); + assertThat(cursor.getInt(8)).isEqualTo(FakeSettingsFragment.ICON); + assertThat(cursor.getString(9)).isEqualTo(FakeSettingsFragment.INTENT_ACTION); + assertThat(cursor.getString(10)).isEqualTo(FakeSettingsFragment.TARGET_PACKAGE); + assertThat(cursor.getString(11)).isEqualTo(FakeSettingsFragment.TARGET_CLASS); + assertThat(cursor.getString(12)).isEqualTo(FakeSettingsFragment.KEY); + } + + @Test + public void testResourcesColumnFetched() { + Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" + + SearchIndexablesContract.INDEXABLES_XML_RES_PATH); + + final Cursor cursor = mProvider.query(rawUri, + SearchIndexablesContract.INDEXABLES_XML_RES_COLUMNS, null, null, null); + + cursor.moveToFirst(); + assertThat(cursor.getCount()).isEqualTo(1); + assertThat(cursor.getInt(1)).isEqualTo(R.xml.display_settings); + assertThat(cursor.getString(2)).isEqualTo(FakeSettingsFragment.CLASS_NAME); + assertThat(cursor.getInt(3)).isEqualTo(0); + assertThat(cursor.getString(4)).isNull(); + assertThat(cursor.getString(5)).isNull(); + assertThat(cursor.getString(6)).isNull(); + } + + @Test + public void testNonIndexablesColumnFetched() { + Uri rawUri = Uri.parse("content://" + BASE_AUTHORITY + "/" + + SearchIndexablesContract.NON_INDEXABLES_KEYS_PATH); + //final ContentResolver resolver = mContext.getContentResolver(); + + final Cursor cursor = mProvider.query(rawUri, + SearchIndexablesContract.NON_INDEXABLES_KEYS_COLUMNS, null, null, null); + + cursor.moveToFirst(); + assertThat(cursor.getCount()).isEqualTo(2); + assertThat(cursor.getString(0)).isEqualTo("pref_key_1"); + cursor.moveToNext(); + assertThat(cursor.getString(0)).isEqualTo("pref_key_3"); + } +} diff --git a/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java b/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java index b95bfe8cb72..0f2ab56f735 100644 --- a/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java +++ b/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java @@ -266,55 +266,6 @@ public class IndexDataConverterTest { assertThat(row.iconResId).isGreaterThan(0); } - // Tests for the flow: IndexOneResource -> IndexFromProvider -> IndexFromResource -> - // UpdateOneRowWithFilteredData -> UpdateOneRow - - @Test - public void testAddProviderWithResource_rowInserted() { - final SearchIndexableResource resource = getFakeResource(0 /* xml */); - resource.className = FAKE_CLASS_NAME; - final PreIndexData preIndexData = new PreIndexData(); - preIndexData.dataToUpdate.add(resource); - - List indexData = mConverter.convertPreIndexDataToIndexData(preIndexData); - - assertThat(indexData.size()).isEqualTo(NUM_FAKE_FRAGMENT_ENTRIES); - assertThat(findIndexDataForTitle(indexData, PAGE_TITLE)).isNotNull(); - assertThat(findIndexDataForTitle(indexData, TITLE_ONE)).isNotNull(); - assertThat(findIndexDataForTitle(indexData, TITLE_TWO)).isNotNull(); - assertThat(findIndexDataForTitle(indexData, TITLE_THREE)).isNotNull(); - assertThat(findIndexDataForTitle(indexData, TITLE_FOUR)).isNotNull(); - assertThat(findIndexDataForTitle(indexData, TITLE_FIVE)).isNotNull(); - assertThat(findIndexDataForTitle(indexData, FakeSettingsFragment.TITLE)).isNotNull(); - } - - @Test - public void testAddProviderWithRaw_rowInserted() { - final SearchIndexableResource resource = getFakeResource(0 /* xml */); - resource.className = FAKE_CLASS_NAME; - final PreIndexData preIndexData = new PreIndexData(); - preIndexData.dataToUpdate.add(resource); - - List indexData = mConverter.convertPreIndexDataToIndexData(preIndexData); - - final IndexData data = findIndexDataForTitle(indexData, FakeSettingsFragment.TITLE); - assertFakeFragment(data); - } - - @Test - public void testAddProvider_disabledRows() { - // Note that in FakeSettingsFragment, preferences 1 and 3 are disabled. - final SearchIndexableResource resource = getFakeResource(0 /* xml */); - resource.className = FAKE_CLASS_NAME; - - final PreIndexData preIndexData = new PreIndexData(); - preIndexData.dataToUpdate.add(resource); - - List indexData = mConverter.convertPreIndexDataToIndexData(preIndexData); - - assertThat(getEnabledResultCount(indexData)).isEqualTo(NUM_ENABLED_FAKE_FRAGMENT_ENTRIES); - } - @Test public void testResource_sameTitleForSettingAndPage_titleNotInserted() { final SearchIndexableResource resource = getFakeResource(R.xml.about_legal); diff --git a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java index c75ca132048..bc82125955f 100644 --- a/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java +++ b/tests/unit/src/com/android/settings/core/PreferenceControllerContractTest.java @@ -54,8 +54,7 @@ public class PreferenceControllerContractTest { public void controllersInSearchShouldImplementPreferenceControllerMixin() { final Set errorClasses = new ArraySet<>(); - for (SearchIndexableResource page : SearchIndexableResources.values()) { - final Class clazz = DatabaseIndexingUtils.getIndexableClass(page.className); + for (Class clazz: SearchIndexableResources.providerValues()) { final Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(clazz); diff --git a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java index 4c5177235c4..5f3e512b2f5 100644 --- a/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java +++ b/tests/unit/src/com/android/settings/core/UniquePreferenceTest.java @@ -90,8 +90,8 @@ public class UniquePreferenceTest { final Set uniqueKeys = new HashSet<>(); final Set nullKeyClasses = new HashSet<>(); final Set duplicatedKeys = new HashSet<>(); - for (SearchIndexableResource sir : SearchIndexableResources.values()) { - verifyPreferenceIdInXml(uniqueKeys, duplicatedKeys, nullKeyClasses, sir); + for (Class clazz : SearchIndexableResources.providerValues()) { + verifyPreferenceIdInXml(uniqueKeys, duplicatedKeys, nullKeyClasses, clazz); } if (!nullKeyClasses.isEmpty()) { @@ -115,22 +115,24 @@ public class UniquePreferenceTest { } private void verifyPreferenceIdInXml(Set uniqueKeys, Set duplicatedKeys, - Set nullKeyClasses, SearchIndexableResource page) + Set nullKeyClasses, Class clazz) throws IOException, XmlPullParserException, Resources.NotFoundException { - final Class clazz = DatabaseIndexingUtils.getIndexableClass(page.className); - + if (clazz == null) { + return; + } + final String className = clazz.getName(); final Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(clazz); final List resourcesToIndex = provider.getXmlResourcesToIndex(mContext, true); if (resourcesToIndex == null) { - Log.d(TAG, page.className + "is not providing SearchIndexableResource, skipping"); + Log.d(TAG, className + "is not providing SearchIndexableResource, skipping"); return; } for (SearchIndexableResource sir : resourcesToIndex) { if (sir.xmlResId <= 0) { - Log.d(TAG, page.className + " doesn't have a valid xml to index."); + Log.d(TAG, className + " doesn't have a valid xml to index."); continue; } final XmlResourceParser parser = mContext.getResources().getXml(sir.xmlResId); @@ -154,14 +156,14 @@ public class UniquePreferenceTest { final String key = XmlParserUtils.getDataKey(mContext, attrs); if (TextUtils.isEmpty(key)) { Log.e(TAG, "Every preference must have an key; found null key" - + " in " + page.className + + " in " + className + " at " + parser.getPositionDescription()); - nullKeyClasses.add(page.className); + nullKeyClasses.add(className); continue; } if (uniqueKeys.contains(key) && !WHITELISTED_DUPLICATE_KEYS.contains(key)) { Log.e(TAG, "Every preference key must unique; found " + nodeName - + " in " + page.className + + " in " + className + " at " + parser.getPositionDescription()); duplicatedKeys.add(key); }