From 80e54df83337be5fd37f2fc85f274c7442784740 Mon Sep 17 00:00:00 2001 From: Matthew Fritze Date: Thu, 31 Aug 2017 14:13:06 -0700 Subject: [PATCH] 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 --- .../search/DatabaseIndexingManager.java | 93 ++- .../search/indexing/IndexDataConverter.java | 147 ++-- ...ther_not_in_search_index_provider_registry | 1 + .../robotests/res/xml-mcc999/about_legal.xml | 34 + .../res/xml-mcc999/display_settings.xml | 61 ++ .../search/indexing/FakeSettingsFragment.java | 125 +++ .../indexing/IndexDataConverterTest.java | 751 +++++++----------- 7 files changed, 625 insertions(+), 587 deletions(-) create mode 100644 tests/robotests/res/xml-mcc999/about_legal.xml create mode 100644 tests/robotests/res/xml-mcc999/display_settings.xml create mode 100644 tests/robotests/src/com/android/settings/search/indexing/FakeSettingsFragment.java diff --git a/src/com/android/settings/search/DatabaseIndexingManager.java b/src/com/android/settings/search/DatabaseIndexingManager.java index de71f0a6539..d540d2fd763 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 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.os.Build; 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 com.android.settings.search.indexing.PreIndexDataCollector; 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 @@ public class DatabaseIndexingManager { final AtomicBoolean mIsIndexingComplete = new AtomicBoolean(false); private PreIndexDataCollector mCollector; + private IndexDataConverter mConverter; private Context mContext; @@ -182,8 +203,8 @@ public class DatabaseIndexingManager { * @param localeStr the default locale for the device. */ @VisibleForTesting - void updateDatabase(PreIndexData indexData, boolean needsReindexing, String localeStr) { - final Map> nonIndexableKeys = indexData.nonIndexableKeys; + void updateDatabase(PreIndexData preIndexData, boolean needsReindexing, String localeStr) { + final Map> nonIndexableKeys = preIndexData.nonIndexableKeys; final SQLiteDatabase database = getWritableDatabase(); if (database == null) { @@ -194,8 +215,9 @@ public class DatabaseIndexingManager { 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 = 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 @@ public class DatabaseIndexingManager { } } - @VisibleForTesting - void addIndaxebleDataToDatabase(SQLiteDatabase database, String locale, PreIndexData data) { - if (data.dataToUpdate.size() == 0) { - return; + List getIndexData(String locale, PreIndexData data) { + if (mConverter == null) { + mConverter = new IndexDataConverter(mContext); + } + 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) { + 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); + } } - IndexDataConverter manager = new IndexDataConverter(mContext, database); - manager.addDataToDatabase(locale, data.dataToUpdate, data.nonIndexableKeys); } /** @@ -288,7 +360,6 @@ public class DatabaseIndexingManager { 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 f900b83cdc6..90430a8376e 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 android.util.Xml; 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 org.xmlpull.v1.XmlPullParserException; 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 @@ public class IndexDataConverter { 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 mIndexData; + + public IndexDataConverter(Context context) { mContext = context; - mDb = database; + mLocale = Locale.getDefault().toString(); + } + + public List convertPreIndexDataToIndexData(PreIndexData preIndexData, + String locale) { + mLocale = locale; + mIndexData = new ArrayList<>(); + List dataToUpdate = preIndexData.dataToUpdate; + Map> 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 dataToUpdate, + private void parsePreIndexData(List dataToUpdate, Map> 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> 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> 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 @@ public class IndexDataConverter { 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 @@ public class IndexDataConverter { .setKey(raw.key) .setUserId(raw.userId); - updateOneRow(builder.build(mContext)); + addRowToData(builder.build(mContext)); } - @VisibleForTesting - void indexOneResource(String localeStr, SearchIndexableResource sir, - Map> nonIndexableKeysFromResource) { + private void addOneResource(SearchIndexableResource sir, + Map> nonIndexableKeysFromResource) { if (sir == null) { Log.e(LOG_TAG, "Cannot index a null resource!"); @@ -182,7 +164,7 @@ public class IndexDataConverter { 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 @@ public class IndexDataConverter { DatabaseIndexingUtils.getSearchIndexProvider(clazz); if (provider != null) { List 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 nonIndexableKeys) { final Context context = sir.context; XmlResourceParser parser = null; @@ -274,7 +255,7 @@ public class IndexDataConverter { headerBuilder.setTitle(headerTitle) .setSummaryOn(headerSummary) .setKeywords(headerKeywords) - .setLocale(localeStr) + .setLocale(mLocale) .setClassName(fragmentName) .setScreenTitle(screenTitle) .setIntentAction(intentAction) @@ -308,7 +289,7 @@ public class IndexDataConverter { builder = new IndexData.Builder(); builder.setTitle(title) - .setLocale(localeStr) + .setLocale(mLocale) .setKeywords(keywords) .setClassName(fragmentName) .setScreenTitle(screenTitle) @@ -339,7 +320,7 @@ public class IndexDataConverter { .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 @@ public class IndexDataConverter { 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 @@ public class IndexDataConverter { } } - @VisibleForTesting - void indexFromProvider(String localeStr, Indexable.SearchIndexProvider provider, + private void addIndexDataFromProvider(Indexable.SearchIndexProvider provider, SearchIndexableResource sir, List nonIndexableKeys) { final String className = sir.className; @@ -393,7 +373,7 @@ public class IndexDataConverter { 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 @@ public class IndexDataConverter { 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 @@ public class IndexDataConverter { .setKey(raw.key) .setUserId(raw.userId); - updateOneRow(builder.build(mContext)); + addRowToData(builder.build(mContext)); } } @@ -426,7 +406,7 @@ public class IndexDataConverter { 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 @@ public class IndexDataConverter { ? 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 a2a772ba778..4ee97fa5fc7 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 00000000000..53a2b897391 --- /dev/null +++ b/tests/robotests/res/xml-mcc999/about_legal.xml @@ -0,0 +1,34 @@ + + + + + + + + + \ 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 00000000000..4e0ce6b65c2 --- /dev/null +++ b/tests/robotests/res/xml-mcc999/display_settings.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + \ 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 00000000000..72df77192f5 --- /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 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 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 result = new ArrayList<>(1); + result.add(data); + return result; + } + + @Override + public List getXmlResourcesToIndex(Context context, + boolean enabled) { + final ArrayList 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 getNonIndexableKeys(Context context) { + List keys = super.getNonIndexableKeys(context); + keys.add("pref_key_1"); + keys.add("pref_key_3"); + return keys; + } + + @Override + public List + 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 ca04d2c6826..b5bfea08fe3 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.junit.runner.RunWith; 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 @@ public class IndexDataConverterTest { } @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 = mConverter.convertPreIndexDataToIndexData(preIndexData, + localeStr); - @Test - public void testInsertRawColumn_nonIndexableKey_resultIsDisabled() { - SearchIndexableRaw raw = getFakeRaw(); - Map> niks = new HashMap<>(); - Set 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 keys = new HashSet<>(); + keys.add(raw.key); + + final PreIndexData preIndexData = new PreIndexData(); + preIndexData.dataToUpdate.add(raw); + preIndexData.nonIndexableKeys.put(raw.intentTargetPackage, keys); + + List 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 = mConverter.convertPreIndexDataToIndexData(preIndexData, + localeStr); + + assertThat(indexData).isEmpty(); } // Tests for the flow: IndexOneResource -> IndexFromResource -> @@ -179,421 +174,202 @@ public class IndexDataConverterTest { @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 = 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 = 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> niks = getNonIndexableKeys(keys); + final SearchIndexableResource resource = getFakeResource(R.xml.display_settings); + Set 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 @@ public class IndexDataConverterTest { return sir; } - private Map> getNonIndexableKeys(String[] keys) { - Map> niks = new HashMap<>(); - Set keysList = new HashSet<>(); - keysList.addAll(Arrays.asList(keys)); - niks.put(packageName, keysList); - return niks; + private static int getEnabledResultCount(List indexData) { + int enabledCount = 0; + for (IndexData data : indexData) { + if (data.enabled) { + enabledCount++; + } + } + return enabledCount; + } + + private static IndexData findIndexDataForTitle(List 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, 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; } }