diff --git a/src/com/android/settings/search2/DatabaseResultLoader.java b/src/com/android/settings/search2/DatabaseResultLoader.java index 0bbded29513..057edeb239c 100644 --- a/src/com/android/settings/search2/DatabaseResultLoader.java +++ b/src/com/android/settings/search2/DatabaseResultLoader.java @@ -141,9 +141,7 @@ public class DatabaseResultLoader extends AsyncLoader> { private List query(String[] matchColumns, int baseRank) { final String whereClause = buildWhereClause(matchColumns); - final String[] selection = new String[matchColumns.length]; - final String query = "%" + mQueryText + "%"; - Arrays.fill(selection, query); + final String[] selection = buildQuerySelection(matchColumns.length * 2); final Cursor resultCursor = mDatabase.query(TABLE_PREFS_INDEX, SELECT_COLUMNS, whereClause, selection, null, null, null); @@ -169,6 +167,8 @@ public class DatabaseResultLoader extends AsyncLoader> { StringBuilder sb = new StringBuilder(" ("); final int count = matchColumns.length; for (int n = 0; n < count; n++) { + sb.append(matchColumns[n]); + sb.append(" like ? OR "); sb.append(matchColumns[n]); sb.append(" like ?"); if (n < count - 1) { @@ -178,4 +178,23 @@ public class DatabaseResultLoader extends AsyncLoader> { sb.append(") AND enabled = 1"); return sb.toString(); } + + /** + * Fills out the selection array to match the query as the prefix of a word. + * + * @param size is twice the number of columns to be matched. The first match is for the prefix + * of the first word in the column. The second match is for any subsequent word + * prefix match. + */ + private String[] buildQuerySelection(int size) { + String[] selection = new String[size]; + final String query = mQueryText + "%"; + final String subStringQuery = "% " + mQueryText + "%"; + + for(int i = 0; i < (size - 1); i += 2) { + selection[i] = query; + selection[i + 1] = subStringQuery; + } + return selection; + } } diff --git a/tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java b/tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java index 31e6e6c288f..6368fcb4808 100644 --- a/tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java +++ b/tests/robotests/src/com/android/settings/search/DatabaseResultLoaderTest.java @@ -144,6 +144,62 @@ public class DatabaseResultLoaderTest { assertThat(loader.loadInBackground().size()).isEqualTo(1); } + @Test + public void testSpecialCasePrefix_MatchesPrefixOfEntry() { + insertSpecialCase("Photos"); + loader = new DatabaseResultLoader(mContext, "pho"); + assertThat(loader.loadInBackground().size()).isEqualTo(1); + } + + @Test + public void testSpecialCasePrefix_DoesNotMatchNonPrefixSubstring() { + insertSpecialCase("Photos"); + loader = new DatabaseResultLoader(mContext, "hot"); + assertThat(loader.loadInBackground().size()).isEqualTo(0); + } + + @Test + public void testSpecialCaseMultiWordPrefix_MatchesPrefixOfEntry() { + insertSpecialCase("Apps Notifications"); + loader = new DatabaseResultLoader(mContext, "Apps"); + assertThat(loader.loadInBackground().size()).isEqualTo(1); + } + + @Test + public void testSpecialCaseMultiWordPrefix_MatchesSecondWordPrefixOfEntry() { + insertSpecialCase("Apps Notifications"); + loader = new DatabaseResultLoader(mContext, "Not"); + assertThat(loader.loadInBackground().size()).isEqualTo(1); + } + + @Test + public void testSpecialCaseMultiWordPrefix_DoesNotMatchMatchesPrefixOfFirstEntry() { + insertSpecialCase("Apps Notifications"); + loader = new DatabaseResultLoader(mContext, "pp"); + assertThat(loader.loadInBackground().size()).isEqualTo(0); + } + + @Test + public void testSpecialCaseMultiWordPrefix_DoesNotMatchMatchesPrefixOfSecondEntry() { + insertSpecialCase("Apps Notifications"); + loader = new DatabaseResultLoader(mContext, "tion"); + assertThat(loader.loadInBackground().size()).isEqualTo(0); + } + + @Test + public void testSpecialCaseMultiWordPrefixWithSpecial_MatchesPrefixOfEntry() { + insertSpecialCase("Apps & Notifications"); + loader = new DatabaseResultLoader(mContext, "App"); + assertThat(loader.loadInBackground().size()).isEqualTo(1); + } + + @Test + public void testSpecialCaseMultiWordPrefixWithSpecial_MatchesPrefixOfSecondEntry() { + insertSpecialCase("Apps & Notifications"); + loader = new DatabaseResultLoader(mContext, "No"); + assertThat(loader.loadInBackground().size()).isEqualTo(1); + } + private void insertSpecialCase(String specialCase) { String normalized = DatabaseIndexingUtils.normalizeHyphen(specialCase); normalized = DatabaseIndexingUtils.normalizeString(normalized); @@ -184,11 +240,11 @@ public class DatabaseResultLoaderTest { values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "alpha_title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "alpha title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "alpha_summary"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "alpha_summary"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "alpha summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "alpha_summary"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "alpha_summary"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "alpha_entries"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "alpha_keywords"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "alpha summary"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "alpha entries"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "alpha keywords"); values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "com.android.settings.gestures.GestureSettings"); values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves"); @@ -211,11 +267,11 @@ public class DatabaseResultLoaderTest { values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "bravo_title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "bravo title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "bravo_summary"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "bravo_summary"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "bravo summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "bravo_summary"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "bravo_summary"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "bravo_entries"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "bravo_keywords"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "bravo summary"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "bravo entries"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "bravo keywords"); values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "com.android.settings.gestures.GestureSettings"); values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves"); @@ -237,11 +293,11 @@ public class DatabaseResultLoaderTest { values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, "charlie_title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, "charlie title"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, "charlie_summary"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "charlie_summary"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, "charlie summary"); values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, "charlie_summary"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "charlie_summary"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "charlie_entries"); - values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "charlie_keywords"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, "charlie summary"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, "charlie entries"); + values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, "charlie keywords"); values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, "com.android.settings.gestures.GestureSettings"); values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves");