Merge "Move Index provider conversion into Settings provider"
diff --git a/src/com/android/settings/search/SearchIndexableResources.java b/src/com/android/settings/search/SearchIndexableResources.java
index 47d17b6..05fd3c9 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;
@@ -89,22 +87,17 @@
 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<String, SearchIndexableResource> sResMap = new HashMap<>();
+    static final Set<Class> 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 {
@@ -180,15 +173,5 @@
     private SearchIndexableResources() {
     }
 
-    public static int size() {
-        return sResMap.size();
-    }
-
-    public static SearchIndexableResource getResourceByName(String className) {
-        return sResMap.get(className);
-    }
-
-    public static Collection<SearchIndexableResource> values() {
-        return sResMap.values();
-    }
+    public static Collection<Class> 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 622378b..968847b 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.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 @@
     @Override
     public Cursor queryXmlResources(String[] projection) {
         MatrixCursor cursor = new MatrixCursor(INDEXABLES_XML_RES_COLUMNS);
-        Collection<SearchIndexableResource> values = SearchIndexableResources.values();
-        for (SearchIndexableResource val : values) {
+        final List<SearchIndexableResource> 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 @@
             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<SearchIndexableRaw> 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 @@
     @Override
     public Cursor queryNonIndexableKeys(String[] projection) {
         MatrixCursor cursor = new MatrixCursor(NON_INDEXABLES_KEYS_COLUMNS);
-        final Collection<String> values = new HashSet<>();
-        final Context context = getContext();
+        final List<String> 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<String> getNonIndexableKeysFromProvider(Context context) {
+        final Collection<Class> values = SearchIndexableResources.providerValues();
+        final List<String> 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<String> providerNonIndexableKeys = provider.getNonIndexableKeys(context);
 
             if (providerNonIndexableKeys == null || providerNonIndexableKeys.isEmpty()) {
@@ -123,22 +153,71 @@
             }
 
             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<SearchIndexableResource> getSearchIndexableResourcesFromProvider(Context context) {
+        Collection<Class> values = SearchIndexableResources.providerValues();
+        List<SearchIndexableResource> resourceList = new ArrayList<>();
+
+        for (Class<?> clazz : values) {
+            Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(
+                    clazz);
+
+            final List<SearchIndexableResource> 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<SearchIndexableRaw> getSearchIndexableRawFromProvider(Context context) {
+        final Collection<Class> values = SearchIndexableResources.providerValues();
+        final List<SearchIndexableRaw> rawList = new ArrayList<>();
+
+        for (Class<?> clazz : values) {
+            Indexable.SearchIndexProvider provider = DatabaseIndexingUtils.getSearchIndexProvider(
+                    clazz);
+            final List<SearchIndexableRaw> 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 ab60f62..65fa279 100644
--- a/src/com/android/settings/search/indexing/IndexDataConverter.java
+++ b/src/com/android/settings/search/indexing/IndexDataConverter.java
@@ -31,7 +31,6 @@
 
 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 @@
                 final SearchIndexableResource sir = (SearchIndexableResource) data;
                 final Set<String> 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<IndexData> resourceData = convertResource(sir,
-                            resourceNonIndexableKeys);
-                    indexData.addAll(resourceData);
-                }
-
+                final List<IndexData> resourceData = convertResource(sir, resourceNonIndexableKeys);
+                indexData.addAll(resourceData);
             }
         }
 
@@ -305,84 +291,10 @@
         return resourceIndexData;
     }
 
-    private List<IndexData> convertIndexProvider(Indexable.SearchIndexProvider provider,
-            SearchIndexableResource sir, Set<String> nonIndexableKeys) {
-        final List<IndexData> 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<SearchIndexableRaw> 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<SearchIndexableResource> 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<String> getNonIndexableKeysForResource(Map<String, Set<String>> 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 b4a91c5..3c51a90 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 @@
                 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 0e3ce50..eedb324 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.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<String, SearchIndexableResource> sResMapCopy;
+    Set<Class> 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 @@
 
         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 0000000..efeaed7
--- /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<Class> 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 b95bfe8..0f2ab56 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 @@
         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> 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> 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> 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 c75ca13..bc82125 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 void controllersInSearchShouldImplementPreferenceControllerMixin() {
         final Set<String> 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 4c51772..5f3e512 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 @@
         final Set<String> uniqueKeys = new HashSet<>();
         final Set<String> nullKeyClasses = new HashSet<>();
         final Set<String> 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 @@
     }
 
     private void verifyPreferenceIdInXml(Set<String> uniqueKeys, Set<String> duplicatedKeys,
-            Set<String> nullKeyClasses, SearchIndexableResource page)
+            Set<String> 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<SearchIndexableResource> 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 @@
                 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);
                 }