diff --git a/src/com/android/settings/search/DatabaseIndexingManager.java b/src/com/android/settings/search/DatabaseIndexingManager.java index a0f47d16542..9c79885602a 100644 --- a/src/com/android/settings/search/DatabaseIndexingManager.java +++ b/src/com/android/settings/search/DatabaseIndexingManager.java @@ -22,68 +22,33 @@ import static com.android.settings.search.DatabaseResultLoader .COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE; 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.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.DOCID; 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.ComponentName; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; -import android.content.res.XmlResourceParser; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteException; import android.os.AsyncTask; import android.os.Build; -import android.provider.SearchIndexableData; import android.provider.SearchIndexableResource; import android.provider.SearchIndexablesContract; -import android.support.annotation.DrawableRes; import android.support.annotation.VisibleForTesting; -import android.text.TextUtils; -import android.util.AttributeSet; import android.util.Log; -import android.util.Xml; -import com.android.settings.SettingsActivity; -import com.android.settings.core.PreferenceControllerMixin; import com.android.settings.overlay.FeatureFactory; -import com.android.settings.search.indexing.IndexableDataCollector; +import com.android.settings.search.indexing.IndexDataConverter; import com.android.settings.search.indexing.PreIndexData; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; +import com.android.settings.search.indexing.PreIndexDataCollector; -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 java.util.concurrent.atomic.AtomicBoolean; @@ -91,7 +56,7 @@ import java.util.concurrent.atomic.AtomicBoolean; * Consumes the SearchIndexableProvider content providers. * Updates the Resource, Raw Data and non-indexable data for Search. * - * TODO this class needs to be refactored by moving most of its methods into controllers + * TODO(b/33577327) this class needs to be refactored by moving most of its methods into controllers */ public class DatabaseIndexingManager { @@ -103,14 +68,10 @@ public class DatabaseIndexingManager { public static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER = "SEARCH_INDEX_DATA_PROVIDER"; - private static final String NODE_NAME_PREFERENCE_SCREEN = "PreferenceScreen"; - private static final String NODE_NAME_CHECK_BOX_PREFERENCE = "CheckBoxPreference"; - private static final String NODE_NAME_LIST_PREFERENCE = "ListPreference"; - @VisibleForTesting final AtomicBoolean mIsIndexingComplete = new AtomicBoolean(false); - private IndexableDataCollector mCollector; + private PreIndexDataCollector mCollector; private Context mContext; @@ -143,8 +104,8 @@ public class DatabaseIndexingManager { final String providerVersionedNames = IndexDatabaseHelper.buildProviderVersionedNames(providers); - final boolean isFullIndex = isFullIndex(mContext, localeStr, - fingerprint, providerVersionedNames); + final boolean isFullIndex = isFullIndex(mContext, localeStr, fingerprint, + providerVersionedNames); if (isFullIndex) { rebuildDatabase(); @@ -174,7 +135,7 @@ public class DatabaseIndexingManager { @VisibleForTesting PreIndexData getIndexDataFromProviders(List providers, boolean isFullIndex) { if (mCollector == null) { - mCollector = new IndexableDataCollector(mContext); + mCollector = new PreIndexDataCollector(mContext); } return mCollector.collectIndexableData(providers, isFullIndex); } @@ -191,7 +152,7 @@ public class DatabaseIndexingManager { */ @VisibleForTesting boolean isFullIndex(Context context, String locale, String fingerprint, - String providerVersionedNames) { + String providerVersionedNames) { final boolean isLocaleIndexed = IndexDatabaseHelper.isLocaleAlreadyIndexed(context, locale); final boolean isBuildIndexed = IndexDatabaseHelper.isBuildIndexed(context, fingerprint); final boolean areProvidersIndexed = IndexDatabaseHelper @@ -222,7 +183,6 @@ public class DatabaseIndexingManager { */ @VisibleForTesting void updateDatabase(PreIndexData indexData, boolean needsReindexing, String localeStr) { - final List dataToUpdate = indexData.dataToUpdate; final Map> nonIndexableKeys = indexData.nonIndexableKeys; final SQLiteDatabase database = getWritableDatabase(); @@ -235,9 +195,7 @@ public class DatabaseIndexingManager { database.beginTransaction(); // Add new data from Providers at initial index time, or inserted later. - if (dataToUpdate.size() > 0) { - addDataToDatabase(database, localeStr, dataToUpdate, nonIndexableKeys); - } + addIndaxebleDataToDatabase(database, localeStr, indexData); // Only check for non-indexable key updates after initial index. // Enabled state with non-indexable keys is checked when items are first inserted. @@ -251,32 +209,14 @@ public class DatabaseIndexingManager { } } - /** - * Inserts {@link SearchIndexableData} into the database. - * - * @param database where the data will be inserted. - * @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. - */ + @VisibleForTesting - void addDataToDatabase(SQLiteDatabase database, String localeStr, - List dataToUpdate, Map> nonIndexableKeys) { - final long current = System.currentTimeMillis(); - - for (SearchIndexableData data : dataToUpdate) { - try { - indexOneSearchIndexableData(database, localeStr, data, nonIndexableKeys); - } catch (Exception e) { - Log.e(LOG_TAG, "Cannot index: " + (data != null ? data.className : data) - + " for locale: " + localeStr, e); - } + void addIndaxebleDataToDatabase(SQLiteDatabase database, String locale, PreIndexData data) { + if (data.dataToUpdate.size() == 0) { + return; } - - final long now = System.currentTimeMillis(); - Log.d(LOG_TAG, "Indexing locale '" + localeStr + "' took " + - (now - current) + " millis"); + IndexDataConverter manager = new IndexDataConverter(mContext, database); + manager.addDataToDatabase(locale, data.dataToUpdate, data.nonIndexableKeys); } /** @@ -388,646 +328,6 @@ public class DatabaseIndexingManager { } } - - @VisibleForTesting - void indexOneSearchIndexableData(SQLiteDatabase database, String localeStr, - SearchIndexableData data, Map> nonIndexableKeys) { - if (data instanceof SearchIndexableResource) { - indexOneResource(database, localeStr, (SearchIndexableResource) data, nonIndexableKeys); - } else if (data instanceof SearchIndexableRaw) { - indexOneRaw(database, localeStr, (SearchIndexableRaw) data, nonIndexableKeys); - } - } - - private void indexOneRaw(SQLiteDatabase database, String localeStr, - SearchIndexableRaw raw, Map> nonIndexableKeysFromResource) { - // Should be the same locale as the one we are processing - if (!raw.locale.toString().equalsIgnoreCase(localeStr)) { - return; - } - - Set packageKeys = nonIndexableKeysFromResource.get(raw.intentTargetPackage); - boolean enabled = raw.enabled; - - if (packageKeys != null && packageKeys.contains(raw.key)) { - enabled = false; - } - - DatabaseRow.Builder builder = new DatabaseRow.Builder(); - builder.setLocale(localeStr) - .setEntries(raw.entries) - .setClassName(raw.className) - .setScreenTitle(raw.screenTitle) - .setIconResId(raw.iconResId) - .setRank(raw.rank) - .setIntentAction(raw.intentAction) - .setIntentTargetPackage(raw.intentTargetPackage) - .setIntentTargetClass(raw.intentTargetClass) - .setEnabled(enabled) - .setKey(raw.key) - .setUserId(raw.userId); - - updateOneRowWithFilteredData(database, builder, raw.title, raw.summaryOn, raw.summaryOff, - raw.keywords); - } - - private void indexOneResource(SQLiteDatabase database, String localeStr, - SearchIndexableResource sir, Map> nonIndexableKeysFromResource) { - - if (sir == null) { - Log.e(LOG_TAG, "Cannot index a null resource!"); - return; - } - - final List nonIndexableKeys = new ArrayList(); - - if (sir.xmlResId > SearchIndexableResources.NO_DATA_RES_ID) { - Set resNonIndexableKeys = nonIndexableKeysFromResource.get(sir.packageName); - if (resNonIndexableKeys != null && resNonIndexableKeys.size() > 0) { - nonIndexableKeys.addAll(resNonIndexableKeys); - } - - indexFromResource(database, localeStr, sir, nonIndexableKeys); - } else { - if (TextUtils.isEmpty(sir.className)) { - Log.w(LOG_TAG, "Cannot index an empty Search Provider name!"); - return; - } - - final Class clazz = DatabaseIndexingUtils.getIndexableClass(sir.className); - if (clazz == null) { - Log.d(LOG_TAG, "SearchIndexableResource '" + sir.className + - "' should implement the " + Indexable.class.getName() + " interface!"); - return; - } - - // Will be non null only for a Local provider implementing a - // SEARCH_INDEX_DATA_PROVIDER field - final Indexable.SearchIndexProvider provider = - DatabaseIndexingUtils.getSearchIndexProvider(clazz); - if (provider != null) { - List providerNonIndexableKeys = provider.getNonIndexableKeys(sir.context); - if (providerNonIndexableKeys != null && providerNonIndexableKeys.size() > 0) { - nonIndexableKeys.addAll(providerNonIndexableKeys); - } - - indexFromProvider(database, localeStr, provider, sir, nonIndexableKeys); - } - } - } - - @VisibleForTesting - void indexFromResource(SQLiteDatabase database, String localeStr, - SearchIndexableResource sir, List nonIndexableKeys) { - final Context context = sir.context; - XmlResourceParser parser = null; - try { - parser = context.getResources().getXml(sir.xmlResId); - - int type; - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && type != XmlPullParser.START_TAG) { - // Parse next until start tag is found - } - - String nodeName = parser.getName(); - if (!NODE_NAME_PREFERENCE_SCREEN.equals(nodeName)) { - throw new RuntimeException( - "XML document must start with tag; found" - + nodeName + " at " + parser.getPositionDescription()); - } - - final int outerDepth = parser.getDepth(); - final AttributeSet attrs = Xml.asAttributeSet(parser); - - final String screenTitle = XmlParserUtils.getDataTitle(context, attrs); - String key = XmlParserUtils.getDataKey(context, attrs); - - String title; - String headerTitle; - String summary; - String headerSummary; - String keywords; - String headerKeywords; - String childFragment; - @DrawableRes - int iconResId; - ResultPayload payload; - boolean enabled; - final String fragmentName = sir.className; - final int rank = sir.rank; - final String intentAction = sir.intentAction; - final String intentTargetPackage = sir.intentTargetPackage; - final String intentTargetClass = sir.intentTargetClass; - - Map controllerUriMap = null; - - if (fragmentName != null) { - controllerUriMap = DatabaseIndexingUtils - .getPreferenceControllerUriMap(fragmentName, context); - } - - // Insert rows for the main PreferenceScreen node. Rewrite the data for removing - // hyphens. - - headerTitle = XmlParserUtils.getDataTitle(context, attrs); - headerSummary = XmlParserUtils.getDataSummary(context, attrs); - headerKeywords = XmlParserUtils.getDataKeywords(context, attrs); - enabled = !nonIndexableKeys.contains(key); - - // TODO: Set payload type for header results - DatabaseRow.Builder headerBuilder = new DatabaseRow.Builder(); - headerBuilder.setLocale(localeStr) - .setEntries(null) - .setClassName(fragmentName) - .setScreenTitle(screenTitle) - .setRank(rank) - .setIntentAction(intentAction) - .setIntentTargetPackage(intentTargetPackage) - .setIntentTargetClass(intentTargetClass) - .setEnabled(enabled) - .setKey(key) - .setUserId(-1 /* default user id */); - - // Flag for XML headers which a child element's title. - boolean isHeaderUnique = true; - DatabaseRow.Builder builder; - - while ((type = parser.next()) != XmlPullParser.END_DOCUMENT - && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { - if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { - continue; - } - - nodeName = parser.getName(); - - title = XmlParserUtils.getDataTitle(context, attrs); - key = XmlParserUtils.getDataKey(context, attrs); - enabled = !nonIndexableKeys.contains(key); - keywords = XmlParserUtils.getDataKeywords(context, attrs); - iconResId = XmlParserUtils.getDataIcon(context, attrs); - - if (isHeaderUnique && TextUtils.equals(headerTitle, title)) { - isHeaderUnique = false; - } - - builder = new DatabaseRow.Builder(); - builder.setLocale(localeStr) - .setClassName(fragmentName) - .setScreenTitle(screenTitle) - .setIconResId(iconResId) - .setRank(rank) - .setIntentAction(intentAction) - .setIntentTargetPackage(intentTargetPackage) - .setIntentTargetClass(intentTargetClass) - .setEnabled(enabled) - .setKey(key) - .setUserId(-1 /* default user id */); - - if (!nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) { - summary = XmlParserUtils.getDataSummary(context, attrs); - - String entries = null; - - if (nodeName.endsWith(NODE_NAME_LIST_PREFERENCE)) { - entries = XmlParserUtils.getDataEntries(context, attrs); - } - - // TODO (b/62254931) index primitives instead of payload - payload = DatabaseIndexingUtils.getPayloadFromUriMap(controllerUriMap, key); - childFragment = XmlParserUtils.getDataChildFragment(context, attrs); - - builder.setEntries(entries) - .setChildClassName(childFragment) - .setPayload(payload); - - // Insert rows for the child nodes of PreferenceScreen - updateOneRowWithFilteredData(database, builder, title, summary, - null /* summary off */, keywords); - } else { - String summaryOn = XmlParserUtils.getDataSummaryOn(context, attrs); - String summaryOff = XmlParserUtils.getDataSummaryOff(context, attrs); - - if (TextUtils.isEmpty(summaryOn) && TextUtils.isEmpty(summaryOff)) { - summaryOn = XmlParserUtils.getDataSummary(context, attrs); - } - - updateOneRowWithFilteredData(database, builder, title, summaryOn, summaryOff, - keywords); - } - } - - // The xml header's title does not match the title of one of the child settings. - if (isHeaderUnique) { - updateOneRowWithFilteredData(database, headerBuilder, headerTitle, headerSummary, - null /* summary off */, headerKeywords); - } - } catch (XmlPullParserException e) { - throw new RuntimeException("Error parsing PreferenceScreen", e); - } catch (IOException e) { - throw new RuntimeException("Error parsing PreferenceScreen", e); - } finally { - if (parser != null) parser.close(); - } - } - - private void indexFromProvider(SQLiteDatabase database, String localeStr, - Indexable.SearchIndexProvider provider, SearchIndexableResource sir, - List nonIndexableKeys) { - - final String className = sir.className; - final String intentAction = sir.intentAction; - final String intentTargetPackage = sir.intentTargetPackage; - - if (provider == null) { - Log.w(LOG_TAG, "Cannot find provider: " + className); - return; - } - - final List rawList = provider.getRawDataToIndex(mContext, - true /* enabled */); - - if (rawList != null) { - - final int rawSize = rawList.size(); - for (int i = 0; i < rawSize; i++) { - SearchIndexableRaw raw = rawList.get(i); - - // Should be the same locale as the one we are processing - if (!raw.locale.toString().equalsIgnoreCase(localeStr)) { - continue; - } - boolean enabled = !nonIndexableKeys.contains(raw.key); - - DatabaseRow.Builder builder = new DatabaseRow.Builder(); - builder.setLocale(localeStr) - .setEntries(raw.entries) - .setClassName(className) - .setScreenTitle(raw.screenTitle) - .setIconResId(raw.iconResId) - .setIntentAction(raw.intentAction) - .setIntentTargetPackage(raw.intentTargetPackage) - .setIntentTargetClass(raw.intentTargetClass) - .setEnabled(enabled) - .setKey(raw.key) - .setUserId(raw.userId); - - updateOneRowWithFilteredData(database, builder, raw.title, raw.summaryOn, - raw.summaryOff, raw.keywords); - } - } - - final List resList = - provider.getXmlResourcesToIndex(mContext, true); - if (resList != null) { - final int resSize = resList.size(); - for (int i = 0; i < resSize; i++) { - SearchIndexableResource item = resList.get(i); - - // Should be the same locale as the one we are processing - if (!item.locale.toString().equalsIgnoreCase(localeStr)) { - continue; - } - - item.className = TextUtils.isEmpty(item.className) - ? className - : item.className; - item.intentAction = TextUtils.isEmpty(item.intentAction) - ? intentAction - : item.intentAction; - item.intentTargetPackage = TextUtils.isEmpty(item.intentTargetPackage) - ? intentTargetPackage - : item.intentTargetPackage; - - indexFromResource(database, localeStr, item, nonIndexableKeys); - } - } - } - - private void updateOneRowWithFilteredData(SQLiteDatabase database, DatabaseRow.Builder builder, - String title, String summaryOn, String summaryOff, String keywords) { - - final String updatedTitle = DatabaseIndexingUtils.normalizeHyphen(title); - final String updatedSummaryOn = DatabaseIndexingUtils.normalizeHyphen(summaryOn); - final String updatedSummaryOff = DatabaseIndexingUtils.normalizeHyphen(summaryOff); - - final String normalizedTitle = DatabaseIndexingUtils.normalizeString(updatedTitle); - final String normalizedSummaryOn = DatabaseIndexingUtils.normalizeString(updatedSummaryOn); - final String normalizedSummaryOff = DatabaseIndexingUtils - .normalizeString(updatedSummaryOff); - - final String spaceDelimitedKeywords = DatabaseIndexingUtils.normalizeKeywords(keywords); - - builder.setUpdatedTitle(updatedTitle) - .setUpdatedSummaryOn(updatedSummaryOn) - .setUpdatedSummaryOff(updatedSummaryOff) - .setNormalizedTitle(normalizedTitle) - .setNormalizedSummaryOn(normalizedSummaryOn) - .setNormalizedSummaryOff(normalizedSummaryOff) - .setSpaceDelimitedKeywords(spaceDelimitedKeywords); - - updateOneRow(database, builder.build(mContext)); - } - - private void updateOneRow(SQLiteDatabase database, DatabaseRow 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_RANK, row.rank); - 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_SUMMARY_OFF, row.updatedSummaryOff); - values.put(DATA_SUMMARY_OFF_NORMALIZED, row.normalizedSummaryOff); - 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); - - database.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); - - database.replaceOrThrow(IndexDatabaseHelper.Tables.TABLE_SITE_MAP, null, siteMapPair); - } - } - - public static class DatabaseRow { - public final String locale; - public final String updatedTitle; - public final String normalizedTitle; - public final String updatedSummaryOn; - public final String normalizedSummaryOn; - public final String updatedSummaryOff; - public final String normalizedSummaryOff; - public final String entries; - public final String className; - public final String childClassName; - public final String screenTitle; - public final int iconResId; - public final int rank; - public final String spaceDelimitedKeywords; - public final String intentAction; - public final String intentTargetPackage; - public final String intentTargetClass; - public final boolean enabled; - public final String key; - public final int userId; - public final int payloadType; - public final byte[] payload; - - private DatabaseRow(Builder builder) { - locale = builder.mLocale; - updatedTitle = builder.mUpdatedTitle; - normalizedTitle = builder.mNormalizedTitle; - updatedSummaryOn = builder.mUpdatedSummaryOn; - normalizedSummaryOn = builder.mNormalizedSummaryOn; - updatedSummaryOff = builder.mUpdatedSummaryOff; - normalizedSummaryOff = builder.mNormalizedSummaryOff; - entries = builder.mEntries; - className = builder.mClassName; - childClassName = builder.mChildClassName; - screenTitle = builder.mScreenTitle; - iconResId = builder.mIconResId; - rank = builder.mRank; - spaceDelimitedKeywords = builder.mSpaceDelimitedKeywords; - intentAction = builder.mIntentAction; - intentTargetPackage = builder.mIntentTargetPackage; - intentTargetClass = builder.mIntentTargetClass; - enabled = builder.mEnabled; - key = builder.mKey; - userId = builder.mUserId; - payloadType = builder.mPayloadType; - payload = builder.mPayload != null ? ResultPayloadUtils.marshall(builder.mPayload) - : null; - } - - /** - * Returns the doc id for this row. - */ - public int getDocId() { - // Eventually we want all DocIds to be the data_reference key. For settings values, - // this will be preference keys, and for non-settings they should be unique. - return TextUtils.isEmpty(key) - ? Objects.hash(updatedTitle, className, screenTitle, intentTargetClass) - : key.hashCode(); - } - - public static class Builder { - private String mLocale; - private String mUpdatedTitle; - private String mNormalizedTitle; - private String mUpdatedSummaryOn; - private String mNormalizedSummaryOn; - private String mUpdatedSummaryOff; - private String mNormalizedSummaryOff; - private String mEntries; - private String mClassName; - private String mChildClassName; - private String mScreenTitle; - private int mIconResId; - private int mRank; - private String mSpaceDelimitedKeywords; - private String mIntentAction; - private String mIntentTargetPackage; - private String mIntentTargetClass; - private boolean mEnabled; - private String mKey; - private int mUserId; - @ResultPayload.PayloadType - private int mPayloadType; - private ResultPayload mPayload; - - public Builder setLocale(String locale) { - mLocale = locale; - return this; - } - - public Builder setUpdatedTitle(String updatedTitle) { - mUpdatedTitle = updatedTitle; - return this; - } - - public Builder setNormalizedTitle(String normalizedTitle) { - mNormalizedTitle = normalizedTitle; - return this; - } - - public Builder setUpdatedSummaryOn(String updatedSummaryOn) { - mUpdatedSummaryOn = updatedSummaryOn; - return this; - } - - public Builder setNormalizedSummaryOn(String normalizedSummaryOn) { - mNormalizedSummaryOn = normalizedSummaryOn; - return this; - } - - public Builder setUpdatedSummaryOff(String updatedSummaryOff) { - mUpdatedSummaryOff = updatedSummaryOff; - return this; - } - - public Builder setNormalizedSummaryOff(String normalizedSummaryOff) { - this.mNormalizedSummaryOff = normalizedSummaryOff; - return this; - } - - public Builder setEntries(String entries) { - mEntries = entries; - return this; - } - - public Builder setClassName(String className) { - mClassName = className; - return this; - } - - public Builder setChildClassName(String childClassName) { - mChildClassName = childClassName; - return this; - } - - public Builder setScreenTitle(String screenTitle) { - mScreenTitle = screenTitle; - return this; - } - - public Builder setIconResId(int iconResId) { - mIconResId = iconResId; - return this; - } - - public Builder setRank(int rank) { - mRank = rank; - return this; - } - - public Builder setSpaceDelimitedKeywords(String spaceDelimitedKeywords) { - mSpaceDelimitedKeywords = spaceDelimitedKeywords; - return this; - } - - public Builder setIntentAction(String intentAction) { - mIntentAction = intentAction; - return this; - } - - public Builder setIntentTargetPackage(String intentTargetPackage) { - mIntentTargetPackage = intentTargetPackage; - return this; - } - - public Builder setIntentTargetClass(String intentTargetClass) { - mIntentTargetClass = intentTargetClass; - return this; - } - - public Builder setEnabled(boolean enabled) { - mEnabled = enabled; - return this; - } - - public Builder setKey(String key) { - mKey = key; - return this; - } - - public Builder setUserId(int userId) { - mUserId = userId; - return this; - } - - public Builder setPayload(ResultPayload payload) { - mPayload = payload; - - if (mPayload != null) { - setPayloadType(mPayload.getType()); - } - return this; - } - - /** - * Payload type is added when a Payload is added to the Builder in {setPayload} - * - * @param payloadType PayloadType - * @return The Builder - */ - private Builder setPayloadType(@ResultPayload.PayloadType int payloadType) { - mPayloadType = payloadType; - return this; - } - - /** - * Adds intent to inline payloads, or creates an Intent Payload as a fallback if the - * payload is null. - */ - private void setIntent(Context context) { - if (mPayload != null) { - return; - } - final Intent intent = buildIntent(context); - mPayload = new ResultPayload(intent); - mPayloadType = ResultPayload.PayloadType.INTENT; - } - - /** - * Adds Intent payload to builder. - */ - private Intent buildIntent(Context context) { - final Intent intent; - - boolean isEmptyIntentAction = TextUtils.isEmpty(mIntentAction); - // No intent action is set, or the intent action is for a subsetting. - if (isEmptyIntentAction - || (!isEmptyIntentAction && TextUtils.equals(mIntentTargetPackage, - SearchIndexableResources.SUBSETTING_TARGET_PACKAGE))) { - // Action is null, we will launch it as a sub-setting - intent = DatabaseIndexingUtils.buildSubsettingIntent(context, mClassName, mKey, - mScreenTitle); - } else { - intent = new Intent(mIntentAction); - final String targetClass = mIntentTargetClass; - if (!TextUtils.isEmpty(mIntentTargetPackage) - && !TextUtils.isEmpty(targetClass)) { - final ComponentName component = new ComponentName(mIntentTargetPackage, - targetClass); - intent.setComponent(component); - } - intent.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, mKey); - } - return intent; - } - - public DatabaseRow build(Context context) { - setIntent(context); - return new DatabaseRow(this); - } - } - } - public class IndexingTask extends AsyncTask { @VisibleForTesting diff --git a/src/com/android/settings/search/DatabaseIndexingUtils.java b/src/com/android/settings/search/DatabaseIndexingUtils.java index 7093134d769..f43f210ec27 100644 --- a/src/com/android/settings/search/DatabaseIndexingUtils.java +++ b/src/com/android/settings/search/DatabaseIndexingUtils.java @@ -174,18 +174,18 @@ public class DatabaseIndexingUtils { return null; } - static String normalizeHyphen(String input) { + public static String normalizeHyphen(String input) { return (input != null) ? input.replaceAll(NON_BREAKING_HYPHEN, HYPHEN) : EMPTY; } - static String normalizeString(String input) { + public static String normalizeString(String input) { final String nohyphen = (input != null) ? input.replaceAll(HYPHEN, EMPTY) : EMPTY; final String normalized = Normalizer.normalize(nohyphen, Normalizer.Form.NFD); return REMOVE_DIACRITICALS_PATTERN.matcher(normalized).replaceAll("").toLowerCase(); } - static String normalizeKeywords(String input) { + public static String normalizeKeywords(String input) { return (input != null) ? input.replaceAll(LIST_DELIMITERS, SPACE) : EMPTY; } } diff --git a/src/com/android/settings/search/InlinePayload.java b/src/com/android/settings/search/InlinePayload.java index 03b882839d7..1cb694a7cb6 100644 --- a/src/com/android/settings/search/InlinePayload.java +++ b/src/com/android/settings/search/InlinePayload.java @@ -35,8 +35,7 @@ public abstract class InlinePayload extends ResultPayload { /** * Defines the key to access and store the Setting the inline result represents. */ - @VisibleForTesting - final String mSettingKey; + private final String mSettingKey; /** * Defines where the Setting is stored. @@ -154,4 +153,8 @@ public abstract class InlinePayload extends ResultPayload { return false; } + + public String getKey() { + return mSettingKey; + } } \ No newline at end of file diff --git a/src/com/android/settings/search/indexing/IndexData.java b/src/com/android/settings/search/indexing/IndexData.java new file mode 100644 index 00000000000..b0c79f368b6 --- /dev/null +++ b/src/com/android/settings/search/indexing/IndexData.java @@ -0,0 +1,287 @@ +/* + * 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.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.text.TextUtils; +import com.android.settings.SettingsActivity; +import com.android.settings.search.DatabaseIndexingUtils; +import com.android.settings.search.ResultPayload; +import com.android.settings.search.ResultPayloadUtils; +import com.android.settings.search.SearchIndexableResources; + +import java.util.Objects; + +/** + * Data class representing a single row in the Setting Search results database. + */ +public class IndexData { + public final String locale; + public final String updatedTitle; + public final String normalizedTitle; + public final String updatedSummaryOn; + public final String normalizedSummaryOn; + public final String updatedSummaryOff; + public final String normalizedSummaryOff; + public final String entries; + public final String className; + public final String childClassName; + public final String screenTitle; + public final int iconResId; + public final int rank; + public final String spaceDelimitedKeywords; + public final String intentAction; + public final String intentTargetPackage; + public final String intentTargetClass; + public final boolean enabled; + public final String key; + public final int userId; + public final int payloadType; + public final byte[] payload; + + private IndexData(Builder builder) { + locale = builder.mLocale; + updatedTitle = builder.mUpdatedTitle; + normalizedTitle = builder.mNormalizedTitle; + updatedSummaryOn = builder.mUpdatedSummaryOn; + normalizedSummaryOn = builder.mNormalizedSummaryOn; + updatedSummaryOff = builder.mUpdatedSummaryOff; + normalizedSummaryOff = builder.mNormalizedSummaryOff; + entries = builder.mEntries; + className = builder.mClassName; + childClassName = builder.mChildClassName; + screenTitle = builder.mScreenTitle; + iconResId = builder.mIconResId; + rank = builder.mRank; + spaceDelimitedKeywords = builder.mSpaceDelimitedKeywords; + intentAction = builder.mIntentAction; + intentTargetPackage = builder.mIntentTargetPackage; + intentTargetClass = builder.mIntentTargetClass; + enabled = builder.mEnabled; + key = builder.mKey; + userId = builder.mUserId; + payloadType = builder.mPayloadType; + payload = builder.mPayload != null ? ResultPayloadUtils.marshall(builder.mPayload) + : null; + } + + /** + * Returns the doc id for this row. + */ + public int getDocId() { + // Eventually we want all DocIds to be the data_reference key. For settings values, + // this will be preference keys, and for non-settings they should be unique. + return TextUtils.isEmpty(key) + ? Objects.hash(updatedTitle, className, screenTitle, intentTargetClass) + : key.hashCode(); + } + + public static class Builder { + private String mLocale; + private String mUpdatedTitle; + private String mNormalizedTitle; + private String mUpdatedSummaryOn; + private String mNormalizedSummaryOn; + private String mUpdatedSummaryOff; + private String mNormalizedSummaryOff; + private String mEntries; + private String mClassName; + private String mChildClassName; + private String mScreenTitle; + private int mIconResId; + private int mRank; + private String mSpaceDelimitedKeywords; + private String mIntentAction; + private String mIntentTargetPackage; + private String mIntentTargetClass; + private boolean mEnabled; + private String mKey; + private int mUserId; + @ResultPayload.PayloadType + private int mPayloadType; + private ResultPayload mPayload; + + public Builder setLocale(String locale) { + mLocale = locale; + return this; + } + + public Builder setUpdatedTitle(String updatedTitle) { + mUpdatedTitle = updatedTitle; + return this; + } + + public Builder setNormalizedTitle(String normalizedTitle) { + mNormalizedTitle = normalizedTitle; + return this; + } + + public Builder setUpdatedSummaryOn(String updatedSummaryOn) { + mUpdatedSummaryOn = updatedSummaryOn; + return this; + } + + public Builder setNormalizedSummaryOn(String normalizedSummaryOn) { + mNormalizedSummaryOn = normalizedSummaryOn; + return this; + } + + public Builder setUpdatedSummaryOff(String updatedSummaryOff) { + mUpdatedSummaryOff = updatedSummaryOff; + return this; + } + + public Builder setNormalizedSummaryOff(String normalizedSummaryOff) { + this.mNormalizedSummaryOff = normalizedSummaryOff; + return this; + } + + public Builder setEntries(String entries) { + mEntries = entries; + return this; + } + + public Builder setClassName(String className) { + mClassName = className; + return this; + } + + public Builder setChildClassName(String childClassName) { + mChildClassName = childClassName; + return this; + } + + public Builder setScreenTitle(String screenTitle) { + mScreenTitle = screenTitle; + return this; + } + + public Builder setIconResId(int iconResId) { + mIconResId = iconResId; + return this; + } + + public Builder setRank(int rank) { + mRank = rank; + return this; + } + + public Builder setSpaceDelimitedKeywords(String spaceDelimitedKeywords) { + mSpaceDelimitedKeywords = spaceDelimitedKeywords; + return this; + } + + public Builder setIntentAction(String intentAction) { + mIntentAction = intentAction; + return this; + } + + public Builder setIntentTargetPackage(String intentTargetPackage) { + mIntentTargetPackage = intentTargetPackage; + return this; + } + + public Builder setIntentTargetClass(String intentTargetClass) { + mIntentTargetClass = intentTargetClass; + return this; + } + + public Builder setEnabled(boolean enabled) { + mEnabled = enabled; + return this; + } + + public Builder setKey(String key) { + mKey = key; + return this; + } + + public Builder setUserId(int userId) { + mUserId = userId; + return this; + } + + public Builder setPayload(ResultPayload payload) { + mPayload = payload; + + if (mPayload != null) { + setPayloadType(mPayload.getType()); + } + return this; + } + + /** + * Payload type is added when a Payload is added to the Builder in {setPayload} + * + * @param payloadType PayloadType + * @return The Builder + */ + private Builder setPayloadType(@ResultPayload.PayloadType int payloadType) { + mPayloadType = payloadType; + return this; + } + + /** + * Adds intent to inline payloads, or creates an Intent Payload as a fallback if the + * payload is null. + */ + private void setIntent(Context context) { + if (mPayload != null) { + return; + } + final Intent intent = buildIntent(context); + mPayload = new ResultPayload(intent); + mPayloadType = ResultPayload.PayloadType.INTENT; + } + + /** + * Adds Intent payload to builder. + */ + private Intent buildIntent(Context context) { + final Intent intent; + + boolean isEmptyIntentAction = TextUtils.isEmpty(mIntentAction); + // No intent action is set, or the intent action is for a subsetting. + if (isEmptyIntentAction + || (!isEmptyIntentAction && TextUtils.equals(mIntentTargetPackage, + SearchIndexableResources.SUBSETTING_TARGET_PACKAGE))) { + // Action is null, we will launch it as a sub-setting + intent = DatabaseIndexingUtils.buildSubsettingIntent(context, mClassName, mKey, + mScreenTitle); + } else { + intent = new Intent(mIntentAction); + final String targetClass = mIntentTargetClass; + if (!TextUtils.isEmpty(mIntentTargetPackage) + && !TextUtils.isEmpty(targetClass)) { + final ComponentName component = new ComponentName(mIntentTargetPackage, + targetClass); + intent.setComponent(component); + } + intent.putExtra(SettingsActivity.EXTRA_FRAGMENT_ARG_KEY, mKey); + } + return intent; + } + + public IndexData build(Context context) { + setIntent(context); + return new IndexData(this); + } + } +} \ No newline at end of file diff --git a/src/com/android/settings/search/indexing/IndexDataConverter.java b/src/com/android/settings/search/indexing/IndexDataConverter.java new file mode 100644 index 00000000000..3c602f67098 --- /dev/null +++ b/src/com/android/settings/search/indexing/IndexDataConverter.java @@ -0,0 +1,510 @@ +/* + * 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.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; +import android.support.annotation.VisibleForTesting; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.util.Log; +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; +import com.android.settings.search.SearchIndexableResources; +import com.android.settings.search.XmlParserUtils; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +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}. + * + * TODO (b/33577327) This is just copied straight from DatabaseIndexingManager. But it's still ugly. + * TODO This is currently a long chain of method calls. It needs to be broken up. + * TODO but for the sake of easy code reviews, that will happen later. + */ +public class IndexDataConverter { + + private static final String LOG_TAG = "IndexDataConverter"; + + private static final String NODE_NAME_PREFERENCE_SCREEN = "PreferenceScreen"; + private static final String NODE_NAME_CHECK_BOX_PREFERENCE = "CheckBoxPreference"; + private static final String NODE_NAME_LIST_PREFERENCE = "ListPreference"; + + private Context mContext; + + private SQLiteDatabase mDb; + + public IndexDataConverter(Context context, SQLiteDatabase database) { + mContext = context; + mDb = database; + } + + /** + * 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, + Map> nonIndexableKeys) { + final long current = System.currentTimeMillis(); + + for (SearchIndexableData data : dataToUpdate) { + try { + indexOneSearchIndexableData(localeStr, data, nonIndexableKeys); + } catch (Exception e) { + Log.e(LOG_TAG, "Cannot index: " + (data != null ? data.className : data) + + " for locale: " + localeStr, e); + } + } + + final long now = System.currentTimeMillis(); + Log.d(LOG_TAG, "Indexing locale '" + localeStr + "' took " + + (now - current) + " millis"); + } + + @VisibleForTesting + void indexOneSearchIndexableData(String localeStr, SearchIndexableData data, + Map> nonIndexableKeys) { + if (data instanceof SearchIndexableResource) { + indexOneResource(localeStr, (SearchIndexableResource) data, nonIndexableKeys); + } else if (data instanceof SearchIndexableRaw) { + indexOneRaw(localeStr, (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)) { + return; + } + + Set packageKeys = nonIndexableKeysFromResource.get(raw.intentTargetPackage); + boolean enabled = raw.enabled; + + if (packageKeys != null && packageKeys.contains(raw.key)) { + enabled = false; + } + + IndexData.Builder builder = new IndexData.Builder(); + builder.setLocale(localeStr) + .setEntries(raw.entries) + .setClassName(raw.className) + .setScreenTitle(raw.screenTitle) + .setIconResId(raw.iconResId) + .setRank(raw.rank) + .setIntentAction(raw.intentAction) + .setIntentTargetPackage(raw.intentTargetPackage) + .setIntentTargetClass(raw.intentTargetClass) + .setEnabled(enabled) + .setKey(raw.key) + .setUserId(raw.userId); + + updateOneRowWithFilteredData(builder, raw.title, raw.summaryOn, raw.summaryOff, + raw.keywords); + } + + @VisibleForTesting + void indexOneResource(String localeStr, SearchIndexableResource sir, + Map> nonIndexableKeysFromResource) { + + if (sir == null) { + Log.e(LOG_TAG, "Cannot index a null resource!"); + return; + } + + final List nonIndexableKeys = new ArrayList<>(); + + if (sir.xmlResId > SearchIndexableResources.NO_DATA_RES_ID) { + Set resNonIndexableKeys = nonIndexableKeysFromResource.get(sir.packageName); + if (resNonIndexableKeys != null && resNonIndexableKeys.size() > 0) { + nonIndexableKeys.addAll(resNonIndexableKeys); + } + + indexFromResource(localeStr, sir, nonIndexableKeys); + } else { + if (TextUtils.isEmpty(sir.className)) { + Log.w(LOG_TAG, "Cannot index an empty Search Provider name!"); + return; + } + + final Class clazz = DatabaseIndexingUtils.getIndexableClass(sir.className); + if (clazz == null) { + Log.d(LOG_TAG, "SearchIndexableResource '" + sir.className + + "' should implement the " + Indexable.class.getName() + " interface!"); + return; + } + + // Will be non null only for a Local provider implementing a + // SEARCH_INDEX_DATA_PROVIDER field + final Indexable.SearchIndexProvider provider = + DatabaseIndexingUtils.getSearchIndexProvider(clazz); + if (provider != null) { + List providerNonIndexableKeys = provider.getNonIndexableKeys(sir.context); + if (providerNonIndexableKeys != null && providerNonIndexableKeys.size() > 0) { + nonIndexableKeys.addAll(providerNonIndexableKeys); + } + + indexFromProvider(localeStr, provider, sir, nonIndexableKeys); + } + } + } + + @VisibleForTesting + void indexFromResource(String localeStr, SearchIndexableResource sir, + List nonIndexableKeys) { + final Context context = sir.context; + XmlResourceParser parser = null; + try { + parser = context.getResources().getXml(sir.xmlResId); + + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && type != XmlPullParser.START_TAG) { + // Parse next until start tag is found + } + + String nodeName = parser.getName(); + if (!NODE_NAME_PREFERENCE_SCREEN.equals(nodeName)) { + throw new RuntimeException( + "XML document must start with tag; found" + + nodeName + " at " + parser.getPositionDescription()); + } + + final int outerDepth = parser.getDepth(); + final AttributeSet attrs = Xml.asAttributeSet(parser); + + final String screenTitle = XmlParserUtils.getDataTitle(context, attrs); + String key = XmlParserUtils.getDataKey(context, attrs); + + String title; + String headerTitle; + String summary; + String headerSummary; + String keywords; + String headerKeywords; + String childFragment; + @DrawableRes + int iconResId; + ResultPayload payload; + boolean enabled; + final String fragmentName = sir.className; + final int rank = sir.rank; + final String intentAction = sir.intentAction; + final String intentTargetPackage = sir.intentTargetPackage; + final String intentTargetClass = sir.intentTargetClass; + + Map controllerUriMap = null; + + if (fragmentName != null) { + controllerUriMap = DatabaseIndexingUtils + .getPreferenceControllerUriMap(fragmentName, context); + } + + // Insert rows for the main PreferenceScreen node. Rewrite the data for removing + // hyphens. + + headerTitle = XmlParserUtils.getDataTitle(context, attrs); + headerSummary = XmlParserUtils.getDataSummary(context, attrs); + headerKeywords = XmlParserUtils.getDataKeywords(context, attrs); + enabled = !nonIndexableKeys.contains(key); + + // TODO: Set payload type for header results + IndexData.Builder headerBuilder = new IndexData.Builder(); + headerBuilder.setLocale(localeStr) + .setEntries(null) + .setClassName(fragmentName) + .setScreenTitle(screenTitle) + .setRank(rank) + .setIntentAction(intentAction) + .setIntentTargetPackage(intentTargetPackage) + .setIntentTargetClass(intentTargetClass) + .setEnabled(enabled) + .setKey(key) + .setUserId(-1 /* default user id */); + + // Flag for XML headers which a child element's title. + boolean isHeaderUnique = true; + IndexData.Builder builder; + + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { + continue; + } + + nodeName = parser.getName(); + + title = XmlParserUtils.getDataTitle(context, attrs); + key = XmlParserUtils.getDataKey(context, attrs); + enabled = !nonIndexableKeys.contains(key); + keywords = XmlParserUtils.getDataKeywords(context, attrs); + iconResId = XmlParserUtils.getDataIcon(context, attrs); + + if (isHeaderUnique && TextUtils.equals(headerTitle, title)) { + isHeaderUnique = false; + } + + builder = new IndexData.Builder(); + builder.setLocale(localeStr) + .setClassName(fragmentName) + .setScreenTitle(screenTitle) + .setIconResId(iconResId) + .setRank(rank) + .setIntentAction(intentAction) + .setIntentTargetPackage(intentTargetPackage) + .setIntentTargetClass(intentTargetClass) + .setEnabled(enabled) + .setKey(key) + .setUserId(-1 /* default user id */); + + if (!nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) { + summary = XmlParserUtils.getDataSummary(context, attrs); + + String entries = null; + + if (nodeName.endsWith(NODE_NAME_LIST_PREFERENCE)) { + entries = XmlParserUtils.getDataEntries(context, attrs); + } + + // TODO (b/62254931) index primitives instead of payload + payload = DatabaseIndexingUtils.getPayloadFromUriMap(controllerUriMap, key); + childFragment = XmlParserUtils.getDataChildFragment(context, attrs); + + builder.setEntries(entries) + .setChildClassName(childFragment) + .setPayload(payload); + + // Insert rows for the child nodes of PreferenceScreen + updateOneRowWithFilteredData(builder, title, summary, + null /* summary off */, keywords); + } else { + String summaryOn = XmlParserUtils.getDataSummaryOn(context, attrs); + String summaryOff = XmlParserUtils.getDataSummaryOff(context, attrs); + + if (TextUtils.isEmpty(summaryOn) && TextUtils.isEmpty(summaryOff)) { + summaryOn = XmlParserUtils.getDataSummary(context, attrs); + } + + updateOneRowWithFilteredData(builder, title, summaryOn, summaryOff, + keywords); + } + } + + // The xml header's title does not match the title of one of the child settings. + if (isHeaderUnique) { + updateOneRowWithFilteredData(headerBuilder, headerTitle, headerSummary, + null /* summary off */, headerKeywords); + } + } catch (XmlPullParserException e) { + throw new RuntimeException("Error parsing PreferenceScreen", e); + } catch (IOException e) { + throw new RuntimeException("Error parsing PreferenceScreen", e); + } finally { + if (parser != null) parser.close(); + } + } + + @VisibleForTesting + void indexFromProvider(String localeStr, Indexable.SearchIndexProvider provider, + SearchIndexableResource sir, List nonIndexableKeys) { + + final String className = sir.className; + final String intentAction = sir.intentAction; + final String intentTargetPackage = sir.intentTargetPackage; + + if (provider == null) { + Log.w(LOG_TAG, "Cannot find provider: " + className); + return; + } + + final List rawList = provider.getRawDataToIndex(mContext, + true /* enabled */); + + if (rawList != null) { + + final int rawSize = rawList.size(); + for (int i = 0; i < rawSize; i++) { + SearchIndexableRaw raw = rawList.get(i); + + // Should be the same locale as the one we are processing + if (!raw.locale.toString().equalsIgnoreCase(localeStr)) { + continue; + } + boolean enabled = !nonIndexableKeys.contains(raw.key); + + IndexData.Builder builder = new IndexData.Builder(); + builder.setLocale(localeStr) + .setEntries(raw.entries) + .setClassName(className) + .setScreenTitle(raw.screenTitle) + .setIconResId(raw.iconResId) + .setIntentAction(raw.intentAction) + .setIntentTargetPackage(raw.intentTargetPackage) + .setIntentTargetClass(raw.intentTargetClass) + .setEnabled(enabled) + .setKey(raw.key) + .setUserId(raw.userId); + + updateOneRowWithFilteredData(builder, raw.title, raw.summaryOn, raw.summaryOff, + raw.keywords); + } + } + + final List resList = + provider.getXmlResourcesToIndex(mContext, true); + if (resList != null) { + final int resSize = resList.size(); + for (int i = 0; i < resSize; i++) { + SearchIndexableResource item = resList.get(i); + + // Should be the same locale as the one we are processing + if (!item.locale.toString().equalsIgnoreCase(localeStr)) { + continue; + } + + item.className = TextUtils.isEmpty(item.className) + ? className + : item.className; + item.intentAction = TextUtils.isEmpty(item.intentAction) + ? intentAction + : item.intentAction; + item.intentTargetPackage = TextUtils.isEmpty(item.intentTargetPackage) + ? intentTargetPackage + : item.intentTargetPackage; + + indexFromResource(localeStr, item, nonIndexableKeys); + } + } + } + + @VisibleForTesting + void updateOneRowWithFilteredData(IndexData.Builder builder, + String title, String summaryOn, String summaryOff, String keywords) { + + final String updatedTitle = DatabaseIndexingUtils.normalizeHyphen(title); + final String updatedSummaryOn = DatabaseIndexingUtils.normalizeHyphen(summaryOn); + final String updatedSummaryOff = DatabaseIndexingUtils.normalizeHyphen(summaryOff); + + final String normalizedTitle = DatabaseIndexingUtils.normalizeString(updatedTitle); + final String normalizedSummaryOn = DatabaseIndexingUtils.normalizeString(updatedSummaryOn); + final String normalizedSummaryOff = DatabaseIndexingUtils + .normalizeString(updatedSummaryOff); + + final String spaceDelimitedKeywords = DatabaseIndexingUtils.normalizeKeywords(keywords); + + builder.setUpdatedTitle(updatedTitle) + .setUpdatedSummaryOn(updatedSummaryOn) + .setUpdatedSummaryOff(updatedSummaryOff) + .setNormalizedTitle(normalizedTitle) + .setNormalizedSummaryOn(normalizedSummaryOn) + .setNormalizedSummaryOff(normalizedSummaryOff) + .setSpaceDelimitedKeywords(spaceDelimitedKeywords); + + updateOneRow(builder.build(mContext)); + } + + private void updateOneRow(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_RANK, row.rank); + 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_SUMMARY_OFF, row.updatedSummaryOff); + values.put(DATA_SUMMARY_OFF_NORMALIZED, row.normalizedSummaryOff); + 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); + } + } +} diff --git a/src/com/android/settings/search/indexing/IndexableDataCollector.java b/src/com/android/settings/search/indexing/PreIndexDataCollector.java similarity index 99% rename from src/com/android/settings/search/indexing/IndexableDataCollector.java rename to src/com/android/settings/search/indexing/PreIndexDataCollector.java index cd6b9bbd2c0..7186df8edda 100644 --- a/src/com/android/settings/search/indexing/IndexableDataCollector.java +++ b/src/com/android/settings/search/indexing/PreIndexDataCollector.java @@ -65,7 +65,7 @@ import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INT /** * Collects all data from {@link android.provider.SearchIndexablesProvider} to be indexed. */ -public class IndexableDataCollector { +public class PreIndexDataCollector { private static final String TAG = "IndexableDataCollector"; @@ -78,7 +78,7 @@ public class IndexableDataCollector { private PreIndexData mIndexData; - public IndexableDataCollector(Context context) { + public PreIndexDataCollector(Context context) { mContext = context; } diff --git a/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java b/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java index a15a449fdf8..47d52873607 100644 --- a/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java +++ b/tests/robotests/src/com/android/settings/search/CursorToSearchResultConverterTest.java @@ -243,7 +243,7 @@ public class CursorToSearchResultConverterTest { for (SearchResult result : results) { final InlineSwitchPayload newPayload = (InlineSwitchPayload) result.payload; final Intent rebuiltIntent = newPayload.getIntent(); - assertThat(newPayload.mSettingKey).isEqualTo(uri); + assertThat(newPayload.getKey()).isEqualTo(uri); assertThat(newPayload.getType()).isEqualTo(type); assertThat(newPayload.mSettingSource).isEqualTo(source); assertThat(newPayload.isStandard()).isTrue(); diff --git a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java b/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java index fff38c59322..db4aff7a13d 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java +++ b/tests/robotests/src/com/android/settings/search/DatabaseIndexingManagerTest.java @@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyList; -import static org.mockito.Matchers.anyMap; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.doNothing; @@ -42,10 +41,8 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Build; import android.provider.SearchIndexableData; -import android.provider.SearchIndexableResource; import android.util.ArrayMap; -import com.android.settings.R; import com.android.settings.TestConfig; import com.android.settings.search.indexing.PreIndexData; import com.android.settings.testutils.DatabaseTestUtils; @@ -65,7 +62,6 @@ 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; @@ -149,7 +145,7 @@ public class DatabaseIndexingManagerTest { Cursor dbCursor = mDb.query("prefs_index", null, null, null, null, null, null); List columnNames = new ArrayList<>(Arrays.asList(dbCursor.getColumnNames())); // Note that docid is not included. - List expColumnNames = new ArrayList<>(Arrays.asList(new String[]{ + List expColumnNames = Arrays.asList( "locale", "data_rank", "data_title", @@ -171,187 +167,13 @@ public class DatabaseIndexingManagerTest { "user_id", "payload_type", "payload" - })); + ); // Prevent database schema regressions assertThat(columnNames).containsAllIn(expColumnNames); } // Tests for the flow: IndexOneRaw -> UpdateOneRowWithFilteredData -> UpdateOneRow - @Test - public void testInsertRawColumn_rowInserted() { - SearchIndexableRaw raw = getFakeRaw(); - mManager.indexOneSearchIndexableData(mDb, localeStr, raw, - new HashMap<>()/* Non-indexable keys */); - Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); - assertThat(cursor.getCount()).isEqualTo(1); - } - - @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); - - mManager.indexOneSearchIndexableData(mDb, 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(); - mManager.indexOneSearchIndexableData(mDb, 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 Rank - assertThat(cursor.getInt(1)).isEqualTo(raw.rank); - // 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); - // Summary Off - assertThat(cursor.getString(6)).isEqualTo(updatedSummaryOff); - // Summary off normalized - assertThat(cursor.getString(7)).isEqualTo(normalizedSummaryOff); - // 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, - ResultPayload.CREATOR); - assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); - } - - @Test - public void testInsertRawColumn_mismatchedLocale_noRowInserted() { - SearchIndexableRaw raw = getFakeRaw("ca-fr"); - mManager.indexOneSearchIndexableData(mDb, localeStr, raw, null /* Non-indexable keys */); - Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); - assertThat(cursor.getCount()).isEqualTo(0); - } - - // Tests for the flow: IndexOneResource -> IndexFromResource -> - // UpdateOneRowWithFilteredData -> UpdateOneRow - - @Test - public void testNullResource_NothingInserted() { - mManager.indexOneSearchIndexableData(mDb, localeStr, null /* searchIndexableResource */, - new HashMap<>()); - Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); - assertThat(cursor.getCount()).isEqualTo(0); - } - - @Test - public void testAddResource_RowsInserted() { - SearchIndexableResource resource = getFakeResource(R.xml.display_settings); - mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); - Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); - assertThat(cursor.getCount()).isEqualTo(17); - } - - @Test - public void testAddResource_withNIKs_rowsInsertedDisabled() { - SearchIndexableResource resource = getFakeResource(R.xml.display_settings); - // Only add 2 of 16 items to be disabled. - String[] keys = {"brightness", "wallpaper"}; - Map> niks = getNonIndexableKeys(keys); - - mManager.indexOneSearchIndexableData(mDb, localeStr, resource, niks); - - 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); - } - - @Test - public void testAddResourceHeader_rowsMatch() { - SearchIndexableResource resource = getFakeResource(R.xml.application_settings); - mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); - - Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); - cursor.moveToPosition(1); - - // Locale - assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(rank); - // 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"); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).isEmpty(); - // 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); - } - @Test public void testAddResource_withChildFragment_shouldUpdateSiteMapDb() { // FIXME: This test was failing. (count = 6 at the end) @@ -377,376 +199,6 @@ public class DatabaseIndexingManagerTest { // assertThat(count).isEqualTo(5); } - @Test - public void testAddResource_customSetting_rowsMatch() { - SearchIndexableResource resource = getFakeResource(R.xml.swipe_to_notification_settings); - mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); - final String prefTitle = - mContext.getString(R.string.fingerprint_swipe_for_notifications_title); - final String prefSummary = - mContext.getString(R.string.fingerprint_swipe_for_notifications_summary); - final String keywords = mContext.getString(R.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 Rank - assertThat(cursor.getInt(1)).isEqualTo(rank); - // 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()); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).isEmpty(); - // 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(R.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); - } - - @Test - public void testAddResource_checkboxPreference_rowsMatch() { - SearchIndexableResource resource = getFakeResource(R.xml.application_settings); - mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); - - /* 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 Rank - assertThat(cursor.getInt(1)).isEqualTo(rank); - // 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"); - // Summary Off - assertThat(cursor.getString(6)).isEqualTo("Enable more settings options"); - // Summary Off - assertThat(cursor.getString(7)).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); - } - - @Test - public void testAddResource_listPreference_rowsMatch() { - SearchIndexableResource resource = getFakeResource(R.xml.application_settings); - mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); - - Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); - cursor.moveToPosition(3); - // Locale - assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(rank); - // 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"); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).isEmpty(); - // 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); - } - - @Test - public void testAddResource_iconAddedFromXml() { - SearchIndexableResource resource = getFakeResource(R.xml.connected_devices); - mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); - - Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); - cursor.moveToPosition(0); - - // Icon - assertThat(cursor.getInt(12)).isNotEqualTo(noIcon); - } - - // Tests for the flow: IndexOneResource -> IndexFromProvider -> IndexFromResource -> - // UpdateOneRowWithFilteredData -> UpdateOneRow - - @Test - public void testResourceProvider_rowInserted() { - SearchIndexableResource resource = getFakeResource(R.xml.swipe_to_notification_settings); - resource.xmlResId = 0; - resource.className = "com.android.settings.display.ScreenZoomSettings"; - - mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); - Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); - assertThat(cursor.getCount()).isEqualTo(1); - } - - @Test - public void testResourceProvider_rowMatches() { - SearchIndexableResource resource = getFakeResource(R.xml.swipe_to_notification_settings); - resource.xmlResId = 0; - resource.className = "com.android.settings.display.ScreenZoomSettings"; - - mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); - Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); - cursor.moveToPosition(0); - - // Locale - assertThat(cursor.getString(0)).isEqualTo(localeStr); - // Data Rank - assertThat(cursor.getInt(1)).isEqualTo(0); - // 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(); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).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_resourceRowInserted() { - SearchIndexableResource resource = getFakeResource(0); - resource.className = "com.android.settings.LegalSettings"; - - mManager.indexOneSearchIndexableData(mDb, 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"; - - mManager.indexOneSearchIndexableData(mDb, 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 Rank - assertThat(cursor.getInt(1)).isEqualTo(0); - // 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(); - // Summary Off - only on for checkbox preferences - assertThat(cursor.getString(6)).isEmpty(); - // Summary off normalized - only on for checkbox preferences - assertThat(cursor.getString(7)).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"; - - mManager.indexOneSearchIndexableData(mDb, 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(R.xml.swipe_to_notification_settings); - mManager.indexFromResource(mDb, 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; - - mManager.indexOneSearchIndexableData(mDb, 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); - } - // Test new public indexing flow @Test @@ -824,14 +276,6 @@ public class DatabaseIndexingManagerTest { assertThat(IndexDatabaseHelper.isBuildIndexed(mContext, Build.FINGERPRINT)).isTrue(); } - @Test - public void testFullUpdatedDatabase_noData_addDataToDatabaseNotCalled() { - PreIndexData emptydata = new PreIndexData(); - mManager.updateDatabase(emptydata, true /* isFullIndex */, localeStr); - verify(mManager, times(0)).addDataToDatabase(any(SQLiteDatabase.class), anyString(), - anyList(), anyMap()); - } - @Test public void testLocaleUpdated_afterIndexing_localeNotAdded() { PreIndexData emptydata = new PreIndexData(); @@ -1013,28 +457,6 @@ public class DatabaseIndexingManagerTest { return data; } - private SearchIndexableResource getFakeResource(int xml) { - SearchIndexableResource sir = new SearchIndexableResource(mContext); - sir.rank = rank; - sir.xmlResId = xml; - sir.className = className; - sir.packageName = packageName; - sir.iconResId = iconResId; - sir.intentAction = action; - sir.intentTargetPackage = targetPackage; - sir.intentTargetClass = targetClass; - sir.enabled = enabled; - 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 void insertSpecialCase(String specialCase, boolean enabled, String key) { ContentValues values = new ContentValues(); values.put(IndexDatabaseHelper.IndexColumns.DOCID, specialCase.hashCode()); diff --git a/tests/robotests/src/com/android/settings/search/InlineListPayloadTest.java b/tests/robotests/src/com/android/settings/search/InlineListPayloadTest.java index bee8d93c1be..fc1520500bd 100644 --- a/tests/robotests/src/com/android/settings/search/InlineListPayloadTest.java +++ b/tests/robotests/src/com/android/settings/search/InlineListPayloadTest.java @@ -40,7 +40,7 @@ public class InlineListPayloadTest { intent, true /* isAvailable */, 1 /* numOptions */, 1 /* default */); final Intent retainedIntent = payload.getIntent(); - assertThat(payload.mSettingKey).isEqualTo(uri); + assertThat(payload.getKey()).isEqualTo(uri); assertThat(payload.getType()).isEqualTo(type); assertThat(payload.mSettingSource).isEqualTo(source); assertThat(payload.getAvailability()).isEqualTo(ResultPayload.Availability.AVAILABLE); @@ -69,7 +69,7 @@ public class InlineListPayloadTest { .CREATOR.createFromParcel(parcel); final Intent builtIntent = payload.getIntent(); - assertThat(payload.mSettingKey).isEqualTo(uri); + assertThat(payload.getKey()).isEqualTo(uri); assertThat(payload.getType()).isEqualTo(type); assertThat(payload.mSettingSource).isEqualTo(source); assertThat(payload.getAvailability()).isEqualTo(ResultPayload.Availability.AVAILABLE); diff --git a/tests/robotests/src/com/android/settings/search/InlineSwitchPayloadTest.java b/tests/robotests/src/com/android/settings/search/InlineSwitchPayloadTest.java index b067ea689e3..64778a00b42 100644 --- a/tests/robotests/src/com/android/settings/search/InlineSwitchPayloadTest.java +++ b/tests/robotests/src/com/android/settings/search/InlineSwitchPayloadTest.java @@ -64,7 +64,7 @@ public class InlineSwitchPayloadTest { InlineSwitchPayload payload = new InlineSwitchPayload(uri, source, 1, intent, true, 1 /* default */); final Intent retainedIntent = payload.getIntent(); - assertThat(payload.mSettingKey).isEqualTo(uri); + assertThat(payload.getKey()).isEqualTo(uri); assertThat(payload.getType()).isEqualTo(type); assertThat(payload.mSettingSource).isEqualTo(source); assertThat(payload.isStandard()).isTrue(); @@ -93,7 +93,7 @@ public class InlineSwitchPayloadTest { InlineSwitchPayload payload = InlineSwitchPayload.CREATOR.createFromParcel(parcel); final Intent builtIntent = payload.getIntent(); - assertThat(payload.mSettingKey).isEqualTo(uri); + assertThat(payload.getKey()).isEqualTo(uri); assertThat(payload.getType()).isEqualTo(type); assertThat(payload.mSettingSource).isEqualTo(source); assertThat(payload.isStandard()).isTrue(); diff --git a/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java b/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java new file mode 100644 index 00000000000..89aa62ec2c6 --- /dev/null +++ b/tests/robotests/src/com/android/settings/search/indexing/IndexDataConverterTest.java @@ -0,0 +1,689 @@ +/* + * 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.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.provider.SearchIndexableResource; +import com.android.settings.TestConfig; +import com.android.settings.search.IndexDatabaseHelper; +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; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +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) +public class IndexDataConverterTest { + + private final String localeStr = "en_US"; + + private final int rank = 8; + 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 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)); + } + + @After + public void cleanUp() { + DatabaseTestUtils.clearDb(mContext); + } + + @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); + } + + @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); + + 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 Rank + assertThat(cursor.getInt(1)).isEqualTo(raw.rank); + // 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); + // Summary Off + assertThat(cursor.getString(6)).isEqualTo(updatedSummaryOff); + // Summary off normalized + assertThat(cursor.getString(7)).isEqualTo(normalizedSummaryOff); + // 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, + ResultPayload.CREATOR); + assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); + } + + @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); + } + + // Tests for the flow: IndexOneResource -> IndexFromResource -> + // UpdateOneRowWithFilteredData -> UpdateOneRow + + @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); + } + + @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); + } + + @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); + + mConverter.indexOneSearchIndexableData(localeStr, resource, niks); + + 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); + } + + @Test + public void testAddResourceHeader_rowsMatch() { + SearchIndexableResource resource = getFakeResource(xml.application_settings); + mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>()); + + Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); + cursor.moveToPosition(1); + + // Locale + assertThat(cursor.getString(0)).isEqualTo(localeStr); + // Data Rank + assertThat(cursor.getInt(1)).isEqualTo(rank); + // 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"); + // Summary Off - only on for checkbox preferences + assertThat(cursor.getString(6)).isEmpty(); + // Summary off normalized - only on for checkbox preferences + assertThat(cursor.getString(7)).isEmpty(); + // 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); + } + + @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 Rank + assertThat(cursor.getInt(1)).isEqualTo(rank); + // 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()); + // Summary Off - only on for checkbox preferences + assertThat(cursor.getString(6)).isEmpty(); + // Summary off normalized - only on for checkbox preferences + assertThat(cursor.getString(7)).isEmpty(); + // 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); + } + + @Test + public void testAddResource_checkboxPreference_rowsMatch() { + SearchIndexableResource resource = getFakeResource(xml.application_settings); + mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>()); + + /* 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 Rank + assertThat(cursor.getInt(1)).isEqualTo(rank); + // 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"); + // Summary Off + assertThat(cursor.getString(6)).isEqualTo("Enable more settings options"); + // Summary Off + assertThat(cursor.getString(7)).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); + } + + @Test + public void testAddResource_listPreference_rowsMatch() { + SearchIndexableResource resource = getFakeResource(xml.application_settings); + mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>()); + + Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); + cursor.moveToPosition(3); + // Locale + assertThat(cursor.getString(0)).isEqualTo(localeStr); + // Data Rank + assertThat(cursor.getInt(1)).isEqualTo(rank); + // 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"); + // Summary Off - only on for checkbox preferences + assertThat(cursor.getString(6)).isEmpty(); + // Summary off normalized - only on for checkbox preferences + assertThat(cursor.getString(7)).isEmpty(); + // 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); + } + + @Test + public void testAddResource_iconAddedFromXml() { + SearchIndexableResource resource = getFakeResource(xml.connected_devices); + mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>()); + + Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); + cursor.moveToPosition(0); + + // Icon + assertThat(cursor.getInt(12)).isNotEqualTo(noIcon); + } + + // 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"; + + mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>()); + Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); + assertThat(cursor.getCount()).isEqualTo(1); + } + + @Test + public void testResourceProvider_rowMatches() { + SearchIndexableResource resource = getFakeResource(xml.swipe_to_notification_settings); + resource.xmlResId = 0; + resource.className = "com.android.settings.display.ScreenZoomSettings"; + + mConverter.indexOneSearchIndexableData(localeStr, resource, new HashMap<>()); + Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); + cursor.moveToPosition(0); + + // Locale + assertThat(cursor.getString(0)).isEqualTo(localeStr); + // Data Rank + assertThat(cursor.getInt(1)).isEqualTo(0); + // 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(); + // Summary Off - only on for checkbox preferences + assertThat(cursor.getString(6)).isEmpty(); + // Summary off normalized - only on for checkbox preferences + assertThat(cursor.getString(7)).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_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 Rank + assertThat(cursor.getInt(1)).isEqualTo(0); + // 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(); + // Summary Off - only on for checkbox preferences + assertThat(cursor.getString(6)).isEmpty(); + // Summary off normalized - only on for checkbox preferences + assertThat(cursor.getString(7)).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 SearchIndexableRaw getFakeRaw() { + return getFakeRaw(localeStr); + } + + private SearchIndexableRaw getFakeRaw(String localeStr) { + SearchIndexableRaw data = new SearchIndexableRaw(mContext); + data.locale = new Locale(localeStr); + data.rank = rank; + data.title = title; + data.summaryOn = summaryOn; + data.summaryOff = summaryOff; + data.entries = entries; + data.keywords = keywords; + data.screenTitle = screenTitle; + data.className = className; + data.packageName = packageName; + data.iconResId = iconResId; + data.intentAction = action; + data.intentTargetPackage = targetPackage; + data.intentTargetClass = targetClass; + data.key = key; + data.userId = userId; + data.enabled = enabled; + return data; + } + + private SearchIndexableResource getFakeResource(int xml) { + SearchIndexableResource sir = new SearchIndexableResource(mContext); + sir.rank = rank; + sir.xmlResId = xml; + sir.className = className; + sir.packageName = packageName; + sir.iconResId = iconResId; + sir.intentAction = action; + sir.intentTargetPackage = targetPackage; + sir.intentTargetClass = targetClass; + sir.enabled = enabled; + 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; + } +} diff --git a/tests/robotests/src/com/android/settings/search/DatabaseRowTest.java b/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java similarity index 91% rename from tests/robotests/src/com/android/settings/search/DatabaseRowTest.java rename to tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java index a0d316363ad..40be4f2a98b 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseRowTest.java +++ b/tests/robotests/src/com/android/settings/search/indexing/IndexDataTest.java @@ -15,16 +15,17 @@ * */ -package com.android.settings.search; +package com.android.settings.search.indexing; import android.content.ComponentName; import android.content.Intent; import android.content.Context; +import com.android.settings.search.InlineSwitchPayload; +import com.android.settings.search.ResultPayload; +import com.android.settings.search.ResultPayloadUtils; import com.android.settings.testutils.SettingsRobolectricTestRunner; import com.android.settings.TestConfig; -import com.android.settings.search.DatabaseIndexingManager.DatabaseRow; -import com.android.settings.search.DatabaseIndexingManager.DatabaseRow.Builder; import org.junit.Before; import org.junit.Test; @@ -36,8 +37,8 @@ import static com.google.common.truth.Truth.assertThat; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class DatabaseRowTest { - private Builder mBuilder; +public class IndexDataTest { + private IndexData.Builder mBuilder; private static final String LOCALE = "locale"; private static final String UPDATED_TITLE = "updated title"; @@ -69,13 +70,13 @@ public class DatabaseRowTest { @Test public void testFullRowBuild_nonNull() { - DatabaseRow row = generateRow(); + IndexData row = generateRow(); assertThat(row).isNotNull(); } @Test public void testPrimitivesBuild_noDataLoss() { - DatabaseRow row = generateRow(); + IndexData row = generateRow(); assertThat(row.locale).isEqualTo(LOCALE); assertThat(row.updatedTitle).isEqualTo(UPDATED_TITLE); @@ -102,7 +103,7 @@ public class DatabaseRowTest { @Test public void testGenericIntent_addedToPayload() { - final DatabaseRow row = generateRow(); + final IndexData row = generateRow(); final ResultPayload payload = ResultPayloadUtils.unmarshall(row.payload, ResultPayload.CREATOR); final ComponentName name = payload.getIntent().getComponent(); @@ -116,12 +117,12 @@ public class DatabaseRowTest { final InlineSwitchPayload payload = new InlineSwitchPayload(URI, 0 /* mSettingSource */, 1 /* onValue */, null /* intent */, true /* isDeviceSupported */, 1 /* default */); mBuilder.setPayload(payload); - final DatabaseRow row = generateRow(); + final IndexData row = generateRow(); final InlineSwitchPayload unmarshalledPayload = ResultPayloadUtils .unmarshall(row.payload, InlineSwitchPayload.CREATOR); assertThat(row.payloadType).isEqualTo(ResultPayload.PayloadType.INLINE_SWITCH); - assertThat(unmarshalledPayload.mSettingKey).isEqualTo(URI); + assertThat(unmarshalledPayload.getKey()).isEqualTo(URI); } @Test @@ -135,7 +136,7 @@ public class DatabaseRowTest { final InlineSwitchPayload payload = new InlineSwitchPayload(URI, 0 /* mSettingSource */, 1 /* onValue */, intent, true /* isDeviceSupported */, 1 /* default */); mBuilder.setPayload(payload); - final DatabaseRow row = generateRow(); + final IndexData row = generateRow(); final InlineSwitchPayload unmarshalledPayload = ResultPayloadUtils .unmarshall(row.payload, InlineSwitchPayload.CREATOR); final ComponentName name = unmarshalledPayload.getIntent().getComponent(); @@ -145,12 +146,12 @@ public class DatabaseRowTest { } - private DatabaseRow generateRow() { + private IndexData generateRow() { return mBuilder.build(mContext); } - private DatabaseRow.Builder createBuilder() { - mBuilder = new DatabaseRow.Builder(); + private IndexData.Builder createBuilder() { + mBuilder = new IndexData.Builder(); mBuilder.setLocale(LOCALE) .setUpdatedTitle(UPDATED_TITLE) .setNormalizedTitle(NORMALIZED_TITLE) diff --git a/tests/robotests/src/com/android/settings/search/indexing/IndexableDataCollectorTest.java b/tests/robotests/src/com/android/settings/search/indexing/PreIndexDataCollectorTest.java similarity index 97% rename from tests/robotests/src/com/android/settings/search/indexing/IndexableDataCollectorTest.java rename to tests/robotests/src/com/android/settings/search/indexing/PreIndexDataCollectorTest.java index 0f1f34524d4..2bb03cba3fe 100644 --- a/tests/robotests/src/com/android/settings/search/indexing/IndexableDataCollectorTest.java +++ b/tests/robotests/src/com/android/settings/search/indexing/PreIndexDataCollectorTest.java @@ -47,7 +47,7 @@ import static org.mockito.Mockito.spy; @RunWith(SettingsRobolectricTestRunner.class) @Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) -public class IndexableDataCollectorTest { +public class PreIndexDataCollectorTest { private final String AUTHORITY_ONE = "authority"; private final String PACKAGE_ONE = "com.android.settings"; @@ -57,7 +57,7 @@ public class IndexableDataCollectorTest { Context mContext; - IndexableDataCollector mDataCollector; + PreIndexDataCollector mDataCollector; @Before public void setUp() { @@ -66,7 +66,7 @@ public class IndexableDataCollectorTest { doReturn(mResolver).when(mContext).getContentResolver(); //doReturn(mPackageManager).when(mContext).getPackageManager(); - mDataCollector = spy(new IndexableDataCollector(mContext)); + mDataCollector = spy(new PreIndexDataCollector(mContext)); } @Test