Merge "Update the Settings database to enable Payloads"
This commit is contained in:
committed by
Android (Google) Code Review
commit
08951ab12f
@@ -20,6 +20,7 @@ import android.support.v7.preference.Preference;
|
||||
import android.support.v7.preference.PreferenceScreen;
|
||||
|
||||
import com.android.settings.search.SearchIndexableRaw;
|
||||
import com.android.settings.search2.ResultPayload;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -104,4 +105,11 @@ public abstract class PreferenceController {
|
||||
screen.removePreference(pref);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link ResultPayload} corresponding to the search result type for the preference.
|
||||
*/
|
||||
public ResultPayload getResultPayload() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,7 @@ package com.android.settings.search;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@@ -46,4 +47,9 @@ public class BaseSearchIndexProvider implements Indexable.SearchIndexProvider {
|
||||
public List<String> getNonIndexableKeys(Context context) {
|
||||
return EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PreferenceController> getPreferenceControllers(Context context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -28,46 +28,48 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper {
|
||||
private static final String TAG = "IndexDatabaseHelper";
|
||||
|
||||
private static final String DATABASE_NAME = "search_index.db";
|
||||
private static final int DATABASE_VERSION = 115;
|
||||
private static final int DATABASE_VERSION = 116;
|
||||
|
||||
private static final String INDEX = "index";
|
||||
|
||||
public interface Tables {
|
||||
public static final String TABLE_PREFS_INDEX = "prefs_index";
|
||||
public static final String TABLE_META_INDEX = "meta_index";
|
||||
public static final String TABLE_SAVED_QUERIES = "saved_queries";
|
||||
String TABLE_PREFS_INDEX = "prefs_index";
|
||||
String TABLE_META_INDEX = "meta_index";
|
||||
String TABLE_SAVED_QUERIES = "saved_queries";
|
||||
}
|
||||
|
||||
public interface IndexColumns {
|
||||
public static final String DOCID = "docid";
|
||||
public static final String LOCALE = "locale";
|
||||
public static final String DATA_RANK = "data_rank";
|
||||
public static final String DATA_TITLE = "data_title";
|
||||
public static final String DATA_TITLE_NORMALIZED = "data_title_normalized";
|
||||
public static final String DATA_SUMMARY_ON = "data_summary_on";
|
||||
public static final String DATA_SUMMARY_ON_NORMALIZED = "data_summary_on_normalized";
|
||||
public static final String DATA_SUMMARY_OFF = "data_summary_off";
|
||||
public static final String DATA_SUMMARY_OFF_NORMALIZED = "data_summary_off_normalized";
|
||||
public static final String DATA_ENTRIES = "data_entries";
|
||||
public static final String DATA_KEYWORDS = "data_keywords";
|
||||
public static final String CLASS_NAME = "class_name";
|
||||
public static final String SCREEN_TITLE = "screen_title";
|
||||
public static final String INTENT_ACTION = "intent_action";
|
||||
public static final String INTENT_TARGET_PACKAGE = "intent_target_package";
|
||||
public static final String INTENT_TARGET_CLASS = "intent_target_class";
|
||||
public static final String ICON = "icon";
|
||||
public static final String ENABLED = "enabled";
|
||||
public static final String DATA_KEY_REF = "data_key_reference";
|
||||
public static final String USER_ID = "user_id";
|
||||
String DOCID = "docid";
|
||||
String LOCALE = "locale";
|
||||
String DATA_RANK = "data_rank";
|
||||
String DATA_TITLE = "data_title";
|
||||
String DATA_TITLE_NORMALIZED = "data_title_normalized";
|
||||
String DATA_SUMMARY_ON = "data_summary_on";
|
||||
String DATA_SUMMARY_ON_NORMALIZED = "data_summary_on_normalized";
|
||||
String DATA_SUMMARY_OFF = "data_summary_off";
|
||||
String DATA_SUMMARY_OFF_NORMALIZED = "data_summary_off_normalized";
|
||||
String DATA_ENTRIES = "data_entries";
|
||||
String DATA_KEYWORDS = "data_keywords";
|
||||
String CLASS_NAME = "class_name";
|
||||
String SCREEN_TITLE = "screen_title";
|
||||
String INTENT_ACTION = "intent_action";
|
||||
String INTENT_TARGET_PACKAGE = "intent_target_package";
|
||||
String INTENT_TARGET_CLASS = "intent_target_class";
|
||||
String ICON = "icon";
|
||||
String ENABLED = "enabled";
|
||||
String DATA_KEY_REF = "data_key_reference";
|
||||
String USER_ID = "user_id";
|
||||
String PAYLOAD_TYPE = "payload_type";
|
||||
String PAYLOAD = "payload";
|
||||
}
|
||||
|
||||
public interface MetaColumns {
|
||||
public static final String BUILD = "build";
|
||||
String BUILD = "build";
|
||||
}
|
||||
|
||||
public interface SavedQueriesColums {
|
||||
public static final String QUERY = "query";
|
||||
public static final String TIME_STAMP = "timestamp";
|
||||
String QUERY = "query";
|
||||
String TIME_STAMP = "timestamp";
|
||||
}
|
||||
|
||||
private static final String CREATE_INDEX_TABLE =
|
||||
@@ -110,6 +112,10 @@ public class IndexDatabaseHelper extends SQLiteOpenHelper {
|
||||
IndexColumns.DATA_KEY_REF +
|
||||
", " +
|
||||
IndexColumns.USER_ID +
|
||||
", " +
|
||||
IndexColumns.PAYLOAD_TYPE +
|
||||
", " +
|
||||
IndexColumns.PAYLOAD +
|
||||
");";
|
||||
|
||||
private static final String CREATE_META_TABLE =
|
||||
|
@@ -18,6 +18,7 @@ package com.android.settings.search;
|
||||
|
||||
import android.content.Context;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import com.android.settings.core.PreferenceController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -65,5 +66,11 @@ public interface Indexable {
|
||||
* @return a list of {@link SearchIndexableRaw} references. Can be null.
|
||||
*/
|
||||
List<String> getNonIndexableKeys(Context context);
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @return a list of {@link PreferenceController} for ResultPayload data during Indexing.
|
||||
*/
|
||||
List<PreferenceController> getPreferenceControllers(Context context);
|
||||
}
|
||||
}
|
||||
|
@@ -34,10 +34,12 @@ import android.provider.SearchIndexableData;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import android.provider.SearchIndexablesContract;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.search.IndexDatabaseHelper;
|
||||
import com.android.settings.search.Indexable;
|
||||
import com.android.settings.search.Ranking;
|
||||
@@ -86,56 +88,6 @@ import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RES
|
||||
public class DatabaseIndexingManager {
|
||||
private static final String LOG_TAG = "DatabaseIndexingManager";
|
||||
|
||||
// Those indices should match the indices of SELECT_COLUMNS !
|
||||
public static final int COLUMN_INDEX_RANK = 0;
|
||||
public static final int COLUMN_INDEX_TITLE = 1;
|
||||
public static final int COLUMN_INDEX_SUMMARY_ON = 2;
|
||||
public static final int COLUMN_INDEX_SUMMARY_OFF = 3;
|
||||
public static final int COLUMN_INDEX_ENTRIES = 4;
|
||||
public static final int COLUMN_INDEX_KEYWORDS = 5;
|
||||
public static final int COLUMN_INDEX_CLASS_NAME = 6;
|
||||
public static final int COLUMN_INDEX_SCREEN_TITLE = 7;
|
||||
public static final int COLUMN_INDEX_ICON = 8;
|
||||
public static final int COLUMN_INDEX_INTENT_ACTION = 9;
|
||||
public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_PACKAGE = 10;
|
||||
public static final int COLUMN_INDEX_INTENT_ACTION_TARGET_CLASS = 11;
|
||||
public static final int COLUMN_INDEX_ENABLED = 12;
|
||||
public static final int COLUMN_INDEX_KEY = 13;
|
||||
public static final int COLUMN_INDEX_USER_ID = 14;
|
||||
|
||||
// If you change the order of columns here, you SHOULD change the COLUMN_INDEX_XXX values
|
||||
private static final String[] SELECT_COLUMNS = new String[] {
|
||||
IndexDatabaseHelper.IndexColumns.DATA_RANK, // 0
|
||||
IndexDatabaseHelper.IndexColumns.DATA_TITLE, // 1
|
||||
IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, // 2
|
||||
IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, // 3
|
||||
IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, // 4
|
||||
IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, // 5
|
||||
IndexDatabaseHelper.IndexColumns.CLASS_NAME, // 6
|
||||
IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, // 7
|
||||
IndexDatabaseHelper.IndexColumns.ICON, // 8
|
||||
IndexDatabaseHelper.IndexColumns.INTENT_ACTION, // 9
|
||||
IndexDatabaseHelper.IndexColumns.INTENT_TARGET_PACKAGE, // 10
|
||||
IndexDatabaseHelper.IndexColumns.INTENT_TARGET_CLASS, // 11
|
||||
IndexDatabaseHelper.IndexColumns.ENABLED, // 12
|
||||
IndexDatabaseHelper.IndexColumns.DATA_KEY_REF // 13
|
||||
};
|
||||
|
||||
private static final String[] MATCH_COLUMNS_PRIMARY = {
|
||||
IndexDatabaseHelper.IndexColumns.DATA_TITLE,
|
||||
IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED,
|
||||
IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS
|
||||
};
|
||||
|
||||
private static final String[] MATCH_COLUMNS_SECONDARY = {
|
||||
IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON,
|
||||
IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED,
|
||||
IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF,
|
||||
IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED,
|
||||
IndexDatabaseHelper.IndexColumns.DATA_ENTRIES
|
||||
};
|
||||
|
||||
|
||||
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";
|
||||
@@ -514,7 +466,7 @@ public class DatabaseIndexingManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void indexOneSearchIndexableData(SQLiteDatabase database, String localeStr,
|
||||
public void indexOneSearchIndexableData(SQLiteDatabase database, String localeStr,
|
||||
SearchIndexableData data, Map<String, List<String>> nonIndexableKeys) {
|
||||
if (data instanceof SearchIndexableResource) {
|
||||
indexOneResource(database, localeStr, (SearchIndexableResource) data, nonIndexableKeys);
|
||||
@@ -530,22 +482,22 @@ public class DatabaseIndexingManager {
|
||||
return;
|
||||
}
|
||||
|
||||
updateOneRowWithFilteredData(database, localeStr,
|
||||
raw.title,
|
||||
raw.summaryOn,
|
||||
raw.summaryOff,
|
||||
raw.entries,
|
||||
raw.className,
|
||||
raw.screenTitle,
|
||||
raw.iconResId,
|
||||
raw.rank,
|
||||
raw.keywords,
|
||||
raw.intentAction,
|
||||
raw.intentTargetPackage,
|
||||
raw.intentTargetClass,
|
||||
raw.enabled,
|
||||
raw.key,
|
||||
raw.userId);
|
||||
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(raw.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,
|
||||
@@ -622,25 +574,45 @@ public class DatabaseIndexingManager {
|
||||
final int outerDepth = parser.getDepth();
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
|
||||
final String screenTitle = XMLParserUtil.getDataTitle(context, attrs);
|
||||
final String screenTitle = XmlParserUtils.getDataTitle(context, attrs);
|
||||
|
||||
String key = XMLParserUtil.getDataKey(context, attrs);
|
||||
String key = XmlParserUtils.getDataKey(context, attrs);
|
||||
|
||||
String title;
|
||||
String summary;
|
||||
String keywords;
|
||||
ResultPayload payload;
|
||||
|
||||
ArrayMap<String, PreferenceController> controllerUriMap = null;
|
||||
|
||||
if (fragmentName != null) {
|
||||
controllerUriMap = (ArrayMap) DatabaseIndexingUtils
|
||||
.getPreferenceControllerUriMap(fragmentName, context);
|
||||
}
|
||||
|
||||
// Insert rows for the main PreferenceScreen node. Rewrite the data for removing
|
||||
// hyphens.
|
||||
if (!nonIndexableKeys.contains(key)) {
|
||||
title = XMLParserUtil.getDataTitle(context, attrs);
|
||||
summary = XMLParserUtil.getDataSummary(context, attrs);
|
||||
keywords = XMLParserUtil.getDataKeywords(context, attrs);
|
||||
title = XmlParserUtils.getDataTitle(context, attrs);
|
||||
summary = XmlParserUtils.getDataSummary(context, attrs);
|
||||
keywords = XmlParserUtils.getDataKeywords(context, attrs);
|
||||
|
||||
updateOneRowWithFilteredData(database, localeStr, title, summary, null, null,
|
||||
fragmentName, screenTitle, iconResId, rank,
|
||||
keywords, intentAction, intentTargetPackage, intentTargetClass, true,
|
||||
key, -1 /* default user id */);
|
||||
DatabaseRow.Builder builder = new DatabaseRow.Builder();
|
||||
builder.setLocale(localeStr)
|
||||
.setEntries(null)
|
||||
.setClassName(fragmentName)
|
||||
.setScreenTitle(screenTitle)
|
||||
.setIconResId(iconResId)
|
||||
.setRank(rank)
|
||||
.setIntentAction(intentAction)
|
||||
.setIntentTargetPackage(intentTargetPackage)
|
||||
.setIntentTargetClass(intentTargetClass)
|
||||
.setEnabled(true)
|
||||
.setKey(key)
|
||||
.setUserId(-1 /* default user id */);
|
||||
|
||||
updateOneRowWithFilteredData(database, builder, title, summary,
|
||||
null /* summary off */, keywords);
|
||||
}
|
||||
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
@@ -651,43 +623,56 @@ public class DatabaseIndexingManager {
|
||||
|
||||
nodeName = parser.getName();
|
||||
|
||||
key = XMLParserUtil.getDataKey(context, attrs);
|
||||
key = XmlParserUtils.getDataKey(context, attrs);
|
||||
if (nonIndexableKeys.contains(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
title = XMLParserUtil.getDataTitle(context, attrs);
|
||||
keywords = XMLParserUtil.getDataKeywords(context, attrs);
|
||||
title = XmlParserUtils.getDataTitle(context, attrs);
|
||||
keywords = XmlParserUtils.getDataKeywords(context, attrs);
|
||||
|
||||
DatabaseRow.Builder builder = new DatabaseRow.Builder();
|
||||
builder.setLocale(localeStr)
|
||||
.setClassName(fragmentName)
|
||||
.setScreenTitle(screenTitle)
|
||||
.setIconResId(iconResId)
|
||||
.setRank(rank)
|
||||
.setIntentAction(intentAction)
|
||||
.setIntentTargetPackage(intentTargetPackage)
|
||||
.setIntentTargetClass(intentTargetClass)
|
||||
.setEnabled(true)
|
||||
.setKey(key)
|
||||
.setUserId(-1 /* default user id */);
|
||||
|
||||
if (!nodeName.equals(NODE_NAME_CHECK_BOX_PREFERENCE)) {
|
||||
summary = XMLParserUtil.getDataSummary(context, attrs);
|
||||
summary = XmlParserUtils.getDataSummary(context, attrs);
|
||||
|
||||
String entries = null;
|
||||
|
||||
if (nodeName.endsWith(NODE_NAME_LIST_PREFERENCE)) {
|
||||
entries = XMLParserUtil.getDataEntries(context, attrs);
|
||||
entries = XmlParserUtils.getDataEntries(context, attrs);
|
||||
}
|
||||
|
||||
payload = DatabaseIndexingUtils.getPayloadFromUriMap(controllerUriMap, key);
|
||||
|
||||
builder.setEntries(entries)
|
||||
.setPayload(payload);
|
||||
|
||||
// Insert rows for the child nodes of PreferenceScreen
|
||||
updateOneRowWithFilteredData(database, localeStr, title, summary, null, entries,
|
||||
fragmentName, screenTitle, iconResId, rank,
|
||||
keywords, intentAction, intentTargetPackage, intentTargetClass,
|
||||
true, key, -1 /* default user id */);
|
||||
updateOneRowWithFilteredData(database, builder, title, summary,
|
||||
null /* summary off */, keywords);
|
||||
} else {
|
||||
String summaryOn = XMLParserUtil.getDataSummaryOn(context, attrs);
|
||||
String summaryOff = XMLParserUtil.getDataSummaryOff(context, attrs);
|
||||
String summaryOn = XmlParserUtils.getDataSummaryOn(context, attrs);
|
||||
String summaryOff = XmlParserUtils.getDataSummaryOff(context, attrs);
|
||||
|
||||
if (TextUtils.isEmpty(summaryOn) && TextUtils.isEmpty(summaryOff)) {
|
||||
summaryOn = XMLParserUtil.getDataSummary(context, attrs);
|
||||
summaryOn = XmlParserUtils.getDataSummary(context, attrs);
|
||||
}
|
||||
|
||||
updateOneRowWithFilteredData(database, localeStr, title, summaryOn, summaryOff,
|
||||
null, fragmentName, screenTitle, iconResId, rank,
|
||||
keywords, intentAction, intentTargetPackage, intentTargetClass,
|
||||
true, key, -1 /* default user id */);
|
||||
updateOneRowWithFilteredData(database, builder, title, summaryOn, summaryOff,
|
||||
keywords);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (XmlPullParserException e) {
|
||||
throw new RuntimeException("Error parsing PreferenceScreen", e);
|
||||
} catch (IOException e) {
|
||||
@@ -709,6 +694,7 @@ public class DatabaseIndexingManager {
|
||||
final List<SearchIndexableRaw> rawList = provider.getRawDataToIndex(context, enabled);
|
||||
|
||||
if (rawList != null) {
|
||||
|
||||
final int rawSize = rawList.size();
|
||||
for (int i = 0; i < rawSize; i++) {
|
||||
SearchIndexableRaw raw = rawList.get(i);
|
||||
@@ -722,22 +708,22 @@ public class DatabaseIndexingManager {
|
||||
continue;
|
||||
}
|
||||
|
||||
updateOneRowWithFilteredData(database, localeStr,
|
||||
raw.title,
|
||||
raw.summaryOn,
|
||||
raw.summaryOff,
|
||||
raw.entries,
|
||||
className,
|
||||
raw.screenTitle,
|
||||
iconResId,
|
||||
rank,
|
||||
raw.keywords,
|
||||
raw.intentAction,
|
||||
raw.intentTargetPackage,
|
||||
raw.intentTargetClass,
|
||||
raw.enabled,
|
||||
raw.key,
|
||||
raw.userId);
|
||||
DatabaseRow.Builder builder = new DatabaseRow.Builder();
|
||||
builder.setLocale(localeStr)
|
||||
.setEntries(raw.entries)
|
||||
.setClassName(className)
|
||||
.setScreenTitle(raw.screenTitle)
|
||||
.setIconResId(iconResId)
|
||||
.setRank(rank)
|
||||
.setIntentAction(raw.intentAction)
|
||||
.setIntentTargetPackage(raw.intentTargetPackage)
|
||||
.setIntentTargetClass(raw.intentTargetClass)
|
||||
.setEnabled(raw.enabled)
|
||||
.setKey(raw.key)
|
||||
.setUserId(raw.userId);
|
||||
|
||||
updateOneRowWithFilteredData(database, builder, raw.title, raw.summaryOn,
|
||||
raw.summaryOff, raw.keywords);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -766,70 +752,68 @@ public class DatabaseIndexingManager {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateOneRowWithFilteredData(SQLiteDatabase database, String locale,
|
||||
String title, String summaryOn, String summaryOff, String entries,
|
||||
String className,
|
||||
String screenTitle, int iconResId, int rank, String keywords,
|
||||
String intentAction, String intentTargetPackage, String intentTargetClass,
|
||||
boolean enabled, String key, int userId) {
|
||||
private void updateOneRowWithFilteredData(SQLiteDatabase database, DatabaseRow.Builder builder,
|
||||
String title, String summaryOn, String summaryOff,String keywords) {
|
||||
|
||||
final String updatedTitle = XMLParserUtil.normalizeHyphen(title);
|
||||
final String updatedSummaryOn = XMLParserUtil.normalizeHyphen(summaryOn);
|
||||
final String updatedSummaryOff = XMLParserUtil.normalizeHyphen(summaryOff);
|
||||
final String updatedTitle = DatabaseIndexingUtils.normalizeHyphen(title);
|
||||
final String updatedSummaryOn = DatabaseIndexingUtils.normalizeHyphen(summaryOn);
|
||||
final String updatedSummaryOff = DatabaseIndexingUtils.normalizeHyphen(summaryOff);
|
||||
|
||||
final String normalizedTitle = XMLParserUtil.normalizeString(updatedTitle);
|
||||
final String normalizedSummaryOn = XMLParserUtil.normalizeString(updatedSummaryOn);
|
||||
final String normalizedSummaryOff = XMLParserUtil.normalizeString(updatedSummaryOff);
|
||||
final String normalizedTitle = DatabaseIndexingUtils.normalizeString(updatedTitle);
|
||||
final String normalizedSummaryOn = DatabaseIndexingUtils.normalizeString(updatedSummaryOn);
|
||||
final String normalizedSummaryOff = DatabaseIndexingUtils
|
||||
.normalizeString(updatedSummaryOff);
|
||||
|
||||
final String spaceDelimitedKeywords = XMLParserUtil.normalizeKeywords(keywords);
|
||||
final String spaceDelimitedKeywords = DatabaseIndexingUtils.normalizeKeywords(keywords);
|
||||
|
||||
updateOneRow(database, locale,
|
||||
updatedTitle, normalizedTitle, updatedSummaryOn, normalizedSummaryOn,
|
||||
updatedSummaryOff, normalizedSummaryOff, entries, className, screenTitle, iconResId,
|
||||
rank, spaceDelimitedKeywords, intentAction, intentTargetPackage, intentTargetClass,
|
||||
enabled, key, userId);
|
||||
builder.setUpdatedTitle(updatedTitle)
|
||||
.setUpdatedSummaryOn(updatedSummaryOn)
|
||||
.setUpdatedSummaryOff(updatedSummaryOff)
|
||||
.setNormalizedTitle(normalizedTitle)
|
||||
.setNormalizedSummaryOn(normalizedSummaryOn)
|
||||
.setNormalizedSummaryOff(normalizedSummaryOff)
|
||||
.setSpaceDelimitedKeywords(spaceDelimitedKeywords);
|
||||
|
||||
updateOneRow(database, builder.build());
|
||||
}
|
||||
|
||||
private void updateOneRow(SQLiteDatabase database, String locale, String updatedTitle,
|
||||
String normalizedTitle, String updatedSummaryOn, String normalizedSummaryOn,
|
||||
String updatedSummaryOff, String normalizedSummaryOff, String entries, String className,
|
||||
String screenTitle, int iconResId, int rank, String spaceDelimitedKeywords,
|
||||
String intentAction, String intentTargetPackage, String intentTargetClass,
|
||||
boolean enabled, String key, int userId) {
|
||||
private void updateOneRow(SQLiteDatabase database, DatabaseRow row) {
|
||||
|
||||
if (TextUtils.isEmpty(updatedTitle)) {
|
||||
if (TextUtils.isEmpty(row.updatedTitle)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The DocID should contains more than the title string itself (you may have two settings
|
||||
// with the same title). So we need to use a combination of the title and the screenTitle.
|
||||
StringBuilder sb = new StringBuilder(updatedTitle);
|
||||
sb.append(screenTitle);
|
||||
StringBuilder sb = new StringBuilder(row.updatedTitle);
|
||||
sb.append(row.screenTitle);
|
||||
int docId = sb.toString().hashCode();
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DOCID, docId);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.LOCALE, locale);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_RANK, rank);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, updatedTitle);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, normalizedTitle);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, updatedSummaryOn);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.LOCALE, row.locale);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_RANK, row.rank);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, row.updatedTitle);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, row.normalizedTitle);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, row.updatedSummaryOn);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED,
|
||||
normalizedSummaryOn);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, updatedSummaryOff);
|
||||
row.normalizedSummaryOn);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, row.updatedSummaryOff);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED,
|
||||
normalizedSummaryOff);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, entries);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, spaceDelimitedKeywords);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, className);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, screenTitle);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.INTENT_ACTION, intentAction);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.INTENT_TARGET_PACKAGE, intentTargetPackage);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.INTENT_TARGET_CLASS, intentTargetClass);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.ICON, iconResId);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.ENABLED, enabled);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEY_REF, key);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.USER_ID, userId);
|
||||
row.normalizedSummaryOff);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, row.entries);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, row.spaceDelimitedKeywords);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, row.className);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, row.screenTitle);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.INTENT_ACTION, row.intentAction);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.INTENT_TARGET_PACKAGE, row.intentTargetPackage);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.INTENT_TARGET_CLASS, row.intentTargetClass);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.ICON, row.iconResId);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.ENABLED, row.enabled);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.DATA_KEY_REF, row.key);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.USER_ID, row.userId);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.PAYLOAD_TYPE, row.payloadType);
|
||||
values.put(IndexDatabaseHelper.IndexColumns.PAYLOAD, row.payload);
|
||||
|
||||
database.replaceOrThrow(IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX, null, values);
|
||||
}
|
||||
@@ -960,4 +944,195 @@ public class DatabaseIndexingManager {
|
||||
whereArgs);
|
||||
}
|
||||
}
|
||||
|
||||
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 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;
|
||||
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;
|
||||
}
|
||||
|
||||
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 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 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;
|
||||
}
|
||||
|
||||
public DatabaseRow build() {
|
||||
return new DatabaseRow(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -23,12 +23,19 @@ import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.settings.core.PreferenceController;
|
||||
import com.android.settings.search.Indexable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.text.Normalizer;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Utility class for {@like DatabaseIndexingManager} to handle the mapping between Payloads
|
||||
@@ -36,17 +43,82 @@ import java.lang.reflect.Field;
|
||||
*/
|
||||
public class DatabaseIndexingUtils {
|
||||
|
||||
private static final String LOG_TAG = "IndexingUtil";
|
||||
private static final String TAG = "IndexingUtil";
|
||||
|
||||
private static final String FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER =
|
||||
"SEARCH_INDEX_DATA_PROVIDER";
|
||||
|
||||
private static final String NON_BREAKING_HYPHEN = "\u2011";
|
||||
private static final String EMPTY = "";
|
||||
private static final String LIST_DELIMITERS = "[,]\\s*";
|
||||
private static final String HYPHEN = "-";
|
||||
private static final String SPACE = " ";
|
||||
|
||||
private static final Pattern REMOVE_DIACRITICALS_PATTERN
|
||||
= Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
|
||||
|
||||
/**
|
||||
* @param className which wil provide the map between from {@link Uri}s to
|
||||
* {@link PreferenceController}
|
||||
* @param context
|
||||
* @return A map between {@link Uri}s and {@link PreferenceController}s to get the payload
|
||||
* types for Settings.
|
||||
*/
|
||||
public static Map<String, PreferenceController> getPreferenceControllerUriMap(
|
||||
String className, Context context) {
|
||||
final Class<?> clazz = getIndexableClass(className);
|
||||
|
||||
if (clazz == null) {
|
||||
Log.d(TAG, "SearchIndexableResource '" + className +
|
||||
"' should implement the " + Indexable.class.getName() + " interface!");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Will be non null only for a Local provider implementing a
|
||||
// SEARCH_INDEX_DATA_PROVIDER field
|
||||
final Indexable.SearchIndexProvider provider = getSearchIndexProvider(clazz);
|
||||
List<PreferenceController> controllers =
|
||||
provider.getPreferenceControllers(context);
|
||||
|
||||
if (controllers == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ArrayMap<String, PreferenceController> map = new ArrayMap<>();
|
||||
|
||||
for (PreferenceController controller : controllers) {
|
||||
map.put(controller.getPreferenceKey(), controller);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uriMap Map between the {@link PreferenceController} keys and the controllers themselves.
|
||||
* @param key The look up key
|
||||
* @return The Payload from the {@link PreferenceController} specified by the key, if it exists.
|
||||
* Otherwise null.
|
||||
*/
|
||||
public static ResultPayload getPayloadFromUriMap(ArrayMap<String, PreferenceController> uriMap,
|
||||
String key) {
|
||||
if (uriMap == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
PreferenceController controller = uriMap.get(key);
|
||||
if (controller == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return controller.getResultPayload();
|
||||
}
|
||||
|
||||
public static Class<?> getIndexableClass(String className) {
|
||||
final Class<?> clazz;
|
||||
try {
|
||||
clazz = Class.forName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
Log.d(LOG_TAG, "Cannot find class: " + className);
|
||||
Log.d(TAG, "Cannot find class: " + className);
|
||||
return null;
|
||||
}
|
||||
return isIndexableClass(clazz) ? clazz : null;
|
||||
@@ -61,15 +133,15 @@ public class DatabaseIndexingUtils {
|
||||
final Field f = clazz.getField(FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER);
|
||||
return (Indexable.SearchIndexProvider) f.get(null);
|
||||
} catch (NoSuchFieldException e) {
|
||||
Log.d(LOG_TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'");
|
||||
Log.d(TAG, "Cannot find field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'");
|
||||
} catch (SecurityException se) {
|
||||
Log.d(LOG_TAG,
|
||||
Log.d(TAG,
|
||||
"Security exception for field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'");
|
||||
} catch (IllegalAccessException e) {
|
||||
Log.d(LOG_TAG,
|
||||
Log.d(TAG,
|
||||
"Illegal access to field '" + FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'");
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.d(LOG_TAG,
|
||||
Log.d(TAG,
|
||||
"Illegal argument when accessing field '" +
|
||||
FIELD_NAME_SEARCH_INDEX_DATA_PROVIDER + "'");
|
||||
}
|
||||
@@ -115,4 +187,19 @@ public class DatabaseIndexingUtils {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static String normalizeHyphen(String input) {
|
||||
return (input != null) ? input.replaceAll(NON_BREAKING_HYPHEN, HYPHEN) : EMPTY;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public static String normalizeKeywords(String input) {
|
||||
return (input != null) ? input.replaceAll(LIST_DELIMITERS, SPACE) : EMPTY;
|
||||
}
|
||||
}
|
||||
|
@@ -18,7 +18,6 @@ package com.android.settings.search2;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Parcel;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
/**
|
||||
* Encapsulates the standard intent based results as seen in first party apps and Settings results.
|
||||
|
56
src/com/android/settings/search2/ResultPayloadUtils.java
Normal file
56
src/com/android/settings/search2/ResultPayloadUtils.java
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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.search2;
|
||||
|
||||
import android.os.BadParcelableException;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.StreamCorruptedException;
|
||||
|
||||
/**
|
||||
* Utility class to Marshall and Unmarshall the payloads stored in the SQLite Database
|
||||
*/
|
||||
public class ResultPayloadUtils {
|
||||
|
||||
private static final String TAG = "PayloadUtil";
|
||||
|
||||
public static byte[] marshall(ResultPayload payload) {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
payload.writeToParcel(parcel, 0);
|
||||
byte[] bytes = parcel.marshall();
|
||||
parcel.recycle();
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static <T> T unmarshall(byte[] bytes, Parcelable.Creator<T> creator) {
|
||||
T result;
|
||||
Parcel parcel = unmarshall(bytes);
|
||||
result = creator.createFromParcel(parcel);
|
||||
parcel.recycle();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Parcel unmarshall(byte[] bytes) {
|
||||
Parcel parcel = Parcel.obtain();
|
||||
parcel.unmarshall(bytes, 0, bytes.length);
|
||||
parcel.setDataPosition(0);
|
||||
return parcel;
|
||||
}
|
||||
}
|
@@ -30,19 +30,10 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* Utility class to parse elements of XML preferences
|
||||
*/
|
||||
public class XMLParserUtil {
|
||||
|
||||
private static final String NON_BREAKING_HYPHEN = "\u2011";
|
||||
private static final String EMPTY = "";
|
||||
private static final String LIST_DELIMITERS = "[,]\\s*";
|
||||
private static final String HYPHEN = "-";
|
||||
private static final String SPACE = " ";
|
||||
public class XmlParserUtils {
|
||||
|
||||
private static final String ENTRIES_SEPARATOR = "|";
|
||||
|
||||
private static final Pattern REMOVE_DIACRITICALS_PATTERN
|
||||
= Pattern.compile("\\p{InCombiningDiacriticalMarks}+");
|
||||
|
||||
public static String getDataKey(Context context, AttributeSet attrs) {
|
||||
return getData(context, attrs,
|
||||
com.android.internal.R.styleable.Preference,
|
||||
@@ -83,7 +74,7 @@ public class XMLParserUtil {
|
||||
return getData(context, attrs, R.styleable.Preference, R.styleable.Preference_keywords);
|
||||
}
|
||||
|
||||
public static String getData(Context context, AttributeSet set, int[] attrs, int resId) {
|
||||
private static String getData(Context context, AttributeSet set, int[] attrs, int resId) {
|
||||
final TypedArray sa = context.obtainStyledAttributes(set, attrs);
|
||||
final TypedValue tv = sa.peekValue(resId);
|
||||
|
||||
@@ -98,7 +89,7 @@ public class XMLParserUtil {
|
||||
return (data != null) ? data.toString() : null;
|
||||
}
|
||||
|
||||
public static String getDataEntries(Context context, AttributeSet set, int[] attrs, int resId) {
|
||||
private static String getDataEntries(Context context, AttributeSet set, int[] attrs, int resId) {
|
||||
final TypedArray sa = context.obtainStyledAttributes(set, attrs);
|
||||
final TypedValue tv = sa.peekValue(resId);
|
||||
|
||||
@@ -119,19 +110,4 @@ public class XMLParserUtil {
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
public static String normalizeHyphen(String input) {
|
||||
return (input != null) ? input.replaceAll(NON_BREAKING_HYPHEN, HYPHEN) : EMPTY;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public static String normalizeKeywords(String input) {
|
||||
return (input != null) ? input.replaceAll(LIST_DELIMITERS, SPACE) : EMPTY;
|
||||
}
|
||||
}
|
@@ -0,0 +1,616 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.provider.SearchIndexableResource;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.search2.DatabaseIndexingManager;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
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 DatabaseIndexingManagerTest {
|
||||
private final String localeStr = "en_US";
|
||||
|
||||
private final int rank = 42;
|
||||
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 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 DatabaseIndexingManager mManager;
|
||||
private SQLiteDatabase mDb;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = ShadowApplication.getInstance().getApplicationContext();
|
||||
mManager = spy(new DatabaseIndexingManager(mContext, mContext.getPackageName()));
|
||||
mDb = IndexDatabaseHelper.getInstance(mContext).getWritableDatabase();
|
||||
}
|
||||
|
||||
@After
|
||||
public void cleanUp() {
|
||||
Field instance;
|
||||
Class clazz = IndexDatabaseHelper.class;
|
||||
try {
|
||||
instance = clazz.getDeclaredField("sSingleton");
|
||||
instance.setAccessible(true);
|
||||
instance.set(null, null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDatabaseSchema() {
|
||||
Cursor dbCursor = mDb.query("prefs_index", null, null, null, null, null, null);
|
||||
List<String> columnNames = new ArrayList<>(Arrays.asList(dbCursor.getColumnNames()));
|
||||
// Note that docid is not included.
|
||||
List<String> expColumnNames = new ArrayList<>(Arrays.asList(new String[ ]{
|
||||
"locale",
|
||||
"data_rank",
|
||||
"data_title",
|
||||
"data_title_normalized",
|
||||
"data_summary_on",
|
||||
"data_summary_on_normalized",
|
||||
"data_summary_off",
|
||||
"data_summary_off_normalized",
|
||||
"data_entries",
|
||||
"data_keywords",
|
||||
"class_name",
|
||||
"screen_title",
|
||||
"intent_action",
|
||||
"intent_target_package",
|
||||
"intent_target_class",
|
||||
"icon",
|
||||
"enabled",
|
||||
"data_key_reference",
|
||||
"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, null /* Non-indexable keys */);
|
||||
Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
|
||||
assertThat(cursor.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertRawColumn_RowMatches() {
|
||||
SearchIndexableRaw raw = getFakeRaw();
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, raw, null /* 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
|
||||
assertThat(cursor.getBlob(20)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertRawColumnMismatchedLocale_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<String, List<String>>());
|
||||
Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
|
||||
assertThat(cursor.getCount()).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddResource_RowsInserted() {
|
||||
SearchIndexableResource resource = getFakeResource(R.xml.gesture_settings);
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
||||
new HashMap<String, List<String>>());
|
||||
Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
|
||||
assertThat(cursor.getCount()).isEqualTo(6);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddResourceHeader_RowsMatch() {
|
||||
SearchIndexableResource resource = getFakeResource(R.xml.application_settings);
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
||||
new HashMap<String, List<String>>());
|
||||
|
||||
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("Apps");
|
||||
// Normalized Title
|
||||
assertThat(cursor.getString(3)).isEqualTo("apps");
|
||||
// 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("Apps");
|
||||
// Class Name
|
||||
assertThat(cursor.getString(11)).isEqualTo(className);
|
||||
// Icon
|
||||
assertThat(cursor.getInt(12)).isEqualTo(iconResId);
|
||||
// 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
|
||||
assertThat(cursor.getBlob(20)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddResourceCustomSetting_RowsMatch() {
|
||||
SearchIndexableResource resource = getFakeResource(R.xml.gesture_settings);
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
||||
new HashMap<String, List<String>>());
|
||||
|
||||
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(rank);
|
||||
// Data Title
|
||||
assertThat(cursor.getString(2)).isEqualTo("Swipe for notifications");
|
||||
// Normalized Title
|
||||
assertThat(cursor.getString(3)).isEqualTo("swipe for notifications");
|
||||
// Summary On
|
||||
assertThat(cursor.getString(4)).isEqualTo("To check your notifications, " +
|
||||
"swipe down on the fingerprint sensor on the back of your phone.");
|
||||
// Summary On Normalized
|
||||
assertThat(cursor.getString(5)).isEqualTo("to check your notifications, " +
|
||||
"swipe down on the fingerprint sensor on the back of your phone.");
|
||||
// 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("Gestures");
|
||||
// Class Name
|
||||
assertThat(cursor.getString(11)).isEqualTo(className);
|
||||
// Icon
|
||||
assertThat(cursor.getInt(12)).isEqualTo(iconResId);
|
||||
// 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
|
||||
assertThat(cursor.getBlob(20)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddResourceCheckboxPreference_RowsMatch() {
|
||||
SearchIndexableResource resource = getFakeResource(R.xml.application_settings);
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
||||
new HashMap<String, List<String>>());
|
||||
|
||||
/* 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("Apps");
|
||||
// Class Name
|
||||
assertThat(cursor.getString(11)).isEqualTo(className);
|
||||
// Icon
|
||||
assertThat(cursor.getInt(12)).isEqualTo(iconResId);
|
||||
// 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
|
||||
assertThat(cursor.getBlob(20)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddResourceListPreference_RowsMatch() {
|
||||
SearchIndexableResource resource = getFakeResource(R.xml.application_settings);
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
||||
new HashMap<String, List<String>>());
|
||||
|
||||
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("Apps");
|
||||
// Class Name
|
||||
assertThat(cursor.getString(11)).isEqualTo(className);
|
||||
// Icon
|
||||
assertThat(cursor.getInt(12)).isEqualTo(iconResId);
|
||||
// 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
|
||||
assertThat(cursor.getBlob(20)).isNull();
|
||||
}
|
||||
|
||||
// Tests for the flow: IndexOneResource -> IndexFromProvider -> IndexFromResource ->
|
||||
// UpdateOneRowWithFilteredData -> UpdateOneRow
|
||||
|
||||
@Test
|
||||
public void testResourceProvider_RowInserted() {
|
||||
SearchIndexableResource resource = getFakeResource(R.xml.gesture_settings);
|
||||
resource.xmlResId = 0;
|
||||
resource.className = "com.android.settings.display.ScreenZoomSettings";
|
||||
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
||||
new HashMap<String, List<String>>());
|
||||
Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
|
||||
assertThat(cursor.getCount()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceProvider_Matches() {
|
||||
SearchIndexableResource resource = getFakeResource(R.xml.gesture_settings);
|
||||
resource.xmlResId = 0;
|
||||
resource.className = "com.android.settings.display.ScreenZoomSettings";
|
||||
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
||||
new HashMap<String, List<String>>());
|
||||
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(rank);
|
||||
// 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(iconResId);
|
||||
// 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
|
||||
assertThat(cursor.getBlob(20)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceProvider_ResourceRowInserted() {
|
||||
SearchIndexableResource resource = getFakeResource(R.xml.gesture_settings);
|
||||
resource.xmlResId = 0;
|
||||
resource.className = "com.android.settings.LegalSettings";
|
||||
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
||||
new HashMap<String, List<String>>());
|
||||
Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null);
|
||||
assertThat(cursor.getCount()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResourceProvider_ResourceRowMatches() {
|
||||
SearchIndexableResource resource = getFakeResource(R.xml.gesture_settings);
|
||||
resource.xmlResId = 0;
|
||||
resource.className = "com.android.settings.LegalSettings";
|
||||
|
||||
mManager.indexOneSearchIndexableData(mDb, localeStr, resource,
|
||||
new HashMap<String, List<String>>());
|
||||
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("Legal information");
|
||||
// Normalized Title
|
||||
assertThat(cursor.getString(3)).isEqualTo("legal information");
|
||||
// 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)).isEmpty();
|
||||
// Screen Title
|
||||
assertThat(cursor.getString(10)).isEqualTo("Legal information");
|
||||
// Class Name
|
||||
assertThat(cursor.getString(11))
|
||||
.isEqualTo("com.android.settings.LegalSettings");
|
||||
// Icon
|
||||
assertThat(cursor.getInt(12)).isEqualTo(iconResId);
|
||||
// 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
|
||||
assertThat(cursor.getBlob(20)).isNull();
|
||||
}
|
||||
|
||||
// Util functions
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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 static for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package com.android.settings.search;
|
||||
|
||||
import android.content.Intent;
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.search2.DatabaseIndexingManager.DatabaseRow;
|
||||
import com.android.settings.search2.DatabaseIndexingManager.DatabaseRow.Builder;
|
||||
import com.android.settings.search2.IntentPayload;
|
||||
import com.android.settings.search2.ResultPayload;
|
||||
import com.android.settings.search2.ResultPayloadUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
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 builder;
|
||||
|
||||
private static final String LOCALE = "locale";
|
||||
private static final String UPDATED_TITLE = "updated title";
|
||||
private static final String NORMALIZED_TITLE = "normal title";
|
||||
private static final String UPDATED_SUMMARY_ON = "updated summary on";
|
||||
private static final String NORMALIZED_SUMMARY_ON = "normalized summary on";
|
||||
private static final String UPDATED_SUMMARY_OFF = "updated summary off";
|
||||
private static final String NORMALIZED_SUMMARY_OFF = "normalized summary off";
|
||||
private static final String ENTRIES = "entries";
|
||||
private static final String CLASS_NAME = "class name";
|
||||
private static final String SCREEN_TITLE = "sceen title";
|
||||
private static final int ICON_RES_ID = 0xff;
|
||||
private static final int RANK = 1;
|
||||
private static final String SPACE_DELIMITED_KEYWORDS = "keywords";
|
||||
private static final String INTENT_ACTION = "intent action";
|
||||
private static final String INTENT_TARGET_PACKAGE = "target package";
|
||||
private static final String INTENT_TARGET_CLASS = "target class";
|
||||
private static final boolean ENABLED = true;
|
||||
private static final String KEY = "key";
|
||||
private static final int USER_ID = 1;
|
||||
private static IntentPayload intentPayload;
|
||||
|
||||
private final String EXTRA_KEY = "key";
|
||||
private final String EXTRA_VALUE = "value";
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_KEY, EXTRA_VALUE);
|
||||
intentPayload = new IntentPayload(intent);
|
||||
|
||||
builder = new DatabaseRow.Builder();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFullRowBuild_NonNull() {
|
||||
DatabaseRow row = generateRow();
|
||||
assertThat(row).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrimativesBuild_NoDataLoss() {
|
||||
DatabaseRow row = generateRow();
|
||||
|
||||
assertThat(row.locale).isEqualTo(LOCALE);
|
||||
assertThat(row.updatedTitle).isEqualTo(UPDATED_TITLE);
|
||||
assertThat(row.normalizedTitle).isEqualTo(NORMALIZED_TITLE);
|
||||
assertThat(row.updatedSummaryOn).isEqualTo(UPDATED_SUMMARY_ON);
|
||||
assertThat(row.normalizedSummaryOn).isEqualTo(NORMALIZED_SUMMARY_ON);
|
||||
assertThat(row.updatedSummaryOff).isEqualTo(UPDATED_SUMMARY_OFF);
|
||||
assertThat(row.normalizedSummaryOff).isEqualTo(NORMALIZED_SUMMARY_OFF);
|
||||
assertThat(row.entries).isEqualTo(ENTRIES);
|
||||
assertThat(row.className).isEqualTo(CLASS_NAME);
|
||||
assertThat(row.screenTitle).isEqualTo(SCREEN_TITLE);
|
||||
assertThat(row.iconResId).isEqualTo(ICON_RES_ID);
|
||||
assertThat(row.rank).isEqualTo(RANK);
|
||||
assertThat(row.spaceDelimitedKeywords).isEqualTo(SPACE_DELIMITED_KEYWORDS);
|
||||
assertThat(row.intentAction).isEqualTo(INTENT_ACTION);
|
||||
assertThat(row.intentTargetClass).isEqualTo(INTENT_TARGET_CLASS);
|
||||
assertThat(row.intentTargetPackage).isEqualTo(INTENT_TARGET_PACKAGE);
|
||||
assertThat(row.enabled).isEqualTo(ENABLED);
|
||||
assertThat(row.userId).isEqualTo(USER_ID);
|
||||
assertThat(row.key).isEqualTo(KEY);
|
||||
assertThat(row.payloadType).isEqualTo(ResultPayload.PayloadType.INTENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPayload_PayloadTypeAdded() {
|
||||
DatabaseRow row = generateRow();
|
||||
byte[] marshalledPayload = row.payload;
|
||||
IntentPayload payload = ResultPayloadUtils.unmarshall(marshalledPayload,
|
||||
IntentPayload.CREATOR);
|
||||
|
||||
Intent intent = payload.intent;
|
||||
assertThat(intent.getExtra(EXTRA_KEY)).isEqualTo(EXTRA_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestNullPayload_NoCrash() {
|
||||
Builder builder = new Builder();
|
||||
builder.setPayload(null);
|
||||
DatabaseRow row = builder.build();
|
||||
|
||||
assertThat(row.payload).isNull();
|
||||
}
|
||||
|
||||
private DatabaseRow generateRow() {
|
||||
builder.setLocale(LOCALE)
|
||||
.setUpdatedTitle(UPDATED_TITLE)
|
||||
.setNormalizedTitle(NORMALIZED_TITLE)
|
||||
.setUpdatedSummaryOn(UPDATED_SUMMARY_ON)
|
||||
.setNormalizedSummaryOn(NORMALIZED_SUMMARY_ON)
|
||||
.setUpdatedSummaryOff(UPDATED_SUMMARY_OFF)
|
||||
.setNormalizedSummaryOff(NORMALIZED_SUMMARY_OFF)
|
||||
.setEntries(ENTRIES)
|
||||
.setClassName(CLASS_NAME)
|
||||
.setScreenTitle(SCREEN_TITLE)
|
||||
.setIconResId(ICON_RES_ID)
|
||||
.setRank(RANK)
|
||||
.setSpaceDelimitedKeywords(SPACE_DELIMITED_KEYWORDS)
|
||||
.setIntentAction(INTENT_ACTION)
|
||||
.setIntentTargetPackage(INTENT_TARGET_PACKAGE)
|
||||
.setIntentTargetClass(INTENT_TARGET_CLASS)
|
||||
.setEnabled(ENABLED)
|
||||
.setKey(KEY)
|
||||
.setUserId(USER_ID)
|
||||
.setPayload(intentPayload);
|
||||
|
||||
return(builder.build());
|
||||
}
|
||||
}
|
||||
;
|
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.BadParcelableException;
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.search2.IntentPayload;
|
||||
import com.android.settings.search2.ResultPayloadUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import java.io.StreamCorruptedException;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static junit.framework.Assert.fail;
|
||||
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class ResultPayloadUtilsTest {
|
||||
private IntentPayload payload;
|
||||
|
||||
private final String EXTRA_KEY = "key";
|
||||
private final String EXTRA_VALUE = "value";
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(EXTRA_KEY, EXTRA_VALUE);
|
||||
payload = new IntentPayload(intent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnmarshallBadData_ExceptionThrown() {
|
||||
byte[] badData = "I'm going to fail :)".getBytes();
|
||||
try {
|
||||
ResultPayloadUtils.unmarshall(badData, IntentPayload.CREATOR);
|
||||
fail("unmarshall should throw exception");
|
||||
} catch ( RuntimeException e) {
|
||||
assertThat(e).isNotNull();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMarshallIntentPayload_NonEmptyArray() {
|
||||
byte[] marshalledPayload = ResultPayloadUtils.marshall(payload);
|
||||
assertThat(marshalledPayload).isNotNull();
|
||||
assertThat(marshalledPayload).isNotEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnmarshall_PreservedData() {
|
||||
byte[] marshalledPayload = ResultPayloadUtils.marshall(payload);
|
||||
IntentPayload newPayload = ResultPayloadUtils.unmarshall(marshalledPayload,
|
||||
IntentPayload.CREATOR);
|
||||
|
||||
String originalIntentExtra = payload.intent.getStringExtra(EXTRA_KEY);
|
||||
String copiedIntentExtra = newPayload.intent.getStringExtra(EXTRA_KEY);
|
||||
assertThat(originalIntentExtra).isEqualTo(copiedIntentExtra);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (C) 2016 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;
|
||||
|
||||
import android.content.res.XmlResourceParser;
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.settings.SettingsRobolectricTestRunner;
|
||||
import com.android.settings.TestConfig;
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.android.settings.search2.XmlParserUtils;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.annotation.Config;
|
||||
import org.robolectric.shadows.ShadowApplication;
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
/**
|
||||
* These tests use a series of preferences that have specific attributes which are sometimes
|
||||
* uncommon (such as summaryOn).
|
||||
*
|
||||
* If changing a preference file breaks a test in this test file, please replace its reference
|
||||
* with another preference with a matchin replacement attribute.
|
||||
*/
|
||||
@RunWith(SettingsRobolectricTestRunner.class)
|
||||
@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION)
|
||||
public class XmlParserUtilTest {
|
||||
|
||||
private Context mContext;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mContext = ShadowApplication.getInstance().getApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataTitleValid_ReturnsPreferenceTitle() {
|
||||
XmlResourceParser parser = getChildByType(R.xml.gesture_settings,
|
||||
"com.android.settings.gestures.GesturePreference");
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String title = XmlParserUtils.getDataTitle(mContext, attrs);
|
||||
String expTitle = mContext.getString(R.string.fingerprint_swipe_for_notifications_title);
|
||||
assertThat(title).isEqualTo(expTitle);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataKeywordsValid_ReturnsPreferenceKeywords() {
|
||||
XmlResourceParser parser = getParentPrimedParser(R.xml.gesture_settings);
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String keywords = XmlParserUtils.getDataKeywords(mContext, attrs);
|
||||
String expKeywords = mContext.getString(R.string.keywords_gesture);
|
||||
assertThat(keywords).isEqualTo(expKeywords);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataKeyValid_ReturnsPreferenceKey() {
|
||||
XmlResourceParser parser = getChildByType(R.xml.gesture_settings,
|
||||
"com.android.settings.gestures.GesturePreference");
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String key = XmlParserUtils.getDataKey(mContext, attrs);
|
||||
String expKey = "gesture_swipe_down_fingerprint";
|
||||
assertThat(key).isEqualTo(expKey);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSummaryValid_ReturnsPreferenceSummary() {
|
||||
XmlResourceParser parser = getChildByType(R.xml.gesture_settings,
|
||||
"com.android.settings.gestures.GesturePreference");
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String summary = XmlParserUtils.getDataSummary(mContext, attrs);
|
||||
String expSummary = mContext.getString(R.string.fingerprint_swipe_for_notifications_summary);
|
||||
assertThat(summary).isEqualTo(expSummary);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSummaryOnValid_ReturnsPreferenceSummaryOn() {
|
||||
XmlResourceParser parser = getChildByType(R.xml.application_settings, "CheckBoxPreference");
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String summary = XmlParserUtils.getDataSummaryOn(mContext, attrs);
|
||||
String expSummary = mContext.getString(R.string.advanced_settings_summary);
|
||||
assertThat(summary).isEqualTo(expSummary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSummaryOffValid_ReturnsPreferenceSummaryOff() {
|
||||
XmlResourceParser parser = getChildByType(R.xml.application_settings, "CheckBoxPreference");
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String summary = XmlParserUtils.getDataSummaryOff(mContext, attrs);
|
||||
String expSummary = mContext.getString(R.string.advanced_settings_summary);
|
||||
assertThat(summary).isEqualTo(expSummary);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataEntriesValid_ReturnsPreferenceEntries() {
|
||||
XmlResourceParser parser = getChildByType(R.xml.application_settings, "ListPreference");
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String entries = XmlParserUtils.getDataEntries(mContext, attrs);
|
||||
String[] expEntries = mContext.getResources()
|
||||
.getStringArray(R.array.app_install_location_entries);
|
||||
for (int i = 0; i < expEntries.length; i++) {
|
||||
assertThat(entries).contains(expEntries[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Null checks
|
||||
|
||||
@Test
|
||||
public void testDataKeyInvalid_ReturnsNull() {
|
||||
XmlResourceParser parser = getParentPrimedParser(R.xml.gesture_settings);
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String key = XmlParserUtils.getDataKey(mContext, attrs);
|
||||
assertThat(key).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSummaryInvalid_ReturnsNull() {
|
||||
XmlResourceParser parser = getParentPrimedParser(R.xml.gesture_settings);
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String summary = XmlParserUtils.getDataSummary(mContext, attrs);
|
||||
assertThat(summary).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataSummaryOffInvalid_ReturnsNull() {
|
||||
XmlResourceParser parser = getParentPrimedParser(R.xml.gesture_settings);
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String summaryOff = XmlParserUtils.getDataSummaryOff(mContext, attrs);
|
||||
assertThat(summaryOff).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataEntriesInvalid_ReturnsNull() {
|
||||
XmlResourceParser parser = getParentPrimedParser(R.xml.gesture_settings);
|
||||
final AttributeSet attrs = Xml.asAttributeSet(parser);
|
||||
String entries = XmlParserUtils.getDataEntries(mContext, attrs);
|
||||
assertThat(entries).isNull();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param resId the ID for the XML preference
|
||||
* @return an XML resource parser that points to the start tag
|
||||
*/
|
||||
private XmlResourceParser getParentPrimedParser(int resId) {
|
||||
XmlResourceParser parser = null;
|
||||
try {
|
||||
parser = mContext.getResources().getXml(resId);
|
||||
|
||||
int type;
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& type != XmlPullParser.START_TAG) {
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
|
||||
private XmlResourceParser getChildByType(int resId, String xmlType) {
|
||||
XmlResourceParser parser = null;
|
||||
try {
|
||||
parser = mContext.getResources().getXml(resId);
|
||||
|
||||
int type;
|
||||
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
|
||||
&& type != XmlPullParser.START_TAG) {
|
||||
}
|
||||
while(parser.getName() != xmlType) {
|
||||
parser.next();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user