1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.settings.search; 18 19 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE; 20 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_CLASS_NAME; 21 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ENTRIES; 22 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_ICON_RESID; 23 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_ACTION; 24 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_CLASS; 25 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE; 26 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEY; 27 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_KEYWORDS; 28 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SCREEN_TITLE; 29 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_OFF; 30 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_SUMMARY_ON; 31 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_TITLE; 32 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_RAW_USER_ID; 33 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_CLASS_NAME; 34 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_ICON_RESID; 35 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_ACTION; 36 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS; 37 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE; 38 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RANK; 39 import static android.provider.SearchIndexablesContract.COLUMN_INDEX_XML_RES_RESID; 40 41 import static com.google.common.truth.Truth.assertThat; 42 43 import android.content.Context; 44 import android.database.Cursor; 45 import android.provider.SearchIndexableResource; 46 47 import androidx.test.core.app.ApplicationProvider; 48 import androidx.test.ext.junit.runners.AndroidJUnit4; 49 50 import com.android.settingslib.search.Indexable; 51 import com.android.settingslib.search.SearchIndexableData; 52 import com.android.settingslib.search.SearchIndexableRaw; 53 import com.android.settingslib.search.SearchIndexableResources; 54 55 import org.junit.Before; 56 import org.junit.Test; 57 import org.junit.runner.RunWith; 58 59 import java.util.Collection; 60 import java.util.Collections; 61 import java.util.HashSet; 62 import java.util.List; 63 import java.util.Set; 64 65 @RunWith(AndroidJUnit4.class) 66 public class CarSettingsSearchIndexablesProviderTest { 67 private final Context mContext = ApplicationProvider.getApplicationContext(); 68 69 private CarSettingsSearchIndexablesProvider mProvider; 70 private SearchIndexableResources mSearchIndexableResources; 71 72 @Before setup()73 public void setup() { 74 mSearchIndexableResources = new SearchIndexableResources() { 75 Set<SearchIndexableData> mValues = new HashSet<>(); 76 77 @Override 78 public Collection<SearchIndexableData> getProviderValues() { 79 return mValues; 80 } 81 82 @Override 83 public void addIndex(SearchIndexableData indexBundle) { 84 mValues.add(indexBundle); 85 } 86 }; 87 88 mProvider = new CarSettingsSearchIndexablesProvider(); 89 mProvider.setResources(mSearchIndexableResources); 90 } 91 92 @Test queryXmlResources_onEmptyResources_returnsEmptyList()93 public void queryXmlResources_onEmptyResources_returnsEmptyList() { 94 assertThat(mProvider.queryXmlResources(null).getCount()).isEqualTo(0); 95 } 96 97 @Test queryXmlResources_fillsColumns()98 public void queryXmlResources_fillsColumns() { 99 SearchIndexableResource res = makeResource(/* seed= */ 50); 100 101 TestSearchIndexProvider provider = new TestSearchIndexProvider(); 102 provider.setResources(Collections.singletonList(res)); 103 mSearchIndexableResources.addIndex( 104 new SearchIndexableData(TestSearchIndexProvider.class, 105 provider)); 106 107 Cursor c = mProvider.queryXmlResources(null); 108 109 assertThat(c.getCount()).isEqualTo(1); 110 111 c.moveToFirst(); 112 113 assertEqual(c, res); 114 } 115 116 @Test queryXmlResources_returnsAllRows()117 public void queryXmlResources_returnsAllRows() { 118 List<SearchIndexableResource> resources = List.of(makeResource(/* seed= */ 1), 119 makeResource(/* seed= */ 2), 120 makeResource(/* seed= */ 3)); 121 122 TestSearchIndexProvider provider = new TestSearchIndexProvider(); 123 provider.setResources(resources); 124 125 mSearchIndexableResources.addIndex( 126 new SearchIndexableData(TestSearchIndexProvider.class, 127 provider)); 128 129 Cursor c = mProvider.queryXmlResources(null); 130 131 assertThat(c.getCount()).isEqualTo(resources.size()); 132 133 int i = 0; 134 while (c.moveToNext()) { 135 assertEqual(c, resources.get(i++)); 136 } 137 } 138 139 @Test queryXmlResources_onPartiallyFilledFields_returnsPartialRows()140 public void queryXmlResources_onPartiallyFilledFields_returnsPartialRows() { 141 SearchIndexableResource res = makeResource(/* seed= */ 100); 142 res.intentTargetPackage = null; 143 TestSearchIndexProvider provider = new TestSearchIndexProvider(); 144 provider.setResources(Collections.singletonList(res)); 145 146 mSearchIndexableResources.addIndex( 147 new SearchIndexableData(TestSearchIndexProvider.class, 148 provider)); 149 150 151 Cursor c = mProvider.queryXmlResources(null); 152 153 assertThat(c.getCount()).isEqualTo(1); 154 155 c.moveToFirst(); 156 157 assertEqual(c, res); 158 } 159 160 @Test queryXmlResources_onNullResources_returnsEmptyList()161 public void queryXmlResources_onNullResources_returnsEmptyList() { 162 mSearchIndexableResources.addIndex( 163 new SearchIndexableData(TestSearchIndexProvider.class, 164 new TestSearchIndexProvider())); 165 166 assertThat(mProvider.queryXmlResources(null).getCount()).isEqualTo(0); 167 } 168 169 @Test queryRawData_fillsColumns()170 public void queryRawData_fillsColumns() { 171 SearchIndexableRaw rawData = makeRawData(/* seed= */ 99); 172 173 TestSearchIndexProvider provider = new TestSearchIndexProvider(); 174 provider.setRawData(Collections.singletonList(rawData)); 175 176 mSearchIndexableResources.addIndex( 177 new SearchIndexableData(TestSearchIndexProvider.class, provider)); 178 179 Cursor c = mProvider.queryRawData(null); 180 181 assertThat(c.getCount()).isEqualTo(1); 182 183 c.moveToFirst(); 184 185 assertEqual(c, rawData); 186 } 187 188 @Test queryRawData_returnsAllRows()189 public void queryRawData_returnsAllRows() { 190 List<SearchIndexableRaw> rawData = List.of(makeRawData(/* seed= */ 1), 191 makeRawData(/* seed= */ 2), makeRawData(/* seed= */ 3)); 192 193 TestSearchIndexProvider provider = new TestSearchIndexProvider(); 194 provider.setRawData(rawData); 195 196 mSearchIndexableResources.addIndex( 197 new SearchIndexableData(TestSearchIndexProvider.class, provider)); 198 199 Cursor c = mProvider.queryRawData(null); 200 201 assertThat(c.getCount()).isEqualTo(rawData.size()); 202 int i = 0; 203 204 while (c.moveToNext()) { 205 assertEqual(c, rawData.get(i++)); 206 } 207 } 208 209 @Test queryRawData_onPartiallyFilledFields_returnsPartialRows()210 public void queryRawData_onPartiallyFilledFields_returnsPartialRows() { 211 SearchIndexableRaw rawData = makeRawData(/* seed= */ 99); 212 rawData.className = null; 213 rawData.keywords = null; 214 215 TestSearchIndexProvider provider = new TestSearchIndexProvider(); 216 provider.setRawData(Collections.singletonList(rawData)); 217 218 mSearchIndexableResources.addIndex( 219 new SearchIndexableData(TestSearchIndexProvider.class, provider)); 220 221 Cursor c = mProvider.queryRawData(null); 222 223 assertThat(c.getCount()).isEqualTo(1); 224 225 c.moveToFirst(); 226 227 assertEqual(c, rawData); 228 } 229 230 @Test queryRawData_onEmptyResources_returnsEmpty()231 public void queryRawData_onEmptyResources_returnsEmpty() { 232 assertThat(mProvider.queryRawData(null).getCount()).isEqualTo(0); 233 } 234 235 @Test queryRawData_onNullRawDataList_returnsEmptyList()236 public void queryRawData_onNullRawDataList_returnsEmptyList() { 237 mSearchIndexableResources.addIndex( 238 new SearchIndexableData(TestSearchIndexProvider.class, 239 new TestSearchIndexProvider())); 240 241 assertThat(mProvider.queryRawData(null).getCount()).isEqualTo(0); 242 } 243 244 @Test queryNonIndexableKeys_fillsColumns()245 public void queryNonIndexableKeys_fillsColumns() { 246 String key = "key1"; 247 248 TestSearchIndexProvider provider = new TestSearchIndexProvider(); 249 provider.setNonIndexableKeys(Collections.singletonList(key)); 250 251 mSearchIndexableResources.addIndex( 252 new SearchIndexableData(TestSearchIndexProvider.class, provider)); 253 254 Cursor c = mProvider.queryNonIndexableKeys(null); 255 256 assertThat(c.getCount()).isEqualTo(1); 257 258 c.moveToFirst(); 259 260 assertThat(c.getString(COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE)).isEqualTo(key); 261 } 262 263 @Test queryNonIndexableKeys_returnsAllRows()264 public void queryNonIndexableKeys_returnsAllRows() { 265 List<String> keys = List.of("key1", "key2", "key3"); 266 267 TestSearchIndexProvider provider = new TestSearchIndexProvider(); 268 provider.setNonIndexableKeys(keys); 269 270 mSearchIndexableResources.addIndex( 271 new SearchIndexableData(TestSearchIndexProvider.class, provider)); 272 273 Cursor c = mProvider.queryNonIndexableKeys(null); 274 275 assertThat(c.getCount()).isEqualTo(keys.size()); 276 int i = 0; 277 278 while (c.moveToNext()) { 279 assertThat(c.getString(COLUMN_INDEX_NON_INDEXABLE_KEYS_KEY_VALUE)).isEqualTo( 280 keys.get(i++)); 281 } 282 } 283 284 @Test queryNonIndexableKeys_onEmptyResources_returnsEmpty()285 public void queryNonIndexableKeys_onEmptyResources_returnsEmpty() { 286 assertThat(mProvider.queryNonIndexableKeys(null).getCount()).isEqualTo(0); 287 } 288 289 @Test queryNonIndexableKeys_onNullNonIndexableKeysList_returnsEmptyList()290 public void queryNonIndexableKeys_onNullNonIndexableKeysList_returnsEmptyList() { 291 mSearchIndexableResources.addIndex( 292 new SearchIndexableData(TestSearchIndexProvider.class, 293 new TestSearchIndexProvider())); 294 295 assertThat(mProvider.queryNonIndexableKeys(null).getCount()).isEqualTo(0); 296 } 297 makeResource(int seed)298 private SearchIndexableResource makeResource(int seed) { 299 int rank = seed; 300 int resId = seed + 1; 301 String className = seed + "className"; 302 int iconResId = seed + 2; 303 String action = seed + "action"; 304 String intentPackage = seed + "package"; 305 String intentClass = seed + "class"; 306 307 SearchIndexableResource resource = new SearchIndexableResource(rank, resId, className, 308 iconResId); 309 resource.intentAction = action; 310 resource.intentTargetPackage = intentPackage; 311 resource.intentTargetClass = intentClass; 312 313 return resource; 314 } 315 assertEqual(Cursor c, SearchIndexableResource res)316 private void assertEqual(Cursor c, SearchIndexableResource res) { 317 assertThat(c.getInt(COLUMN_INDEX_XML_RES_RANK)).isEqualTo(res.rank); 318 assertThat(c.getInt(COLUMN_INDEX_XML_RES_RESID)).isEqualTo(res.xmlResId); 319 assertThat(c.getString(COLUMN_INDEX_XML_RES_CLASS_NAME)).isEqualTo(res.className); 320 assertThat(c.getInt(COLUMN_INDEX_XML_RES_ICON_RESID)).isEqualTo(res.iconResId); 321 assertThat(c.getString(COLUMN_INDEX_XML_RES_INTENT_ACTION)).isEqualTo(res.intentAction); 322 assertThat(c.getString(COLUMN_INDEX_XML_RES_INTENT_TARGET_PACKAGE)).isEqualTo( 323 res.intentTargetPackage); 324 assertThat(c.getString(COLUMN_INDEX_XML_RES_INTENT_TARGET_CLASS)).isEqualTo( 325 res.intentTargetClass); 326 } 327 makeRawData(int seed)328 private SearchIndexableRaw makeRawData(int seed) { 329 SearchIndexableRaw rawData = new SearchIndexableRaw(mContext); 330 rawData.title = seed + "title"; 331 rawData.summaryOn = seed + "summaryOn"; 332 rawData.summaryOff = seed + "summaryOff"; 333 rawData.entries = seed + "entries"; 334 rawData.keywords = seed + "keywords"; 335 rawData.screenTitle = seed + "screenTitle"; 336 rawData.className = seed + "className"; 337 rawData.iconResId = seed; 338 rawData.intentAction = seed + "intentAction"; 339 rawData.intentTargetPackage = seed + "intentTargetPackage"; 340 rawData.intentTargetClass = seed + "intentTargetClass"; 341 rawData.key = seed + "key"; 342 rawData.userId = seed + 1; 343 return rawData; 344 } 345 assertEqual(Cursor c, SearchIndexableRaw raw)346 private void assertEqual(Cursor c, SearchIndexableRaw raw) { 347 assertThat(c.getString(COLUMN_INDEX_RAW_TITLE)).isEqualTo(raw.title); 348 assertThat(c.getString(COLUMN_INDEX_RAW_SUMMARY_ON)).isEqualTo(raw.summaryOn); 349 assertThat(c.getString(COLUMN_INDEX_RAW_SUMMARY_OFF)).isEqualTo(raw.summaryOff); 350 assertThat(c.getString(COLUMN_INDEX_RAW_ENTRIES)).isEqualTo(raw.entries); 351 assertThat(c.getString(COLUMN_INDEX_RAW_KEYWORDS)).isEqualTo(raw.keywords); 352 assertThat(c.getString(COLUMN_INDEX_RAW_SCREEN_TITLE)).isEqualTo(raw.screenTitle); 353 assertThat(c.getString(COLUMN_INDEX_RAW_CLASS_NAME)).isEqualTo(raw.className); 354 assertThat(c.getInt(COLUMN_INDEX_RAW_ICON_RESID)).isEqualTo(raw.iconResId); 355 assertThat(c.getString(COLUMN_INDEX_RAW_INTENT_ACTION)).isEqualTo(raw.intentAction); 356 assertThat(c.getString(COLUMN_INDEX_RAW_INTENT_TARGET_PACKAGE)).isEqualTo( 357 raw.intentTargetPackage); 358 assertThat(c.getString(COLUMN_INDEX_RAW_INTENT_TARGET_CLASS)).isEqualTo( 359 raw.intentTargetClass); 360 assertThat(c.getString(COLUMN_INDEX_RAW_KEY)).isEqualTo(raw.key); 361 assertThat(c.getInt(COLUMN_INDEX_RAW_USER_ID)).isEqualTo(raw.userId); 362 } 363 364 private static class TestSearchIndexProvider implements Indexable.SearchIndexProvider { 365 private List<SearchIndexableResource> mResources; 366 private List<SearchIndexableRaw> mRawData; 367 private List<String> mNonIndexableKeys; 368 TestSearchIndexProvider()369 TestSearchIndexProvider() { 370 } 371 372 @Override getXmlResourcesToIndex(Context context, boolean enabled)373 public List<SearchIndexableResource> getXmlResourcesToIndex(Context context, 374 boolean enabled) { 375 return mResources; 376 } 377 378 @Override getRawDataToIndex(Context context, boolean enabled)379 public List<SearchIndexableRaw> getRawDataToIndex(Context context, boolean enabled) { 380 return mRawData; 381 } 382 383 @Override getDynamicRawDataToIndex(Context context, boolean enabled)384 public List<SearchIndexableRaw> getDynamicRawDataToIndex(Context context, boolean enabled) { 385 return mRawData; 386 } 387 388 @Override getNonIndexableKeys(Context context)389 public List<String> getNonIndexableKeys(Context context) { 390 return mNonIndexableKeys; 391 } 392 setResources(List<SearchIndexableResource> resources)393 void setResources(List<SearchIndexableResource> resources) { 394 mResources = resources; 395 } 396 setRawData(List<SearchIndexableRaw> rawData)397 void setRawData(List<SearchIndexableRaw> rawData) { 398 mRawData = rawData; 399 } 400 setNonIndexableKeys(List<String> nonIndexableKeys)401 void setNonIndexableKeys(List<String> nonIndexableKeys) { 402 mNonIndexableKeys = nonIndexableKeys; 403 } 404 } 405 } 406