Move the indexing back into DatabaseIndexingManager

For the sake of incremental updates, we moved all of the
conversion from PreIndexData to IndexData, and the
insertion of the rows into the SQLite DB into a new class,
IndexDataConverter. However, it's real role is just to
convert PreIndexData into IndexData.

So this CL moves the insertion of the rows back into
DatabaseIndexingManager.

Again, for the sake of simplicity, I did not change the
conversion flow. Rather, instead of inserting a row at the
end of the conversion, I just put it into a list which is
then returned. This lets me move the tests to appropriate
locations, without having to change them too much.

In the tests, the references to real xml layouts are
changed to fake references. Hooray for being less brittle.
IndexDataConverter now just tests that the IndexData
has the appropriate data from PreIndexdData.

Independently, we test that IndexData gets inserted in
DatabaseIndexingManager.

In the next CL, I'll refactor the conversion
flow for readability.

Bug: 33577327
Test: make RunSettingsRoboTests
Test: Took a database dump before and after change,
      and they were the same. Cool.

Change-Id: I39cc812d1f736e13a0a51af50984c239961ecf7a
diff --git a/src/com/android/settings/search/DatabaseIndexingManager.java b/src/com/android/settings/search/DatabaseIndexingManager.java
index de71f0a..d540d2f 100644
--- a/src/com/android/settings/search/DatabaseIndexingManager.java
+++ b/src/com/android/settings/search/DatabaseIndexingManager.java
@@ -23,7 +23,24 @@
 import static com.android.settings.search.DatabaseResultLoader.COLUMN_INDEX_KEY;
 import static com.android.settings.search.DatabaseResultLoader.SELECT_COLUMNS;
 import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DOCID;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.CLASS_NAME;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_ENTRIES;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_KEY_REF;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_TITLE;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED;
 import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.ENABLED;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.ICON;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.INTENT_ACTION;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.INTENT_TARGET_CLASS;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.INTENT_TARGET_PACKAGE;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.LOCALE;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.PAYLOAD;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.PAYLOAD_TYPE;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.SCREEN_TITLE;
+import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.USER_ID;
 import static com.android.settings.search.IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX;
 
 import android.content.ContentValues;
@@ -38,10 +55,12 @@
 import android.provider.SearchIndexableResource;
 import android.provider.SearchIndexablesContract;
 import android.support.annotation.VisibleForTesting;
+import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.settings.overlay.FeatureFactory;
 
+import com.android.settings.search.indexing.IndexData;
 import com.android.settings.search.indexing.IndexDataConverter;
 import com.android.settings.search.indexing.PreIndexData;
 import com.android.settings.search.indexing.PreIndexDataCollector;
@@ -49,6 +68,7 @@
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicBoolean;
 
@@ -72,6 +92,7 @@
     final AtomicBoolean mIsIndexingComplete = new AtomicBoolean(false);
 
     private PreIndexDataCollector mCollector;
+    private IndexDataConverter mConverter;
 
     private Context mContext;
 
@@ -182,8 +203,8 @@
      * @param localeStr       the default locale for the device.
      */
     @VisibleForTesting
-    void updateDatabase(PreIndexData indexData, boolean needsReindexing, String localeStr) {
-        final Map<String, Set<String>> nonIndexableKeys = indexData.nonIndexableKeys;
+    void updateDatabase(PreIndexData preIndexData, boolean needsReindexing, String localeStr) {
+        final Map<String, Set<String>> nonIndexableKeys = preIndexData.nonIndexableKeys;
 
         final SQLiteDatabase database = getWritableDatabase();
         if (database == null) {
@@ -194,8 +215,9 @@
         try {
             database.beginTransaction();
 
-            // Add new data from Providers at initial index time, or inserted later.
-            addIndaxebleDataToDatabase(database, localeStr, indexData);
+            // Convert all Pre-index data to Index data.
+            List<IndexData> indexData = getIndexData(localeStr, preIndexData);
+            insertIndexData(database, indexData);
 
             // Only check for non-indexable key updates after initial index.
             // Enabled state with non-indexable keys is checked when items are first inserted.
@@ -209,14 +231,64 @@
         }
     }
 
-
     @VisibleForTesting
-    void addIndaxebleDataToDatabase(SQLiteDatabase database, String locale, PreIndexData data) {
-        if (data.dataToUpdate.size() == 0) {
-            return;
+    List<IndexData> getIndexData(String locale, PreIndexData data) {
+        if (mConverter == null) {
+            mConverter = new IndexDataConverter(mContext);
         }
-        IndexDataConverter manager = new IndexDataConverter(mContext, database);
-        manager.addDataToDatabase(locale, data.dataToUpdate, data.nonIndexableKeys);
+        return mConverter.convertPreIndexDataToIndexData(data, locale);
+    }
+
+    /**
+     * Inserts all of the entries in {@param indexData} into the {@param database}
+     * as Search Data and as part of the Information Hierarchy.
+     */
+    @VisibleForTesting
+    void insertIndexData(SQLiteDatabase database, List<IndexData> indexData) {
+        ContentValues values;
+
+        for (IndexData dataRow : indexData) {
+            values = new ContentValues();
+            values.put(IndexDatabaseHelper.IndexColumns.DOCID, dataRow.getDocId());
+            values.put(LOCALE, dataRow.locale);
+            values.put(DATA_TITLE, dataRow.updatedTitle);
+            values.put(DATA_TITLE_NORMALIZED, dataRow.normalizedTitle);
+            values.put(DATA_SUMMARY_ON, dataRow.updatedSummaryOn);
+            values.put(DATA_SUMMARY_ON_NORMALIZED, dataRow.normalizedSummaryOn);
+            values.put(DATA_ENTRIES, dataRow.entries);
+            values.put(DATA_KEYWORDS, dataRow.spaceDelimitedKeywords);
+            values.put(CLASS_NAME, dataRow.className);
+            values.put(SCREEN_TITLE, dataRow.screenTitle);
+            values.put(INTENT_ACTION, dataRow.intentAction);
+            values.put(INTENT_TARGET_PACKAGE, dataRow.intentTargetPackage);
+            values.put(INTENT_TARGET_CLASS, dataRow.intentTargetClass);
+            values.put(ICON, dataRow.iconResId);
+            values.put(ENABLED, dataRow.enabled);
+            values.put(DATA_KEY_REF, dataRow.key);
+            values.put(USER_ID, dataRow.userId);
+            values.put(PAYLOAD_TYPE, dataRow.payloadType);
+            values.put(PAYLOAD, dataRow.payload);
+
+            database.replaceOrThrow(TABLE_PREFS_INDEX, null, values);
+
+            if (!TextUtils.isEmpty(dataRow.className)
+                    && !TextUtils.isEmpty(dataRow.childClassName)) {
+                ContentValues siteMapPair = new ContentValues();
+                final int pairDocId = Objects.hash(dataRow.className, dataRow.childClassName);
+                siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.DOCID, pairDocId);
+                siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.PARENT_CLASS,
+                        dataRow.className);
+                siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.PARENT_TITLE,
+                        dataRow.screenTitle);
+                siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.CHILD_CLASS,
+                        dataRow.childClassName);
+                siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.CHILD_TITLE,
+                        dataRow.updatedTitle);
+
+                database.replaceOrThrow(IndexDatabaseHelper.Tables.TABLE_SITE_MAP,
+                        null /* nullColumnHack */, siteMapPair);
+            }
+        }
     }
 
     /**
@@ -288,7 +360,6 @@
         disabledResults.close();
     }
 
-
     /**
      * TODO (b/64951285): Deprecate this method
      *
diff --git a/src/com/android/settings/search/indexing/IndexDataConverter.java b/src/com/android/settings/search/indexing/IndexDataConverter.java
index f900b83..90430a8 100644
--- a/src/com/android/settings/search/indexing/IndexDataConverter.java
+++ b/src/com/android/settings/search/indexing/IndexDataConverter.java
@@ -17,10 +17,8 @@
 
 package com.android.settings.search.indexing;
 
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.res.XmlResourceParser;
-import android.database.sqlite.SQLiteDatabase;
 import android.provider.SearchIndexableData;
 import android.provider.SearchIndexableResource;
 import android.support.annotation.DrawableRes;
@@ -32,7 +30,6 @@
 import com.android.settings.core.PreferenceControllerMixin;
 
 import com.android.settings.search.DatabaseIndexingUtils;
-import com.android.settings.search.IndexDatabaseHelper;
 import com.android.settings.search.Indexable;
 import com.android.settings.search.ResultPayload;
 import com.android.settings.search.SearchIndexableRaw;
@@ -44,33 +41,10 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.CLASS_NAME;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_ENTRIES;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_KEY_REF;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_RANK;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_TITLE;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.ENABLED;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.ICON;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.INTENT_ACTION;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.INTENT_TARGET_CLASS;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.INTENT_TARGET_PACKAGE;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.LOCALE;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.PAYLOAD;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.PAYLOAD_TYPE;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.SCREEN_TITLE;
-import static com.android.settings.search.IndexDatabaseHelper.IndexColumns.USER_ID;
-import static com.android.settings.search.IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX;
-
 /**
  * Helper class to convert {@link PreIndexData} to {@link IndexData}.
  *
@@ -86,56 +60,65 @@
     private static final String NODE_NAME_CHECK_BOX_PREFERENCE = "CheckBoxPreference";
     private static final String NODE_NAME_LIST_PREFERENCE = "ListPreference";
 
-    private Context mContext;
+    private final Context mContext;
 
-    private SQLiteDatabase mDb;
+    private String mLocale;
 
-    public IndexDataConverter(Context context, SQLiteDatabase database) {
+    private List<IndexData> mIndexData;
+
+    public IndexDataConverter(Context context) {
         mContext = context;
-        mDb = database;
+        mLocale = Locale.getDefault().toString();
+    }
+
+    public List<IndexData> convertPreIndexDataToIndexData(PreIndexData preIndexData,
+            String locale) {
+        mLocale = locale;
+        mIndexData = new ArrayList<>();
+        List<SearchIndexableData> dataToUpdate = preIndexData.dataToUpdate;
+        Map<String, Set<String>> nonIndexableKeys = preIndexData.nonIndexableKeys;
+        parsePreIndexData(dataToUpdate, nonIndexableKeys);
+        return mIndexData;
     }
 
     /**
      * Inserts {@link SearchIndexableData} into the database.
      *
-     * @param localeStr        is the locale of the data to be inserted.
      * @param dataToUpdate     is a {@link List} of the data to be inserted.
      * @param nonIndexableKeys is a {@link Map} from Package Name to a {@link Set} of keys which
      *                         identify search results which should not be surfaced.
      */
-    public void addDataToDatabase(String localeStr, List<SearchIndexableData> dataToUpdate,
+    private void parsePreIndexData(List<SearchIndexableData> dataToUpdate,
             Map<String, Set<String>> nonIndexableKeys) {
         final long current = System.currentTimeMillis();
 
         for (SearchIndexableData data : dataToUpdate) {
             try {
-                indexOneSearchIndexableData(localeStr, data, nonIndexableKeys);
+                addOneIndexData(data, nonIndexableKeys);
             } catch (Exception e) {
                 Log.e(LOG_TAG, "Cannot index: " + (data != null ? data.className : data)
-                        + " for locale: " + localeStr, e);
+                        + " for locale: " + mLocale, e);
             }
         }
 
         final long now = System.currentTimeMillis();
-        Log.d(LOG_TAG, "Indexing locale '" + localeStr + "' took " +
+        Log.d(LOG_TAG, "Indexing locale '" + mLocale + "' took " +
                 (now - current) + " millis");
     }
 
-    @VisibleForTesting
-    void indexOneSearchIndexableData(String localeStr, SearchIndexableData data,
+    private void addOneIndexData(SearchIndexableData data,
             Map<String, Set<String>> nonIndexableKeys) {
         if (data instanceof SearchIndexableResource) {
-            indexOneResource(localeStr, (SearchIndexableResource) data, nonIndexableKeys);
+            addOneResource((SearchIndexableResource) data, nonIndexableKeys);
         } else if (data instanceof SearchIndexableRaw) {
-            indexOneRaw(localeStr, (SearchIndexableRaw) data, nonIndexableKeys);
+            addOneRaw((SearchIndexableRaw) data, nonIndexableKeys);
         }
     }
 
-    @VisibleForTesting
-    void indexOneRaw(String localeStr, SearchIndexableRaw raw, Map<String,
+    private void addOneRaw(SearchIndexableRaw raw, Map<String,
             Set<String>> nonIndexableKeysFromResource) {
         // Should be the same locale as the one we are processing
-        if (!raw.locale.toString().equalsIgnoreCase(localeStr)) {
+        if (!raw.locale.toString().equalsIgnoreCase(mLocale)) {
             return;
         }
 
@@ -149,7 +132,7 @@
         IndexData.Builder builder = new IndexData.Builder();
         builder.setTitle(raw.title)
                 .setSummaryOn(raw.summaryOn)
-                .setLocale(localeStr)
+                .setLocale(mLocale)
                 .setEntries(raw.entries)
                 .setKeywords(raw.keywords)
                 .setClassName(raw.className)
@@ -162,12 +145,11 @@
                 .setKey(raw.key)
                 .setUserId(raw.userId);
 
-        updateOneRow(builder.build(mContext));
+        addRowToData(builder.build(mContext));
     }
 
-    @VisibleForTesting
-    void indexOneResource(String localeStr, SearchIndexableResource sir,
-            Map<String, Set<String>> nonIndexableKeysFromResource) {
+    private void addOneResource(SearchIndexableResource sir,
+        Map<String, Set<String>> nonIndexableKeysFromResource) {
 
         if (sir == null) {
             Log.e(LOG_TAG, "Cannot index a null resource!");
@@ -182,7 +164,7 @@
                 nonIndexableKeys.addAll(resNonIndexableKeys);
             }
 
-            indexFromResource(localeStr, sir, nonIndexableKeys);
+            addIndexDataFromResource(sir, nonIndexableKeys);
         } else {
             if (TextUtils.isEmpty(sir.className)) {
                 Log.w(LOG_TAG, "Cannot index an empty Search Provider name!");
@@ -202,17 +184,16 @@
                     DatabaseIndexingUtils.getSearchIndexProvider(clazz);
             if (provider != null) {
                 List<String> providerNonIndexableKeys = provider.getNonIndexableKeys(sir.context);
-                if (providerNonIndexableKeys != null && providerNonIndexableKeys.size() > 0) {
+                if (providerNonIndexableKeys != null) {
                     nonIndexableKeys.addAll(providerNonIndexableKeys);
                 }
 
-                indexFromProvider(localeStr, provider, sir, nonIndexableKeys);
+                addIndexDataFromProvider(provider, sir, nonIndexableKeys);
             }
         }
     }
 
-    @VisibleForTesting
-    void indexFromResource(String localeStr, SearchIndexableResource sir,
+    private void addIndexDataFromResource(SearchIndexableResource sir,
             List<String> nonIndexableKeys) {
         final Context context = sir.context;
         XmlResourceParser parser = null;
@@ -274,7 +255,7 @@
             headerBuilder.setTitle(headerTitle)
                     .setSummaryOn(headerSummary)
                     .setKeywords(headerKeywords)
-                    .setLocale(localeStr)
+                    .setLocale(mLocale)
                     .setClassName(fragmentName)
                     .setScreenTitle(screenTitle)
                     .setIntentAction(intentAction)
@@ -308,7 +289,7 @@
 
                 builder = new IndexData.Builder();
                 builder.setTitle(title)
-                        .setLocale(localeStr)
+                        .setLocale(mLocale)
                         .setKeywords(keywords)
                         .setClassName(fragmentName)
                         .setScreenTitle(screenTitle)
@@ -339,7 +320,7 @@
                             .setPayload(payload);
 
                     // Insert rows for the child nodes of PreferenceScreen
-                    updateOneRow(builder.build(mContext));
+                    addRowToData(builder.build(mContext));
                 } else {
                     // TODO (b/33577327) We removed summary off here. We should check if we can
                     // merge this 'else' section with the one above. Put a break point to
@@ -353,13 +334,13 @@
 
                     builder.setSummaryOn(summaryOn);
 
-                    updateOneRow(builder.build(mContext));
+                    addRowToData(builder.build(mContext));
                 }
             }
 
             // The xml header's title does not match the title of one of the child settings.
             if (isHeaderUnique) {
-                updateOneRow(headerBuilder.build(mContext));
+                addRowToData(headerBuilder.build(mContext));
             }
         } catch (XmlPullParserException e) {
             throw new RuntimeException("Error parsing PreferenceScreen", e);
@@ -370,8 +351,7 @@
         }
     }
 
-    @VisibleForTesting
-    void indexFromProvider(String localeStr, Indexable.SearchIndexProvider provider,
+    private void addIndexDataFromProvider(Indexable.SearchIndexProvider provider,
             SearchIndexableResource sir, List<String> nonIndexableKeys) {
 
         final String className = sir.className;
@@ -393,7 +373,7 @@
                 SearchIndexableRaw raw = rawList.get(i);
 
                 // Should be the same locale as the one we are processing
-                if (!raw.locale.toString().equalsIgnoreCase(localeStr)) {
+                if (!raw.locale.toString().equalsIgnoreCase(mLocale)) {
                     continue;
                 }
                 boolean enabled = !nonIndexableKeys.contains(raw.key);
@@ -401,7 +381,7 @@
                 IndexData.Builder builder = new IndexData.Builder();
                 builder.setTitle(raw.title)
                         .setSummaryOn(raw.summaryOn)
-                        .setLocale(localeStr)
+                        .setLocale(mLocale)
                         .setEntries(raw.entries)
                         .setKeywords(raw.keywords)
                         .setClassName(className)
@@ -414,7 +394,7 @@
                         .setKey(raw.key)
                         .setUserId(raw.userId);
 
-                updateOneRow(builder.build(mContext));
+                addRowToData(builder.build(mContext));
             }
         }
 
@@ -426,7 +406,7 @@
                 SearchIndexableResource item = resList.get(i);
 
                 // Should be the same locale as the one we are processing
-                if (!item.locale.toString().equalsIgnoreCase(localeStr)) {
+                if (!item.locale.toString().equalsIgnoreCase(mLocale)) {
                     continue;
                 }
 
@@ -440,49 +420,16 @@
                         ? intentTargetPackage
                         : item.intentTargetPackage;
 
-                indexFromResource(localeStr, item, nonIndexableKeys);
+                addIndexDataFromResource(item, nonIndexableKeys);
             }
         }
     }
 
-    private void updateOneRow(IndexData row) {
+    private void addRowToData(IndexData row) {
         if (TextUtils.isEmpty(row.updatedTitle)) {
             return;
         }
 
-        ContentValues values = new ContentValues();
-        values.put(IndexDatabaseHelper.IndexColumns.DOCID, row.getDocId());
-        values.put(LOCALE, row.locale);
-        values.put(DATA_TITLE, row.updatedTitle);
-        values.put(DATA_TITLE_NORMALIZED, row.normalizedTitle);
-        values.put(DATA_SUMMARY_ON, row.updatedSummaryOn);
-        values.put(DATA_SUMMARY_ON_NORMALIZED, row.normalizedSummaryOn);
-        values.put(DATA_ENTRIES, row.entries);
-        values.put(DATA_KEYWORDS, row.spaceDelimitedKeywords);
-        values.put(CLASS_NAME, row.className);
-        values.put(SCREEN_TITLE, row.screenTitle);
-        values.put(INTENT_ACTION, row.intentAction);
-        values.put(INTENT_TARGET_PACKAGE, row.intentTargetPackage);
-        values.put(INTENT_TARGET_CLASS, row.intentTargetClass);
-        values.put(ICON, row.iconResId);
-        values.put(ENABLED, row.enabled);
-        values.put(DATA_KEY_REF, row.key);
-        values.put(USER_ID, row.userId);
-        values.put(PAYLOAD_TYPE, row.payloadType);
-        values.put(PAYLOAD, row.payload);
-
-        mDb.replaceOrThrow(TABLE_PREFS_INDEX, null, values);
-
-        if (!TextUtils.isEmpty(row.className) && !TextUtils.isEmpty(row.childClassName)) {
-            ContentValues siteMapPair = new ContentValues();
-            final int pairDocId = Objects.hash(row.className, row.childClassName);
-            siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.DOCID, pairDocId);
-            siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.PARENT_CLASS, row.className);
-            siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.PARENT_TITLE, row.screenTitle);
-            siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.CHILD_CLASS, row.childClassName);
-            siteMapPair.put(IndexDatabaseHelper.SiteMapColumns.CHILD_TITLE, row.updatedTitle);
-
-            mDb.replaceOrThrow(IndexDatabaseHelper.Tables.TABLE_SITE_MAP, null, siteMapPair);
-        }
+        mIndexData.add(row);
     }
 }
diff --git a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
index a2a772b..4ee97fa 100644
--- a/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
+++ b/tests/robotests/assets/grandfather_not_in_search_index_provider_registry
@@ -1,2 +1,3 @@
 com.android.settings.development.DevelopmentSettingsDashboardFragment
 com.android.settings.display.ScreenZoomPreferenceFragmentForSetupWizard
+com.android.settings.search.indexing.FakeSettingsFragment
diff --git a/tests/robotests/res/xml-mcc999/about_legal.xml b/tests/robotests/res/xml-mcc999/about_legal.xml
new file mode 100644
index 0000000..53a2b89
--- /dev/null
+++ b/tests/robotests/res/xml-mcc999/about_legal.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2017 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  -->
+
+<!--
+    WARNING: This resource file is used to test Settings Search indexing.
+    If you change something in here, please run the settings robotests and
+    make sure they still pass.
+ -->
+
+<PreferenceScreen
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
+        android:title="bears_bears_bears"
+        settings:keywords="keywords">
+
+    <Preference
+            android:key="pref_key_1"
+            android:title="bears_bears_bears"/>
+</PreferenceScreen>
\ No newline at end of file
diff --git a/tests/robotests/res/xml-mcc999/display_settings.xml b/tests/robotests/res/xml-mcc999/display_settings.xml
new file mode 100644
index 0000000..4e0ce6b
--- /dev/null
+++ b/tests/robotests/res/xml-mcc999/display_settings.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2017 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+
+<!--
+    WARNING: This resource file is used to test Settings Search indexing.
+    If you change something in here, please run the settings robotests and
+    make sure they still pass.
+ -->
+
+<PreferenceScreen
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:settings="http://schemas.android.com/apk/res/com.android.settings"
+    android:title="page_title"
+    settings:keywords="keywords">
+
+    <Preference
+        android:key="pref_key_1"
+        android:title="pref_title_1"
+        android:summary="summary_1"
+        settings:keywords="keywords1, keywords2, keywords3" />
+
+    <SwitchPreference
+        android:key="pref_key_2"
+        android:title="pref_title_2"
+        android:summary="summary_2"
+        settings:keywords="keywords1, keywords2, keywords3" />
+
+    <Preference
+        android:key="pref_key_3"
+        android:title="pref_title_3"
+        android:summary="summary_3"
+        android:icon="@drawable/ic_android"
+        settings:keywords="keywords1, keywords2, keywords3" />
+
+    <ListPreference
+        android:key="pref_key_4"
+        android:title="pref_title_4"
+        android:summary="summary_4"
+        settings:keywords="keywords1, keywords2, keywords3" />
+
+    <CheckBoxPreference
+            android:key="pref_key_5"
+            android:title="pref_title_5"
+            android:summaryOn="summary_on"
+            android:summaryOff="summary_off"
+            settings:keywords="keywords1, keywords2, keywords3" />
+</PreferenceScreen>
\ No newline at end of file
diff --git a/tests/robotests/src/com/android/settings/search/indexing/FakeSettingsFragment.java b/tests/robotests/src/com/android/settings/search/indexing/FakeSettingsFragment.java
new file mode 100644
index 0000000..72df771
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/search/indexing/FakeSettingsFragment.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.settings.search.indexing;
+
+import android.content.Context;
+import android.provider.SearchIndexableResource;
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.dashboard.DashboardFragment;
+import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.search.SearchIndexableRaw;
+import com.android.settingslib.core.AbstractPreferenceController;
+import com.android.settingslib.core.lifecycle.Lifecycle;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Test class for Settings Search Indexing.
+ * If you change this class, please run robotests to make sure they still pass.
+ */
+public class FakeSettingsFragment extends DashboardFragment {
+
+    public static final String TITLE = "raw title";
+    public static final String SUMMARY_ON = "raw summary on";
+    public static final String SUMMARY_OFF = "raw summary off";
+    public static final String ENTRIES = "rawentries";
+    public static final String KEYWORDS = "keywords, keywordss, keywordsss";
+    public static final String SPACE_KEYWORDS = "keywords keywordss keywordsss";
+    public static final String SCREEN_TITLE = "raw screen title";
+    public static final String CLASS_NAME = FakeSettingsFragment.class.getName();
+    public static final int ICON = 0xff;
+    public static final String INTENT_ACTION = "raw action";
+    public static final String PACKAGE_NAME = "raw target package";
+    public static final String TARGET_CLASS = "raw target class";
+    public static final String TARGET_PACKAGE = "raw package name";
+    public static final String KEY = "raw key";
+    public static final boolean ENABLED = true;
+
+
+    @Override
+    public int getMetricsCategory() {
+        return MetricsProto.MetricsEvent.DISPLAY;
+    }
+
+    @Override
+    protected String getLogTag() {
+        return "";
+    }
+
+    @Override
+    protected int getPreferenceScreenResId() {
+        return com.android.settings.R.xml.display_settings;
+    }
+
+    @Override
+    protected List<AbstractPreferenceController> getPreferenceControllers(Context context) {
+        return null;
+    }
+
+    /** Index provider used to expose this fragment in search. */
+    public static final SearchIndexProvider SEARCH_INDEX_DATA_PROVIDER =
+            new BaseSearchIndexProvider() {
+                @Override
+                public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) {
+                    final SearchIndexableRaw data = new SearchIndexableRaw(context);
+                    data.title = TITLE;
+                    data.summaryOn = SUMMARY_ON;
+                    data.summaryOff = SUMMARY_OFF;
+                    data.entries = ENTRIES;
+                    data.keywords = KEYWORDS;
+                    data.screenTitle = SCREEN_TITLE;
+                    data.packageName = PACKAGE_NAME;
+                    data.intentAction = INTENT_ACTION;
+                    data.intentTargetClass = TARGET_CLASS;
+                    data.intentTargetPackage = TARGET_PACKAGE;
+                    data.key = KEY;
+                    data.iconResId = ICON;
+                    data.enabled = ENABLED;
+
+                    final List<SearchIndexableRaw> result = new ArrayList<>(1);
+                    result.add(data);
+                    return result;
+                }
+
+                @Override
+                public List<SearchIndexableResource> getXmlResourcesToIndex(Context context,
+                        boolean enabled) {
+                    final ArrayList<SearchIndexableResource> result = new ArrayList<>();
+
+                    final SearchIndexableResource sir = new SearchIndexableResource(context);
+                    sir.xmlResId = com.android.settings.R.xml.display_settings;
+                    result.add(sir);
+                    return result;
+                }
+
+                @Override
+                public List<String> getNonIndexableKeys(Context context) {
+                    List<String> keys = super.getNonIndexableKeys(context);
+                    keys.add("pref_key_1");
+                    keys.add("pref_key_3");
+                    return keys;
+                }
+
+                @Override
+                public List<AbstractPreferenceController>
+                        getPreferenceControllers(Context context) {
+                    return null;
+                }
+            };
+}
\ No newline at end of file
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 ca04d2c..b5bfea0 100644
--- a/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java
+++ b/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java
@@ -18,15 +18,13 @@
 package com.android.settings.search.indexing;
 
 import android.content.Context;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
 import android.provider.SearchIndexableResource;
+import android.text.TextUtils;
 import com.android.settings.TestConfig;
-import com.android.settings.search.IndexDatabaseHelper;
+import com.android.settings.R;
 import com.android.settings.search.ResultPayload;
 import com.android.settings.search.ResultPayloadUtils;
 import com.android.settings.search.SearchIndexableRaw;
-import com.android.settings.search.SearchIndexableResources;
 import com.android.settings.testutils.DatabaseTestUtils;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import org.junit.After;
@@ -36,58 +34,70 @@
 import org.robolectric.RuntimeEnvironment;
 import org.robolectric.annotation.Config;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Locale;
-import java.util.Map;
 import java.util.Set;
 
-import static com.android.settings.R.*;
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Mockito.spy;
 
 @RunWith(SettingsRobolectricTestRunner.class)
-@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
+@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, qualifiers = "mcc999")
 public class IndexDataConverterTest {
 
     private final String localeStr = "en_US";
 
-    private final String title = "title\u2011title";
-    private final String updatedTitle = "title-title";
-    private final String normalizedTitle = "titletitle";
-    private final String summaryOn = "summary\u2011on";
-    private final String updatedSummaryOn = "summary-on";
-    private final String normalizedSummaryOn = "summaryon";
-    private final String summaryOff = "summary\u2011off";
-    private final String updatedSummaryOff = "summary-off";
-    private final String normalizedSummaryOff = "summaryoff";
-    private final String entries = "entries";
-    private final String keywords = "keywords, keywordss, keywordsss";
-    private final String spaceDelimittedKeywords = "keywords keywordss keywordsss";
-    private final String screenTitle = "screen title";
-    private final String className = "class name";
-    private final int iconResId = 0xff;
-    private final int noIcon = 0;
-    private final String action = "action";
-    private final String targetPackage = "target package";
-    private final String targetClass = "target class";
-    private final String packageName = "package name";
-    private final String key = "key";
-    private final int userId = -1;
-    private final boolean enabled = true;
+    private static final String title = "title\u2011title";
+    private static final String updatedTitle = "title-title";
+    private static final String normalizedTitle = "titletitle";
+    private static final String summaryOn = "summary\u2011on";
+    private static final String updatedSummaryOn = "summary-on";
+    private static final String normalizedSummaryOn = "summaryon";
+    private static final String summaryOff = "summary\u2011off";
+    private static final String updatedSummaryOff = "summary-off";
+    private static final String normalizedSummaryOff = "summaryoff";
+    private static final String entries = "entries";
+    private static final String keywords = "keywords, keywordss, keywordsss";
+    private static final String spaceDelimittedKeywords = "keywords keywordss keywordsss";
+    private static final String screenTitle = "screen title";
+    private static final String className = "class name";
+    private static final int iconResId = 0xff;
+    private static final String action = "action";
+    private static final String targetPackage = "target package";
+    private static final String targetClass = "target class";
+    private static final String packageName = "package name";
+    private static final String key = "key";
+    private static final int userId = -1;
+    private static final boolean enabled = true;
+
+    // There are 6 entries in the fake display_settings.xml preference.
+    private final int NUM_DISPLAY_ENTRIES = 6;
+    private static final String PAGE_TITLE = "page_title";
+    private static final String TITLE_ONE = "pref_title_1";
+    private static final String TITLE_TWO = "pref_title_2";
+    private static final String TITLE_THREE = "pref_title_3";
+    private static final String TITLE_FOUR = "pref_title_4";
+    private static final String TITLE_FIVE = "pref_title_5";
+    private static final String DISPLAY_SPACE_DELIM_KEYWORDS = "keywords1 keywords2 keywords3";
+
+    // There are 6 display entries from resources, and 1 raw.
+    private static final int NUM_FAKE_FRAGMENT_ENTRIES = 7;
+    private static final int NUM_ENABLED_FAKE_FRAGMENT_ENTRIES = 5;
+    private static final String FAKE_CLASS_NAME =
+            "com.android.settings.search.indexing.FakeSettingsFragment";
+
+    // There is a title and one preference.
+    private final int NUM_LEGAL_SETTINGS = 2;
 
     private Context mContext;
 
     private IndexDataConverter mConverter;
-    private SQLiteDatabase mDb;
 
     @Before
     public void setUp() {
         mContext = spy(RuntimeEnvironment.application);
-        mDb = IndexDatabaseHelper.getInstance(mContext).getWritableDatabase();
-        mConverter = spy(new IndexDataConverter(mContext, mDb));
+        mConverter = spy(new IndexDataConverter(mContext));
     }
 
     @After
@@ -96,82 +106,67 @@
     }
 
     @Test
-    public void testInsertRawColumn_rowInserted() {
-        SearchIndexableRaw raw = getFakeRaw();
-        mConverter.indexOneSearchIndexableData(localeStr, raw,
-                new HashMap<>()/* Non-indexable keys */);
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-    }
+    public void testInsertRawColumn_rowConverted() {
+        final SearchIndexableRaw raw = getFakeRaw();
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(raw);
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
 
-    @Test
-    public void testInsertRawColumn_nonIndexableKey_resultIsDisabled() {
-        SearchIndexableRaw raw = getFakeRaw();
-        Map<String, Set<String>> niks = new HashMap<>();
-        Set<String> keys = new HashSet<>();
-        keys.add(raw.key);
-        niks.put(raw.intentTargetPackage, keys);
+        assertThat(indexData.size()).isEqualTo(1);
+        final IndexData row = indexData.get(0);
 
-        mConverter.indexOneSearchIndexableData(localeStr, raw, niks);
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-    }
-
-    @Test
-    public void testInsertRawColumn_rowMatches() {
-        SearchIndexableRaw raw = getFakeRaw();
-        mConverter.indexOneSearchIndexableData(localeStr, raw,
-                new HashMap<>()/* Non-indexable keys */);
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
-        cursor.moveToPosition(0);
-
-        // Locale
-        assertThat(cursor.getString(0)).isEqualTo(localeStr);
-        // Data Title
-        assertThat(cursor.getString(2)).isEqualTo(updatedTitle);
-        // Normalized Title
-        assertThat(cursor.getString(3)).isEqualTo(normalizedTitle);
-        // Summary On
-        assertThat(cursor.getString(4)).isEqualTo(updatedSummaryOn);
-        // Summary On Normalized
-        assertThat(cursor.getString(5)).isEqualTo(normalizedSummaryOn);
-        // Entries
-        assertThat(cursor.getString(8)).isEqualTo(raw.entries);
-        // Keywords
-        assertThat(cursor.getString(9)).isEqualTo(spaceDelimittedKeywords);
-        // Screen Title
-        assertThat(cursor.getString(10)).isEqualTo(raw.screenTitle);
-        // Class Name
-        assertThat(cursor.getString(11)).isEqualTo(raw.className);
-        // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(raw.iconResId);
-        // Intent Action
-        assertThat(cursor.getString(13)).isEqualTo(raw.intentAction);
-        // Target Package
-        assertThat(cursor.getString(14)).isEqualTo(raw.intentTargetPackage);
-        // Target Class
-        assertThat(cursor.getString(15)).isEqualTo(raw.intentTargetClass);
-        // Enabled
-        assertThat(cursor.getInt(16) == 1).isEqualTo(raw.enabled);
-        // Data ref key
-        assertThat(cursor.getString(17)).isNotNull();
-        // User Id
-        assertThat(cursor.getInt(18)).isEqualTo(raw.userId);
-        // Payload Type - default is 0
-        assertThat(cursor.getInt(19)).isEqualTo(0);
-        // Payload
-        byte[] payload = cursor.getBlob(20);
-        ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload,
+        assertThat(row.normalizedTitle).isEqualTo(normalizedTitle);
+        assertThat(row.updatedTitle).isEqualTo(updatedTitle);
+        assertThat(row.locale).isEqualTo(localeStr);
+        assertThat(row.updatedSummaryOn).isEqualTo(updatedSummaryOn);
+        assertThat(row.entries).isEqualTo(entries);
+        assertThat(row.spaceDelimitedKeywords).isEqualTo(spaceDelimittedKeywords);
+        assertThat(row.screenTitle).isEqualTo(screenTitle);
+        assertThat(row.className).isEqualTo(className);
+        assertThat(row.iconResId).isEqualTo(iconResId);
+        assertThat(row.intentAction).isEqualTo(action);
+        assertThat(row.intentTargetPackage).isEqualTo(targetPackage);
+        assertThat(row.intentTargetClass).isEqualTo(targetClass);
+        assertThat(row.enabled).isEqualTo(enabled);
+        assertThat(row.key).isEqualTo(key);
+        assertThat(row.userId).isEqualTo(userId);
+        assertThat(row.payloadType).isEqualTo(0);
+        ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(row.payload,
                 ResultPayload.CREATOR);
         assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class);
     }
 
     @Test
+    public void testInsertRawColumn_nonIndexableKey_resultIsDisabled() {
+        final SearchIndexableRaw raw = getFakeRaw();
+        // Add non-indexable key for raw row.
+        Set<String> keys = new HashSet<>();
+        keys.add(raw.key);
+
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(raw);
+        preIndexData.nonIndexableKeys.put(raw.intentTargetPackage, keys);
+
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
+
+        assertThat(indexData.size()).isEqualTo(1);
+        assertThat(indexData.get(0).enabled).isFalse();
+    }
+
+    /**
+     * TODO (b/66916397) investigate why locale is attached to IndexData
+     */
+    @Test
     public void testInsertRawColumn_mismatchedLocale_noRowInserted() {
-        SearchIndexableRaw raw = getFakeRaw("ca-fr");
-        mConverter.indexOneSearchIndexableData(localeStr, raw, null /* Non-indexable keys */);
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
-        assertThat(cursor.getCount()).isEqualTo(0);
+        final SearchIndexableRaw raw = getFakeRaw("ca-fr");
+        PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(raw);
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
+
+        assertThat(indexData).isEmpty();
     }
 
     // Tests for the flow: IndexOneResource -> IndexFromResource ->
@@ -179,421 +174,202 @@
 
     @Test
     public void testNullResource_NothingInserted() {
-        mConverter.indexOneSearchIndexableData(localeStr, null /* searchIndexableResource */,
-                new HashMap<>());
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
-        assertThat(cursor.getCount()).isEqualTo(0);
+        PreIndexData preIndexData = new PreIndexData();
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
+
+        assertThat(indexData).isEmpty();
     }
 
     @Test
     public void testAddResource_RowsInserted() {
-        SearchIndexableResource resource = getFakeResource(xml.display_settings);
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
-        assertThat(cursor.getCount()).isEqualTo(17);
+        final SearchIndexableResource resource = getFakeResource(R.xml.display_settings);
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(resource);
+
+        final List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
+        int numEnabled = getEnabledResultCount(indexData);
+
+        assertThat(numEnabled).isEqualTo(NUM_DISPLAY_ENTRIES);
     }
 
     @Test
     public void testAddResource_withNIKs_rowsInsertedDisabled() {
-        SearchIndexableResource resource = getFakeResource(xml.display_settings);
-        // Only add 2 of 16 items to be disabled.
-        String[] keys = {"brightness", "wallpaper"};
-        Map<String, Set<String>> niks = getNonIndexableKeys(keys);
+        final SearchIndexableResource resource = getFakeResource(R.xml.display_settings);
+        Set<String> keys = new HashSet<>();
+        keys.add("pref_key_1");
+        keys.add("pref_key_3");
 
-        mConverter.indexOneSearchIndexableData(localeStr, resource, niks);
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(resource);
+        preIndexData.nonIndexableKeys.put(packageName, keys);
 
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null);
-        assertThat(cursor.getCount()).isEqualTo(2);
-        cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null);
-        assertThat(cursor.getCount()).isEqualTo(15);
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
+
+        assertThat(indexData.size()).isEqualTo(NUM_DISPLAY_ENTRIES);
+        assertThat(getEnabledResultCount(indexData)).isEqualTo(NUM_DISPLAY_ENTRIES - 2);
     }
 
     @Test
     public void testAddResourceHeader_rowsMatch() {
-        SearchIndexableResource resource = getFakeResource(xml.application_settings);
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
+        final SearchIndexableResource resource = getFakeResource(R.xml.display_settings);
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(resource);
 
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null);
-        cursor.moveToPosition(1);
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
 
-        // Locale
-        assertThat(cursor.getString(0)).isEqualTo(localeStr);
-        // Data Title
-        assertThat(cursor.getString(2)).isEqualTo("App info");
-        // Normalized Title
-        assertThat(cursor.getString(3)).isEqualTo("app info");
-        // Summary On
-        assertThat(cursor.getString(4)).isEqualTo("Manage apps, set up quick launch shortcuts");
-        // Summary On Normalized
-        assertThat(cursor.getString(5)).isEqualTo("manage apps, set up quick launch shortcuts");
-        // Entries - only on for list preferences
-        assertThat(cursor.getString(8)).isNull();
-        // Keywords
-        assertThat(cursor.getString(9)).isEmpty();
-        // Screen Title
-        assertThat(cursor.getString(10)).isEqualTo("App info");
-        // Class Name
-        assertThat(cursor.getString(11)).isEqualTo(className);
-        // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(0);
-        // Intent Action
-        assertThat(cursor.getString(13)).isEqualTo(action);
-        // Target Package
-        assertThat(cursor.getString(14)).isEqualTo(targetPackage);
-        // Target Class
-        assertThat(cursor.getString(15)).isEqualTo(targetClass);
-        // Enabled
-        assertThat(cursor.getInt(16) == 1).isEqualTo(enabled);
-        // Data ref key
-        assertThat(cursor.getString(17)).isEqualTo("applications_settings");
-        // User Id
-        assertThat(cursor.getInt(18)).isEqualTo(userId);
-        // Payload Type - default is 0
-        assertThat(cursor.getInt(19)).isEqualTo(0);
-        // Payload - should be updated to real payloads as controllers are added
-        byte[] payload = cursor.getBlob(20);
-        ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload,
-                ResultPayload.CREATOR);
-        assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class);
-    }
+        final IndexData row = findIndexDataForTitle(indexData, PAGE_TITLE);
 
-    @Test
-    public void testAddResource_customSetting_rowsMatch() {
-        SearchIndexableResource resource = getFakeResource(xml.swipe_to_notification_settings);
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
-        final String prefTitle =
-                mContext.getString(string.fingerprint_swipe_for_notifications_title);
-        final String prefSummary =
-                mContext.getString(string.fingerprint_swipe_for_notifications_summary);
-        final String keywords = mContext.getString(string.keywords_gesture);
-        Cursor cursor = mDb.rawQuery(
-                "SELECT * FROM prefs_index where data_title='" + prefTitle + "'", null);
-        cursor.moveToFirst();
-
-        // Locale
-        assertThat(cursor.getString(0)).isEqualTo(localeStr);
-        // Data Title
-        assertThat(cursor.getString(2)).isEqualTo(prefTitle);
-        // Normalized Title
-        assertThat(cursor.getString(3)).isEqualTo(prefTitle.toLowerCase());
-        // Summary On
-        assertThat(cursor.getString(4)).isEqualTo(prefSummary);
-        // Summary On Normalized
-        assertThat(cursor.getString(5)).isEqualTo(prefSummary.toLowerCase());
-        // Entries - only on for list preferences
-        assertThat(cursor.getString(8)).isNull();
-        // Keywords
-        assertThat(cursor.getString(9)).isEqualTo(keywords);
-        // Screen Title
-        assertThat(cursor.getString(10)).isEqualTo(
-                mContext.getString(string.fingerprint_swipe_for_notifications_title));
-        // Class Name
-        assertThat(cursor.getString(11)).isEqualTo(className);
-        // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
-        // Intent Action
-        assertThat(cursor.getString(13)).isEqualTo(action);
-        // Target Package
-        assertThat(cursor.getString(14)).isEqualTo(targetPackage);
-        // Target Class
-        assertThat(cursor.getString(15)).isEqualTo(targetClass);
-        // Enabled
-        assertThat(cursor.getInt(16) == 1).isEqualTo(enabled);
-        // Data ref key
-        assertThat(cursor.getString(17)).isEqualTo("gesture_swipe_down_fingerprint");
-        // User Id
-        assertThat(cursor.getInt(18)).isEqualTo(userId);
-        // Payload Type - default is 0
-        assertThat(cursor.getInt(19)).isEqualTo(0);
-        // Payload - should be updated to real payloads as controllers are added
-        byte[] payload = cursor.getBlob(20);
-        ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload,
-                ResultPayload.CREATOR);
-        assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class);
+        // Header exists
+        assertThat(row).isNotNull();
+        assertThat(row.spaceDelimitedKeywords).isEqualTo("keywords");
     }
 
     @Test
     public void testAddResource_checkboxPreference_rowsMatch() {
-        SearchIndexableResource resource = getFakeResource(xml.application_settings);
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
+        final SearchIndexableResource resource = getFakeResource(R.xml.display_settings);
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(resource);
 
-        /* Should return 6 results, with the following titles:
-         * Advanced Settings, Apps, Manage Apps, Preferred install location, Running Services
-         */
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null);
-        cursor.moveToPosition(0);
-        // Locale
-        assertThat(cursor.getString(0)).isEqualTo(localeStr);
-        // Data Title
-        assertThat(cursor.getString(2)).isEqualTo("Advanced settings");
-        // Normalized Title
-        assertThat(cursor.getString(3)).isEqualTo("advanced settings");
-        // Summary On
-        assertThat(cursor.getString(4)).isEqualTo("Enable more settings options");
-        // Summary On Normalized
-        assertThat(cursor.getString(5)).isEqualTo("enable more settings options");
-        // Entries - only on for list preferences
-        assertThat(cursor.getString(8)).isNull();
-        // Keywords
-        assertThat(cursor.getString(9)).isEmpty();
-        // Screen Title
-        assertThat(cursor.getString(10)).isEqualTo("App info");
-        // Class Name
-        assertThat(cursor.getString(11)).isEqualTo(className);
-        // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
-        // Intent Action
-        assertThat(cursor.getString(13)).isEqualTo(action);
-        // Target Package
-        assertThat(cursor.getString(14)).isEqualTo(targetPackage);
-        // Target Class
-        assertThat(cursor.getString(15)).isEqualTo(targetClass);
-        // Enabled
-        assertThat(cursor.getInt(16) == 1).isEqualTo(enabled);
-        // Data ref key
-        assertThat(cursor.getString(17)).isEqualTo("toggle_advanced_settings");
-        // User Id
-        assertThat(cursor.getInt(18)).isEqualTo(userId);
-        // Payload Type - default is 0
-        assertThat(cursor.getInt(19)).isEqualTo(0);
-        // Payload - should be updated to real payloads as controllers are added
-        byte[] payload = cursor.getBlob(20);
-        ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload,
-                ResultPayload.CREATOR);
-        assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class);
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
+
+        String checkBoxSummaryOn = "summary_on";
+        String checkBoxSummaryOff = "summary_off";
+        String checkBoxKey = "pref_key_5";
+        final IndexData row = findIndexDataForTitle(indexData, TITLE_FIVE);
+
+        assertDisplaySetting(row, TITLE_FIVE, checkBoxSummaryOn, checkBoxSummaryOff,
+                checkBoxKey);
     }
 
     @Test
     public void testAddResource_listPreference_rowsMatch() {
-        SearchIndexableResource resource = getFakeResource(xml.application_settings);
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
+        final SearchIndexableResource resource = getFakeResource(R.xml.display_settings);
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(resource);
 
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null);
-        cursor.moveToPosition(3);
-        // Locale
-        assertThat(cursor.getString(0)).isEqualTo(localeStr);
-        // Data Title
-        assertThat(cursor.getString(2)).isEqualTo("Preferred install location");
-        // Normalized Title
-        assertThat(cursor.getString(3)).isEqualTo("preferred install location");
-        // Summary On
-        assertThat(cursor.getString(4)).isEqualTo(
-                "Change the preferred installation location for new apps");
-        // Summary On Normalized
-        assertThat(cursor.getString(5)).isEqualTo(
-                "change the preferred installation location for new apps");
-        // Entries - only on for list preferences
-        assertThat(cursor.getString(8)).isEqualTo("Internal device storage|Removable SD card|" +
-                "Let the system decide|");
-        // Keywords
-        assertThat(cursor.getString(9)).isEmpty();
-        // Screen Title
-        assertThat(cursor.getString(10)).isEqualTo("App info");
-        // Class Name
-        assertThat(cursor.getString(11)).isEqualTo(className);
-        // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
-        // Intent Action
-        assertThat(cursor.getString(13)).isEqualTo(action);
-        // Target Package
-        assertThat(cursor.getString(14)).isEqualTo(targetPackage);
-        // Target Class
-        assertThat(cursor.getString(15)).isEqualTo(targetClass);
-        // Enabled
-        assertThat(cursor.getInt(16) == 1).isEqualTo(enabled);
-        // Data ref key
-        assertThat(cursor.getString(17)).isEqualTo("app_install_location");
-        // User Id
-        assertThat(cursor.getInt(18)).isEqualTo(userId);
-        // Payload Type - default is 0
-        assertThat(cursor.getInt(19)).isEqualTo(0);
-        // Payload - should be updated to real payloads as controllers are added
-        byte[] payload = cursor.getBlob(20);
-        ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload,
-                ResultPayload.CREATOR);
-        assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class);
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
+
+        String listSummary = "summary_4";
+        String listKey = "pref_key_4";
+        final IndexData row = findIndexDataForTitle(indexData, TITLE_FOUR);
+
+        assertDisplaySetting(row, TITLE_FOUR, listSummary, "", listKey);
     }
 
     @Test
     public void testAddResource_iconAddedFromXml() {
-        SearchIndexableResource resource = getFakeResource(xml.connected_devices);
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
+        final SearchIndexableResource resource = getFakeResource(R.xml.display_settings);
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(resource);
 
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null);
-        cursor.moveToPosition(0);
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
 
-        // Icon
-        assertThat(cursor.getInt(12)).isNotEqualTo(noIcon);
+        final IndexData row = findIndexDataForTitle(indexData, TITLE_THREE);
+
+        assertThat(row.iconResId).isGreaterThan(0);
     }
 
     // Tests for the flow: IndexOneResource -> IndexFromProvider -> IndexFromResource ->
     //                     UpdateOneRowWithFilteredData -> UpdateOneRow
 
     @Test
-    public void testResourceProvider_rowInserted() {
-        SearchIndexableResource resource = getFakeResource(xml.swipe_to_notification_settings);
-        resource.xmlResId = 0;
-        resource.className = "com.android.settings.display.ScreenZoomSettings";
+    public void testAddProviderWithResource_rowInserted() {
+        final SearchIndexableResource resource = getFakeResource(0 /* xml */);
+        resource.className = FAKE_CLASS_NAME;
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(resource);
 
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
-        assertThat(cursor.getCount()).isEqualTo(1);
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
+
+        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 testResourceProvider_rowMatches() {
-        SearchIndexableResource resource = getFakeResource(xml.swipe_to_notification_settings);
-        resource.xmlResId = 0;
-        resource.className = "com.android.settings.display.ScreenZoomSettings";
+    public void testAddProviderWithRaw_rowInserted() {
+        final SearchIndexableResource resource = getFakeResource(0 /* xml */);
+        resource.className = FAKE_CLASS_NAME;
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(resource);
 
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
-        cursor.moveToPosition(0);
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
 
-        // Locale
-        assertThat(cursor.getString(0)).isEqualTo(localeStr);
-        // Data Title
-        assertThat(cursor.getString(2)).isEqualTo("Display size");
-        // Normalized Title
-        assertThat(cursor.getString(3)).isEqualTo("display size");
-        // Summary On
-        assertThat(cursor.getString(4)).isEmpty();
-        // Summary On Normalized
-        assertThat(cursor.getString(5)).isEmpty();
-        // Entries - only on for list preferences
-        assertThat(cursor.getString(8)).isNull();
-        // Keywords
-        assertThat(cursor.getString(9)).isEqualTo("display density screen zoom scale scaling");
-        // Screen Title
-        assertThat(cursor.getString(10)).isEqualTo("Display size");
-        // Class Name
-        assertThat(cursor.getString(11))
-                .isEqualTo("com.android.settings.display.ScreenZoomSettings");
-        // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
-        // Intent Action
-        assertThat(cursor.getString(13)).isNull();
-        // Target Package
-        assertThat(cursor.getString(14)).isNull();
-        // Target Class
-        assertThat(cursor.getString(15)).isNull();
-        // Enabled
-        assertThat(cursor.getInt(16) == 1).isEqualTo(enabled);
-        // Data ref key
-        assertThat(cursor.getString(17)).isNull();
-        // User Id
-        assertThat(cursor.getInt(18)).isEqualTo(userId);
-        // Payload Type - default is 0
-        assertThat(cursor.getInt(19)).isEqualTo(0);
-        // Payload - should be updated to real payloads as controllers are added
-        byte[] payload = cursor.getBlob(20);
-        ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload,
+        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,
+                localeStr);
+
+        assertThat(getEnabledResultCount(indexData)).isEqualTo(NUM_ENABLED_FAKE_FRAGMENT_ENTRIES);
+    }
+
+    @Test
+    public void testResource_sameTitleForSettingAndPage_titleNotInserted() {
+        final SearchIndexableResource resource = getFakeResource(R.xml.about_legal);
+        final PreIndexData preIndexData = new PreIndexData();
+        preIndexData.dataToUpdate.add(resource);
+
+        List<IndexData> indexData = mConverter.convertPreIndexDataToIndexData(preIndexData,
+                localeStr);
+
+        int numEnabled = getEnabledResultCount(indexData);
+        final IndexData nonTitlePref = findIndexDataForKey(indexData, "pref_key_1");
+
+        assertThat(indexData.size()).isEqualTo(NUM_LEGAL_SETTINGS - 1);
+        assertThat(numEnabled).isEqualTo(NUM_LEGAL_SETTINGS - 1);
+        assertThat(nonTitlePref.enabled).isTrue();
+    }
+
+    private void assertDisplaySetting(IndexData row, String title, String summaryOn,
+            String summaryOff, String key) {
+        assertThat(row.normalizedTitle).isEqualTo(title);
+        assertThat(row.locale).isEqualTo(localeStr);
+        assertThat(row.updatedSummaryOn).isEqualTo(summaryOn);
+        assertThat(row.spaceDelimitedKeywords).isEqualTo(DISPLAY_SPACE_DELIM_KEYWORDS);
+        assertThat(row.screenTitle).isEqualTo(PAGE_TITLE);
+        assertThat(row.className).isEqualTo(className);
+        assertThat(row.enabled).isEqualTo(true);
+        assertThat(row.key).isEqualTo(key);
+        assertThat(row.payloadType).isEqualTo(0);
+        ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(row.payload,
                 ResultPayload.CREATOR);
         assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class);
     }
 
-    @Test
-    public void testResourceProvider_resourceRowInserted() {
-        SearchIndexableResource resource = getFakeResource(0);
-        resource.className = "com.android.settings.LegalSettings";
-
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
-        assertThat(cursor.getCount()).isEqualTo(6);
-    }
-
-    @Test
-    public void testResourceProvider_resourceRowMatches() {
-        SearchIndexableResource resource = getFakeResource(0 /* xml */);
-        resource.className = "com.android.settings.display.ScreenZoomSettings";
-
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null);
-        cursor.moveToPosition(0);
-
-        // Locale
-        assertThat(cursor.getString(0)).isEqualTo(localeStr);
-        // Data Title
-        assertThat(cursor.getString(2)).isEqualTo("Display size");
-        // Normalized Title
-        assertThat(cursor.getString(3)).isEqualTo("display size");
-        // Summary On
-        assertThat(cursor.getString(4)).isEmpty();
-        // Summary On Normalized
-        assertThat(cursor.getString(5)).isEmpty();
-        // Entries - only on for list preferences
-        assertThat(cursor.getString(8)).isNull();
-        // Keywords
-        assertThat(cursor.getString(9)).isEqualTo(
-                "display density screen zoom scale scaling");
-        // Screen Title
-        assertThat(cursor.getString(10)).isEqualTo("Display size");
-        // Class Name
-        assertThat(cursor.getString(11))
-                .isEqualTo("com.android.settings.display.ScreenZoomSettings");
-        // Icon
-        assertThat(cursor.getInt(12)).isEqualTo(noIcon);
-        // Intent Action
-        assertThat(cursor.getString(13)).isNull();
-        // Target Package
-        assertThat(cursor.getString(14)).isNull();
-        // Target Class
-        assertThat(cursor.getString(15)).isNull();
-        // Enabled
-        assertThat(cursor.getInt(16) == 1).isEqualTo(enabled);
-        // Data ref key
-        assertThat(cursor.getString(17)).isNull();
-        // User Id
-        assertThat(cursor.getInt(18)).isEqualTo(userId);
-        // Payload Type - default is 0
-        assertThat(cursor.getInt(19)).isEqualTo(0);
-        // Payload - should be updated to real payloads as controllers are added
-        byte[] payload = cursor.getBlob(20);
-        ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload,
-                ResultPayload.CREATOR);
-        assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class);
-    }
-
-    @Test
-    public void testResourceProvider_disabledResource_rowsInserted() {
-        SearchIndexableResource resource = getFakeResource(0 /* xml */);
-        resource.className = "com.android.settings.LegalSettings";
-
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
-
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-        cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null);
-        assertThat(cursor.getCount()).isEqualTo(5);
-    }
-
-    @Test
-    public void testResource_withTitleAndSettingName_titleNotInserted() {
-        SearchIndexableResource resource = getFakeResource(xml.swipe_to_notification_settings);
-        mConverter.indexFromResource(localeStr, resource, new ArrayList<>());
-
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE" +
-                " enabled = 1", null);
-        assertThat(cursor.getCount()).isEqualTo(1);
-    }
-
-    @Test
-    public void testResourceProvider_nonSubsettingIntent() {
-        SearchIndexableResource resource = getFakeResource(0 /* xml */);
-        String fakeAction = "fake_action";
-        resource.className = "com.android.settings.LegalSettings";
-        resource.intentAction = fakeAction;
-        resource.intentTargetPackage = SearchIndexableResources.SUBSETTING_TARGET_PACKAGE;
-
-        mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>());
-        Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
-        cursor.moveToPosition(0);
-
-        // Intent Action
-        assertThat(cursor.getString(13)).isEqualTo(fakeAction);
-        // Target Package
-        assertThat(cursor.getString(14))
-                .isEqualTo(SearchIndexableResources.SUBSETTING_TARGET_PACKAGE);
+    private void assertFakeFragment(IndexData row) {
+        assertThat(row.normalizedTitle).isEqualTo(FakeSettingsFragment.TITLE);
+        assertThat(row.updatedSummaryOn).isEqualTo(FakeSettingsFragment.SUMMARY_ON);
+        assertThat(row.spaceDelimitedKeywords)
+                .isEqualTo(FakeSettingsFragment.SPACE_KEYWORDS);
+        assertThat(row.screenTitle).isEqualTo(FakeSettingsFragment.SCREEN_TITLE);
+        assertThat(row.className).isEqualTo(FakeSettingsFragment.CLASS_NAME);
+        assertThat(row.enabled).isEqualTo(FakeSettingsFragment.ENABLED);
+        assertThat(row.key).isEqualTo(FakeSettingsFragment.KEY);
     }
 
     private SearchIndexableRaw getFakeRaw() {
@@ -634,11 +410,34 @@
         return sir;
     }
 
-    private Map<String, Set<String>> getNonIndexableKeys(String[] keys) {
-        Map<String, Set<String>> niks = new HashMap<>();
-        Set<String> keysList = new HashSet<>();
-        keysList.addAll(Arrays.asList(keys));
-        niks.put(packageName, keysList);
-        return niks;
+    private static int getEnabledResultCount(List<IndexData> indexData) {
+        int enabledCount = 0;
+        for (IndexData data : indexData) {
+            if (data.enabled) {
+                enabledCount++;
+            }
+        }
+        return enabledCount;
+    }
+
+    private static IndexData findIndexDataForTitle(List<IndexData> indexData,
+            String indexDataTitle) {
+        for (int i = 0; i < indexData.size(); i++) {
+            IndexData row = indexData.get(i);
+            if (TextUtils.equals(row.updatedTitle, indexDataTitle)) {
+                return row;
+            }
+        }
+        return null;
+    }
+
+    private static IndexData findIndexDataForKey(List<IndexData> indexData, String indexDataKey) {
+        for (int i = 0; i < indexData.size(); i++) {
+            IndexData row = indexData.get(i);
+            if (TextUtils.equals(row.key, indexDataKey)) {
+                return row;
+            }
+        }
+        return null;
     }
 }