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; } }