Update the Settings database to enable Payloads
Add Payload and Payload type columns to the settings database. This includes extending preference controllers to map their settings to UI components so that the payload results can be consumed by a front end. Change-Id: I889dcc4ff7793306718d12e1e5993386b58f21cc Fixes: 33451851, 33390556 Test: RunSettingsRoboTests
This commit is contained in:
@@ -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