DatabaseIndexingManagerTest.java revision bdd57aad3eb4ffeb106feb7b3d300ac6680def0d
1/* 2 * Copyright (C) 2017 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 18package com.android.settings.search; 19 20import android.annotation.NonNull; 21import android.annotation.Nullable; 22import android.content.ContentProvider; 23import android.content.ContentValues; 24import android.content.Context; 25import android.content.Intent; 26import android.content.pm.PackageManager; 27import android.content.pm.ProviderInfo; 28import android.content.pm.ResolveInfo; 29import android.database.Cursor; 30import android.database.MatrixCursor; 31import android.database.sqlite.SQLiteDatabase; 32import android.net.Uri; 33import android.os.Build; 34import android.provider.SearchIndexableResource; 35import android.util.ArrayMap; 36 37import com.android.settings.R; 38import com.android.settings.testutils.FakeFeatureFactory; 39import com.android.settings.testutils.SettingsRobolectricTestRunner; 40import com.android.settings.TestConfig; 41import com.android.settings.testutils.DatabaseTestUtils; 42import com.android.settings.testutils.shadow.ShadowDatabaseIndexingUtils; 43import com.android.settings.testutils.shadow.ShadowRunnableAsyncTask; 44 45import org.junit.After; 46import org.junit.Before; 47import org.junit.Test; 48import org.junit.runner.RunWith; 49import org.mockito.Mock; 50import org.mockito.MockitoAnnotations; 51import org.robolectric.Robolectric; 52import org.robolectric.RuntimeEnvironment; 53import org.robolectric.annotation.Config; 54import org.robolectric.shadows.ShadowContentResolver; 55 56import java.util.ArrayList; 57import java.util.Arrays; 58import java.util.HashMap; 59import java.util.HashSet; 60import java.util.List; 61import java.util.Locale; 62import java.util.Map; 63import java.util.Set; 64 65import static android.provider.SearchIndexablesContract.INDEXABLES_RAW_COLUMNS; 66import static com.google.common.truth.Truth.assertThat; 67import static org.mockito.Matchers.any; 68import static org.mockito.Matchers.anyInt; 69import static org.mockito.Matchers.anyList; 70import static org.mockito.Matchers.anyMap; 71import static org.mockito.Matchers.anyString; 72import static org.mockito.Mockito.doNothing; 73import static org.mockito.Mockito.doReturn; 74import static org.mockito.Mockito.mock; 75import static org.mockito.Mockito.spy; 76import static org.mockito.Mockito.times; 77import static org.mockito.Mockito.verify; 78import static org.mockito.Mockito.when; 79 80@RunWith(SettingsRobolectricTestRunner.class) 81@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION, 82 shadows = {ShadowRunnableAsyncTask.class}) 83public class DatabaseIndexingManagerTest { 84 private final String localeStr = "en_US"; 85 86 private final int rank = 8; 87 private final String title = "title\u2011title"; 88 private final String updatedTitle = "title-title"; 89 private final String normalizedTitle = "titletitle"; 90 private final String summaryOn = "summary\u2011on"; 91 private final String updatedSummaryOn = "summary-on"; 92 private final String normalizedSummaryOn = "summaryon"; 93 private final String summaryOff = "summary\u2011off"; 94 private final String updatedSummaryOff = "summary-off"; 95 private final String normalizedSummaryOff = "summaryoff"; 96 private final String entries = "entries"; 97 private final String keywords = "keywords, keywordss, keywordsss"; 98 private final String spaceDelimittedKeywords = "keywords keywordss keywordsss"; 99 private final String screenTitle = "screen title"; 100 private final String className = "class name"; 101 private final int iconResId = 0xff; 102 private final int noIcon = 0; 103 private final String action = "action"; 104 private final String targetPackage = "target package"; 105 private final String targetClass = "target class"; 106 private final String packageName = "package name"; 107 private final String key = "key"; 108 private final int userId = -1; 109 private final boolean enabled = true; 110 111 private final String AUTHORITY_ONE = "authority"; 112 private final String PACKAGE_ONE = "com.android.settings"; 113 114 private final String TITLE_ONE = "title one"; 115 private final String TITLE_TWO = "title two"; 116 private final String KEY_ONE = "key one"; 117 private final String KEY_TWO = "key two"; 118 119 private Context mContext; 120 121 private DatabaseIndexingManager mManager; 122 private SQLiteDatabase mDb; 123 124 @Mock 125 private PackageManager mPackageManager; 126 127 @Before 128 public void setUp() { 129 MockitoAnnotations.initMocks(this); 130 mContext = spy(RuntimeEnvironment.application); 131 mManager = spy(new DatabaseIndexingManager(mContext, PACKAGE_ONE)); 132 mDb = IndexDatabaseHelper.getInstance(mContext).getWritableDatabase(); 133 134 doReturn(mPackageManager).when(mContext).getPackageManager(); 135 FakeFeatureFactory.setupForTest(mContext); 136 } 137 138 @After 139 public void cleanUp() { 140 DatabaseTestUtils.clearDb(mContext); 141 } 142 143 @Test 144 public void testDatabaseSchema() { 145 Cursor dbCursor = mDb.query("prefs_index", null, null, null, null, null, null); 146 List<String> columnNames = new ArrayList<>(Arrays.asList(dbCursor.getColumnNames())); 147 // Note that docid is not included. 148 List<String> expColumnNames = new ArrayList<>(Arrays.asList(new String[]{ 149 "locale", 150 "data_rank", 151 "data_title", 152 "data_title_normalized", 153 "data_summary_on", 154 "data_summary_on_normalized", 155 "data_summary_off", 156 "data_summary_off_normalized", 157 "data_entries", 158 "data_keywords", 159 "class_name", 160 "screen_title", 161 "intent_action", 162 "intent_target_package", 163 "intent_target_class", 164 "icon", 165 "enabled", 166 "data_key_reference", 167 "user_id", 168 "payload_type", 169 "payload" 170 })); 171 // Prevent database schema regressions 172 assertThat(columnNames).containsAllIn(expColumnNames); 173 } 174 175 // Tests for the flow: IndexOneRaw -> UpdateOneRowWithFilteredData -> UpdateOneRow 176 177 @Test 178 public void testInsertRawColumn_rowInserted() { 179 SearchIndexableRaw raw = getFakeRaw(); 180 mManager.indexOneSearchIndexableData(mDb, localeStr, raw, 181 new HashMap<>()/* Non-indexable keys */); 182 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); 183 assertThat(cursor.getCount()).isEqualTo(1); 184 } 185 186 @Test 187 public void testInsertRawColumn_nonIndexableKey_resultIsDisabled() { 188 SearchIndexableRaw raw = getFakeRaw(); 189 Map<String, Set<String>> niks = new HashMap<>(); 190 Set<String> keys = new HashSet<>(); 191 keys.add(raw.key); 192 niks.put(raw.intentTargetPackage, keys); 193 194 mManager.indexOneSearchIndexableData(mDb, localeStr, raw, niks); 195 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null); 196 assertThat(cursor.getCount()).isEqualTo(1); 197 } 198 199 @Test 200 public void testInsertRawColumn_rowMatches() { 201 SearchIndexableRaw raw = getFakeRaw(); 202 mManager.indexOneSearchIndexableData(mDb, localeStr, raw, 203 new HashMap<>()/* Non-indexable keys */); 204 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); 205 cursor.moveToPosition(0); 206 207 // Locale 208 assertThat(cursor.getString(0)).isEqualTo(localeStr); 209 // Data Rank 210 assertThat(cursor.getInt(1)).isEqualTo(raw.rank); 211 // Data Title 212 assertThat(cursor.getString(2)).isEqualTo(updatedTitle); 213 // Normalized Title 214 assertThat(cursor.getString(3)).isEqualTo(normalizedTitle); 215 // Summary On 216 assertThat(cursor.getString(4)).isEqualTo(updatedSummaryOn); 217 // Summary On Normalized 218 assertThat(cursor.getString(5)).isEqualTo(normalizedSummaryOn); 219 // Summary Off 220 assertThat(cursor.getString(6)).isEqualTo(updatedSummaryOff); 221 // Summary off normalized 222 assertThat(cursor.getString(7)).isEqualTo(normalizedSummaryOff); 223 // Entries 224 assertThat(cursor.getString(8)).isEqualTo(raw.entries); 225 // Keywords 226 assertThat(cursor.getString(9)).isEqualTo(spaceDelimittedKeywords); 227 // Screen Title 228 assertThat(cursor.getString(10)).isEqualTo(raw.screenTitle); 229 // Class Name 230 assertThat(cursor.getString(11)).isEqualTo(raw.className); 231 // Icon 232 assertThat(cursor.getInt(12)).isEqualTo(raw.iconResId); 233 // Intent Action 234 assertThat(cursor.getString(13)).isEqualTo(raw.intentAction); 235 // Target Package 236 assertThat(cursor.getString(14)).isEqualTo(raw.intentTargetPackage); 237 // Target Class 238 assertThat(cursor.getString(15)).isEqualTo(raw.intentTargetClass); 239 // Enabled 240 assertThat(cursor.getInt(16) == 1).isEqualTo(raw.enabled); 241 // Data ref key 242 assertThat(cursor.getString(17)).isNotNull(); 243 // User Id 244 assertThat(cursor.getInt(18)).isEqualTo(raw.userId); 245 // Payload Type - default is 0 246 assertThat(cursor.getInt(19)).isEqualTo(0); 247 // Payload 248 byte[] payload = cursor.getBlob(20); 249 ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload, 250 ResultPayload.CREATOR); 251 assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); 252 } 253 254 @Test 255 public void testInsertRawColumn_mismatchedLocale_noRowInserted() { 256 SearchIndexableRaw raw = getFakeRaw("ca-fr"); 257 mManager.indexOneSearchIndexableData(mDb, localeStr, raw, null /* Non-indexable keys */); 258 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); 259 assertThat(cursor.getCount()).isEqualTo(0); 260 } 261 262 // Tests for the flow: IndexOneResource -> IndexFromResource -> 263 // UpdateOneRowWithFilteredData -> UpdateOneRow 264 265 @Test 266 public void testNullResource_NothingInserted() { 267 mManager.indexOneSearchIndexableData(mDb, localeStr, null /* searchIndexableResource */, 268 new HashMap<>()); 269 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); 270 assertThat(cursor.getCount()).isEqualTo(0); 271 } 272 273 @Test 274 public void testAddResource_RowsInserted() { 275 SearchIndexableResource resource = getFakeResource(R.xml.display_settings); 276 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 277 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); 278 assertThat(cursor.getCount()).isEqualTo(17); 279 } 280 281 @Test 282 public void testAddResource_withNIKs_rowsInsertedDisabled() { 283 SearchIndexableResource resource = getFakeResource(R.xml.display_settings); 284 // Only add 2 of 16 items to be disabled. 285 String[] keys = {"brightness", "wallpaper"}; 286 Map<String, Set<String>> niks = getNonIndexableKeys(keys); 287 288 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, niks); 289 290 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null); 291 assertThat(cursor.getCount()).isEqualTo(2); 292 cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null); 293 assertThat(cursor.getCount()).isEqualTo(15); 294 } 295 296 @Test 297 public void testAddResourceHeader_rowsMatch() { 298 SearchIndexableResource resource = getFakeResource(R.xml.application_settings); 299 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 300 301 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); 302 cursor.moveToPosition(1); 303 304 // Locale 305 assertThat(cursor.getString(0)).isEqualTo(localeStr); 306 // Data Rank 307 assertThat(cursor.getInt(1)).isEqualTo(rank); 308 // Data Title 309 assertThat(cursor.getString(2)).isEqualTo("App info"); 310 // Normalized Title 311 assertThat(cursor.getString(3)).isEqualTo("app info"); 312 // Summary On 313 assertThat(cursor.getString(4)).isEqualTo("Manage apps, set up quick launch shortcuts"); 314 // Summary On Normalized 315 assertThat(cursor.getString(5)).isEqualTo("manage apps, set up quick launch shortcuts"); 316 // Summary Off - only on for checkbox preferences 317 assertThat(cursor.getString(6)).isEmpty(); 318 // Summary off normalized - only on for checkbox preferences 319 assertThat(cursor.getString(7)).isEmpty(); 320 // Entries - only on for list preferences 321 assertThat(cursor.getString(8)).isNull(); 322 // Keywords 323 assertThat(cursor.getString(9)).isEmpty(); 324 // Screen Title 325 assertThat(cursor.getString(10)).isEqualTo("App info"); 326 // Class Name 327 assertThat(cursor.getString(11)).isEqualTo(className); 328 // Icon 329 assertThat(cursor.getInt(12)).isEqualTo(0); 330 // Intent Action 331 assertThat(cursor.getString(13)).isEqualTo(action); 332 // Target Package 333 assertThat(cursor.getString(14)).isEqualTo(targetPackage); 334 // Target Class 335 assertThat(cursor.getString(15)).isEqualTo(targetClass); 336 // Enabled 337 assertThat(cursor.getInt(16) == 1).isEqualTo(enabled); 338 // Data ref key 339 assertThat(cursor.getString(17)).isEqualTo("applications_settings"); 340 // User Id 341 assertThat(cursor.getInt(18)).isEqualTo(userId); 342 // Payload Type - default is 0 343 assertThat(cursor.getInt(19)).isEqualTo(0); 344 // Payload - should be updated to real payloads as controllers are added 345 byte[] payload = cursor.getBlob(20); 346 ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload, 347 ResultPayload.CREATOR); 348 assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); 349 } 350 351 @Test 352 public void testAddResource_withChildFragment_shouldUpdateSiteMapDb() { 353 // FIXME: This test was failing. (count = 6 at the end) 354 355// SearchIndexableResource resource = getFakeResource(R.xml.network_and_internet); 356// mManager.indexOneSearchIndexableData(mDb, localeStr, resource, 357// new HashMap<>()); 358// Cursor query = mDb.query(IndexDatabaseHelper.Tables.TABLE_SITE_MAP, SITE_MAP_COLUMNS, 359// null, null, null, null, null); 360// query.moveToPosition(-1); 361// int count = 0; 362// while (query.moveToNext()) { 363// count++; 364// assertThat(query.getString(query.getColumnIndex(SiteMapColumns.PARENT_CLASS))) 365// .isEqualTo(className); 366// assertThat(query.getString(query.getColumnIndex(SiteMapColumns.PARENT_TITLE))) 367// .isEqualTo(mContext.getString(R.string.network_dashboard_title)); 368// assertThat(query.getString(query.getColumnIndex(SiteMapColumns.CHILD_CLASS))) 369// .isNotEmpty(); 370// assertThat(query.getString(query.getColumnIndex(SiteMapColumns.CHILD_TITLE))) 371// .isNotEmpty(); 372// } 373// assertThat(count).isEqualTo(5); 374 } 375 376 @Test 377 public void testAddResource_customSetting_rowsMatch() { 378 SearchIndexableResource resource = getFakeResource(R.xml.swipe_to_notification_settings); 379 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 380 final String prefTitle = 381 mContext.getString(R.string.fingerprint_swipe_for_notifications_title); 382 final String prefSummary = 383 mContext.getString(R.string.fingerprint_swipe_for_notifications_summary); 384 final String keywords = mContext.getString(R.string.keywords_gesture); 385 Cursor cursor = mDb.rawQuery( 386 "SELECT * FROM prefs_index where data_title='" + prefTitle + "'", null); 387 cursor.moveToFirst(); 388 389 // Locale 390 assertThat(cursor.getString(0)).isEqualTo(localeStr); 391 // Data Rank 392 assertThat(cursor.getInt(1)).isEqualTo(rank); 393 // Data Title 394 assertThat(cursor.getString(2)).isEqualTo(prefTitle); 395 // Normalized Title 396 assertThat(cursor.getString(3)).isEqualTo(prefTitle.toLowerCase()); 397 // Summary On 398 assertThat(cursor.getString(4)).isEqualTo(prefSummary); 399 // Summary On Normalized 400 assertThat(cursor.getString(5)).isEqualTo(prefSummary.toLowerCase()); 401 // Summary Off - only on for checkbox preferences 402 assertThat(cursor.getString(6)).isEmpty(); 403 // Summary off normalized - only on for checkbox preferences 404 assertThat(cursor.getString(7)).isEmpty(); 405 // Entries - only on for list preferences 406 assertThat(cursor.getString(8)).isNull(); 407 // Keywords 408 assertThat(cursor.getString(9)).isEqualTo(keywords); 409 // Screen Title 410 assertThat(cursor.getString(10)).isEqualTo( 411 mContext.getString(R.string.fingerprint_swipe_for_notifications_title)); 412 // Class Name 413 assertThat(cursor.getString(11)).isEqualTo(className); 414 // Icon 415 assertThat(cursor.getInt(12)).isEqualTo(noIcon); 416 // Intent Action 417 assertThat(cursor.getString(13)).isEqualTo(action); 418 // Target Package 419 assertThat(cursor.getString(14)).isEqualTo(targetPackage); 420 // Target Class 421 assertThat(cursor.getString(15)).isEqualTo(targetClass); 422 // Enabled 423 assertThat(cursor.getInt(16) == 1).isEqualTo(enabled); 424 // Data ref key 425 assertThat(cursor.getString(17)).isEqualTo("gesture_swipe_down_fingerprint"); 426 // User Id 427 assertThat(cursor.getInt(18)).isEqualTo(userId); 428 // Payload Type - default is 0 429 assertThat(cursor.getInt(19)).isEqualTo(0); 430 // Payload - should be updated to real payloads as controllers are added 431 byte[] payload = cursor.getBlob(20); 432 ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload, 433 ResultPayload.CREATOR); 434 assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); 435 } 436 437 @Test 438 public void testAddResource_checkboxPreference_rowsMatch() { 439 SearchIndexableResource resource = getFakeResource(R.xml.application_settings); 440 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 441 442 /* Should return 6 results, with the following titles: 443 * Advanced Settings, Apps, Manage Apps, Preferred install location, Running Services 444 */ 445 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); 446 cursor.moveToPosition(0); 447 // Locale 448 assertThat(cursor.getString(0)).isEqualTo(localeStr); 449 // Data Rank 450 assertThat(cursor.getInt(1)).isEqualTo(rank); 451 // Data Title 452 assertThat(cursor.getString(2)).isEqualTo("Advanced settings"); 453 // Normalized Title 454 assertThat(cursor.getString(3)).isEqualTo("advanced settings"); 455 // Summary On 456 assertThat(cursor.getString(4)).isEqualTo("Enable more settings options"); 457 // Summary On Normalized 458 assertThat(cursor.getString(5)).isEqualTo("enable more settings options"); 459 // Summary Off 460 assertThat(cursor.getString(6)).isEqualTo("Enable more settings options"); 461 // Summary Off 462 assertThat(cursor.getString(7)).isEqualTo("enable more settings options"); 463 // Entries - only on for list preferences 464 assertThat(cursor.getString(8)).isNull(); 465 // Keywords 466 assertThat(cursor.getString(9)).isEmpty(); 467 // Screen Title 468 assertThat(cursor.getString(10)).isEqualTo("App info"); 469 // Class Name 470 assertThat(cursor.getString(11)).isEqualTo(className); 471 // Icon 472 assertThat(cursor.getInt(12)).isEqualTo(noIcon); 473 // Intent Action 474 assertThat(cursor.getString(13)).isEqualTo(action); 475 // Target Package 476 assertThat(cursor.getString(14)).isEqualTo(targetPackage); 477 // Target Class 478 assertThat(cursor.getString(15)).isEqualTo(targetClass); 479 // Enabled 480 assertThat(cursor.getInt(16) == 1).isEqualTo(enabled); 481 // Data ref key 482 assertThat(cursor.getString(17)).isEqualTo("toggle_advanced_settings"); 483 // User Id 484 assertThat(cursor.getInt(18)).isEqualTo(userId); 485 // Payload Type - default is 0 486 assertThat(cursor.getInt(19)).isEqualTo(0); 487 // Payload - should be updated to real payloads as controllers are added 488 byte[] payload = cursor.getBlob(20); 489 ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload, 490 ResultPayload.CREATOR); 491 assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); 492 } 493 494 @Test 495 public void testAddResource_listPreference_rowsMatch() { 496 SearchIndexableResource resource = getFakeResource(R.xml.application_settings); 497 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 498 499 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); 500 cursor.moveToPosition(3); 501 // Locale 502 assertThat(cursor.getString(0)).isEqualTo(localeStr); 503 // Data Rank 504 assertThat(cursor.getInt(1)).isEqualTo(rank); 505 // Data Title 506 assertThat(cursor.getString(2)).isEqualTo("Preferred install location"); 507 // Normalized Title 508 assertThat(cursor.getString(3)).isEqualTo("preferred install location"); 509 // Summary On 510 assertThat(cursor.getString(4)).isEqualTo( 511 "Change the preferred installation location for new apps"); 512 // Summary On Normalized 513 assertThat(cursor.getString(5)).isEqualTo( 514 "change the preferred installation location for new apps"); 515 // Summary Off - only on for checkbox preferences 516 assertThat(cursor.getString(6)).isEmpty(); 517 // Summary off normalized - only on for checkbox preferences 518 assertThat(cursor.getString(7)).isEmpty(); 519 // Entries - only on for list preferences 520 assertThat(cursor.getString(8)).isEqualTo("Internal device storage|Removable SD card|" + 521 "Let the system decide|"); 522 // Keywords 523 assertThat(cursor.getString(9)).isEmpty(); 524 // Screen Title 525 assertThat(cursor.getString(10)).isEqualTo("App info"); 526 // Class Name 527 assertThat(cursor.getString(11)).isEqualTo(className); 528 // Icon 529 assertThat(cursor.getInt(12)).isEqualTo(noIcon); 530 // Intent Action 531 assertThat(cursor.getString(13)).isEqualTo(action); 532 // Target Package 533 assertThat(cursor.getString(14)).isEqualTo(targetPackage); 534 // Target Class 535 assertThat(cursor.getString(15)).isEqualTo(targetClass); 536 // Enabled 537 assertThat(cursor.getInt(16) == 1).isEqualTo(enabled); 538 // Data ref key 539 assertThat(cursor.getString(17)).isEqualTo("app_install_location"); 540 // User Id 541 assertThat(cursor.getInt(18)).isEqualTo(userId); 542 // Payload Type - default is 0 543 assertThat(cursor.getInt(19)).isEqualTo(0); 544 // Payload - should be updated to real payloads as controllers are added 545 byte[] payload = cursor.getBlob(20); 546 ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload, 547 ResultPayload.CREATOR); 548 assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); 549 } 550 551 @Test 552 public void testAddResource_iconAddedFromXml() { 553 SearchIndexableResource resource = getFakeResource(R.xml.connected_devices); 554 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 555 556 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); 557 cursor.moveToPosition(0); 558 559 // Icon 560 assertThat(cursor.getInt(12)).isNotEqualTo(noIcon); 561 } 562 563 // Tests for the flow: IndexOneResource -> IndexFromProvider -> IndexFromResource -> 564 // UpdateOneRowWithFilteredData -> UpdateOneRow 565 566 @Test 567 public void testResourceProvider_rowInserted() { 568 SearchIndexableResource resource = getFakeResource(R.xml.swipe_to_notification_settings); 569 resource.xmlResId = 0; 570 resource.className = "com.android.settings.display.ScreenZoomSettings"; 571 572 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 573 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); 574 assertThat(cursor.getCount()).isEqualTo(1); 575 } 576 577 @Test 578 public void testResourceProvider_rowMatches() { 579 SearchIndexableResource resource = getFakeResource(R.xml.swipe_to_notification_settings); 580 resource.xmlResId = 0; 581 resource.className = "com.android.settings.display.ScreenZoomSettings"; 582 583 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 584 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); 585 cursor.moveToPosition(0); 586 587 // Locale 588 assertThat(cursor.getString(0)).isEqualTo(localeStr); 589 // Data Rank 590 assertThat(cursor.getInt(1)).isEqualTo(rank); 591 // Data Title 592 assertThat(cursor.getString(2)).isEqualTo("Display size"); 593 // Normalized Title 594 assertThat(cursor.getString(3)).isEqualTo("display size"); 595 // Summary On 596 assertThat(cursor.getString(4)).isEmpty(); 597 // Summary On Normalized 598 assertThat(cursor.getString(5)).isEmpty(); 599 // Summary Off - only on for checkbox preferences 600 assertThat(cursor.getString(6)).isEmpty(); 601 // Summary off normalized - only on for checkbox preferences 602 assertThat(cursor.getString(7)).isEmpty(); 603 // Entries - only on for list preferences 604 assertThat(cursor.getString(8)).isNull(); 605 // Keywords 606 assertThat(cursor.getString(9)).isEqualTo("display density screen zoom scale scaling"); 607 // Screen Title 608 assertThat(cursor.getString(10)).isEqualTo("Display size"); 609 // Class Name 610 assertThat(cursor.getString(11)) 611 .isEqualTo("com.android.settings.display.ScreenZoomSettings"); 612 // Icon 613 assertThat(cursor.getInt(12)).isEqualTo(noIcon); 614 // Intent Action 615 assertThat(cursor.getString(13)).isNull(); 616 // Target Package 617 assertThat(cursor.getString(14)).isNull(); 618 // Target Class 619 assertThat(cursor.getString(15)).isNull(); 620 // Enabled 621 assertThat(cursor.getInt(16) == 1).isEqualTo(enabled); 622 // Data ref key 623 assertThat(cursor.getString(17)).isNull(); 624 // User Id 625 assertThat(cursor.getInt(18)).isEqualTo(userId); 626 // Payload Type - default is 0 627 assertThat(cursor.getInt(19)).isEqualTo(0); 628 // Payload - should be updated to real payloads as controllers are added 629 byte[] payload = cursor.getBlob(20); 630 ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload, 631 ResultPayload.CREATOR); 632 assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); 633 } 634 635 @Test 636 public void testResourceProvider_resourceRowInserted() { 637 SearchIndexableResource resource = getFakeResource(0); 638 resource.className = "com.android.settings.LegalSettings"; 639 640 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 641 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); 642 assertThat(cursor.getCount()).isEqualTo(6); 643 } 644 645 @Test 646 public void testResourceProvider_resourceRowMatches() { 647 SearchIndexableResource resource = getFakeResource(0); 648 resource.className = "com.android.settings.display.ScreenZoomSettings"; 649 650 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, new HashMap<>()); 651 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index ORDER BY data_title", null); 652 cursor.moveToPosition(0); 653 654 // Locale 655 assertThat(cursor.getString(0)).isEqualTo(localeStr); 656 // Data Rank 657 assertThat(cursor.getInt(1)).isEqualTo(rank); 658 // Data Title 659 assertThat(cursor.getString(2)).isEqualTo("Display size"); 660 // Normalized Title 661 assertThat(cursor.getString(3)).isEqualTo("display size"); 662 // Summary On 663 assertThat(cursor.getString(4)).isEmpty(); 664 // Summary On Normalized 665 assertThat(cursor.getString(5)).isEmpty(); 666 // Summary Off - only on for checkbox preferences 667 assertThat(cursor.getString(6)).isEmpty(); 668 // Summary off normalized - only on for checkbox preferences 669 assertThat(cursor.getString(7)).isEmpty(); 670 // Entries - only on for list preferences 671 assertThat(cursor.getString(8)).isNull(); 672 // Keywords 673 assertThat(cursor.getString(9)).isEqualTo( 674 "display density screen zoom scale scaling"); 675 // Screen Title 676 assertThat(cursor.getString(10)).isEqualTo("Display size"); 677 // Class Name 678 assertThat(cursor.getString(11)) 679 .isEqualTo("com.android.settings.display.ScreenZoomSettings"); 680 // Icon 681 assertThat(cursor.getInt(12)).isEqualTo(noIcon); 682 // Intent Action 683 assertThat(cursor.getString(13)).isNull(); 684 // Target Package 685 assertThat(cursor.getString(14)).isNull(); 686 // Target Class 687 assertThat(cursor.getString(15)).isNull(); 688 // Enabled 689 assertThat(cursor.getInt(16) == 1).isEqualTo(enabled); 690 // Data ref key 691 assertThat(cursor.getString(17)).isNull(); 692 // User Id 693 assertThat(cursor.getInt(18)).isEqualTo(userId); 694 // Payload Type - default is 0 695 assertThat(cursor.getInt(19)).isEqualTo(0); 696 // Payload - should be updated to real payloads as controllers are added 697 byte[] payload = cursor.getBlob(20); 698 ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload, 699 ResultPayload.CREATOR); 700 assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); 701 } 702 703 @Test 704 public void testResourceProvider_disabledResource_rowsInserted() { 705 SearchIndexableResource resource = getFakeResource(0); 706 resource.className = "com.android.settings.LegalSettings"; 707 708 mManager.indexOneSearchIndexableData(mDb, localeStr, resource, 709 new HashMap<String, Set<String>>()); 710 711 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null); 712 assertThat(cursor.getCount()).isEqualTo(1); 713 cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null); 714 assertThat(cursor.getCount()).isEqualTo(5); 715 } 716 717 @Test 718 public void testResource_withTitleAndSettingName_titleNotInserted() { 719 SearchIndexableResource resource = getFakeResource(R.xml.swipe_to_notification_settings); 720 mManager.indexFromResource(mDb, localeStr, resource, new ArrayList<String>()); 721 722 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE" + 723 " enabled = 1", null); 724 assertThat(cursor.getCount()).isEqualTo(1); 725 } 726 727 // Test new public indexing flow 728 729 @Test 730 @Config(shadows = {ShadowDatabaseIndexingUtils.class,}) 731 public void testPerformIndexing_fullIndex_getsDataFromProviders() { 732 DummyProvider provider = new DummyProvider(); 733 provider.onCreate(); 734 ShadowContentResolver.registerProvider(AUTHORITY_ONE, provider); 735 736 // Test that Indexables are added for Full indexing 737 when(mPackageManager.queryIntentContentProviders(any(Intent.class), anyInt())) 738 .thenReturn(getDummyResolveInfo()); 739 740 DatabaseIndexingManager manager = 741 spy(new DatabaseIndexingManager(mContext, PACKAGE_ONE)); 742 doReturn(true).when(manager).isFullIndex(anyString(), anyString()); 743 744 manager.performIndexing(); 745 746 verify(manager).addIndexablesFromRemoteProvider(PACKAGE_ONE, AUTHORITY_ONE); 747 verify(manager).updateDatabase(true /* isFullIndex */, Locale.getDefault().toString()); 748 } 749 750 @Test 751 @Config(shadows = {ShadowDatabaseIndexingUtils.class,}) 752 public void testPerformIndexing_incrementalIndex_noDataAdded() { 753 DummyProvider provider = new DummyProvider(); 754 provider.onCreate(); 755 ShadowContentResolver.registerProvider(AUTHORITY_ONE, provider); 756 757 // Test that Indexables are added for Full indexing 758 when(mPackageManager.queryIntentContentProviders(any(Intent.class), anyInt())) 759 .thenReturn(getDummyResolveInfo()); 760 761 DatabaseIndexingManager manager = 762 spy(new DatabaseIndexingManager(mContext, PACKAGE_ONE)); 763 doReturn(false).when(manager).isFullIndex(anyString(), anyString()); 764 765 manager.mDataToProcess.dataToUpdate.clear(); 766 767 manager.performIndexing(); 768 769 verify(manager, times(0)).addDataToDatabase(any(SQLiteDatabase.class), anyString(), 770 anyList(), anyMap()); 771 verify(manager, times(0)).addIndexablesFromRemoteProvider(PACKAGE_ONE, AUTHORITY_ONE); 772 verify(manager).updateDataInDatabase(any(SQLiteDatabase.class), anyMap()); 773 } 774 775 @Test 776 @Config(shadows = {ShadowDatabaseIndexingUtils.class,}) 777 public void testPerformIndexing_localeChanged_databaseDropped() { 778 DummyProvider provider = new DummyProvider(); 779 provider.onCreate(); 780 ShadowContentResolver.registerProvider(AUTHORITY_ONE, provider); 781 782 // Test that Indexables are added for Full indexing 783 when(mPackageManager.queryIntentContentProviders(any(Intent.class), anyInt())) 784 .thenReturn(getDummyResolveInfo()); 785 786 // Initialize the Manager 787 DatabaseIndexingManager manager = 788 spy(new DatabaseIndexingManager(mContext, PACKAGE_ONE)); 789 doReturn(true).when(manager).isFullIndex(anyString(), anyString()); 790 791 // Insert data point which will be dropped 792 final String oldTitle = "This is French"; 793 insertSpecialCase(oldTitle, true, "key"); 794 795 // Add a data point to be added by the indexing 796 SearchIndexableRaw raw = new SearchIndexableRaw(mContext); 797 final String newTitle = "This is English"; 798 raw.title = newTitle; 799 manager.mDataToProcess.dataToUpdate.add(raw); 800 801 manager.performIndexing(); 802 803 // Assert that the New Title is inserted 804 final Cursor newCursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE data_title = '" + 805 newTitle + "'", null); 806 assertThat(newCursor.getCount()).isEqualTo(1); 807 808 // Assert that the Old Title is no longer in the database, since it was dropped 809 final Cursor oldCursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE data_title = '" + 810 oldTitle + "'", null); 811 assertThat(oldCursor.getCount()).isEqualTo(0); 812 } 813 814 @Test 815 @Config(shadows = {ShadowDatabaseIndexingUtils.class,}) 816 public void testPerformIndexing_onOta_FullIndex() { 817 DummyProvider provider = new DummyProvider(); 818 provider.onCreate(); 819 ShadowContentResolver.registerProvider( 820 AUTHORITY_ONE, provider 821 ); 822 823 // Test that Indexables are added for Full indexing 824 when(mPackageManager.queryIntentContentProviders(any(Intent.class), anyInt())) 825 .thenReturn(getDummyResolveInfo()); 826 827 DatabaseIndexingManager manager = 828 spy(new DatabaseIndexingManager(mContext, PACKAGE_ONE)); 829 doReturn(true).when(manager).isFullIndex(anyString(), anyString()); 830 831 manager.performIndexing(); 832 833 verify(manager).updateDatabase(true /* isFullIndex */, Locale.getDefault().toString()); 834 } 835 836 @Test 837 @Config(shadows = {ShadowDatabaseIndexingUtils.class,}) 838 public void testPerformIndexing_onOta_buildNumberIsCached() { 839 DummyProvider provider = new DummyProvider(); 840 provider.onCreate(); 841 ShadowContentResolver.registerProvider( 842 AUTHORITY_ONE, provider 843 ); 844 845 // Test that Indexables are added for Full indexing 846 when(mPackageManager.queryIntentContentProviders(any(Intent.class), anyInt())) 847 .thenReturn(getDummyResolveInfo()); 848 849 DatabaseIndexingManager manager = 850 spy(new DatabaseIndexingManager(mContext, PACKAGE_ONE)); 851 doReturn(true).when(manager).isFullIndex(anyString(), anyString()); 852 853 manager.performIndexing(); 854 855 assertThat(IndexDatabaseHelper.getInstance(mContext).isBuildIndexed(mContext, 856 Build.FINGERPRINT)).isTrue(); 857 } 858 859 @Test 860 public void testFullUpdatedDatabase_noData_addDataToDatabaseNotCalled() { 861 mManager.updateDatabase(true /* isFullIndex */, localeStr); 862 mManager.mDataToProcess.dataToUpdate.clear(); 863 verify(mManager, times(0)).addDataToDatabase(any(SQLiteDatabase.class), anyString(), 864 anyList(), anyMap()); 865 } 866 867 @Test 868 public void testFullUpdatedDatabase_updatedDataInDatabaseNotCalled() { 869 mManager.updateDatabase(true /* isFullIndex */, localeStr); 870 verify(mManager, times(0)).updateDataInDatabase(any(SQLiteDatabase.class), anyMap()); 871 } 872 873 @Test 874 public void testLocaleUpdated_afterIndexing_localeNotAdded() { 875 mManager.updateDatabase(true /* isFullIndex */, localeStr); 876 assertThat(IndexDatabaseHelper.getInstance(mContext) 877 .isLocaleAlreadyIndexed(mContext, localeStr)).isFalse(); 878 } 879 880 @Test 881 public void testLocaleUpdated_afterFullIndexing_localeAdded() { 882 mManager.performIndexing(); 883 assertThat(IndexDatabaseHelper.getInstance(mContext) 884 .isLocaleAlreadyIndexed(mContext, localeStr)).isTrue(); 885 } 886 887 @Test 888 public void testUpdateDatabase_newEligibleData_addedToDatabase() { 889 // Test that addDataToDatabase is called when dataToUpdate is non-empty 890 mManager.mDataToProcess.dataToUpdate.add(getFakeRaw()); 891 mManager.updateDatabase(true /* isFullIndex */, localeStr); 892 893 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index", null); 894 cursor.moveToPosition(0); 895 896 // Locale 897 assertThat(cursor.getString(0)).isEqualTo(localeStr); 898 // Data Rank 899 assertThat(cursor.getInt(1)).isEqualTo(rank); 900 // Data Title 901 assertThat(cursor.getString(2)).isEqualTo(updatedTitle); 902 // Normalized Title 903 assertThat(cursor.getString(3)).isEqualTo(normalizedTitle); 904 // Summary On 905 assertThat(cursor.getString(4)).isEqualTo(updatedSummaryOn); 906 // Summary On Normalized 907 assertThat(cursor.getString(5)).isEqualTo(normalizedSummaryOn); 908 // Summary Off 909 assertThat(cursor.getString(6)).isEqualTo(updatedSummaryOff); 910 // Summary off normalized 911 assertThat(cursor.getString(7)).isEqualTo(normalizedSummaryOff); 912 // Entries 913 assertThat(cursor.getString(8)).isEqualTo(entries); 914 // Keywords 915 assertThat(cursor.getString(9)).isEqualTo(spaceDelimittedKeywords); 916 // Screen Title 917 assertThat(cursor.getString(10)).isEqualTo(screenTitle); 918 // Class Name 919 assertThat(cursor.getString(11)).isEqualTo(className); 920 // Icon 921 assertThat(cursor.getInt(12)).isEqualTo(iconResId); 922 // Intent Action 923 assertThat(cursor.getString(13)).isEqualTo(action); 924 // Target Package 925 assertThat(cursor.getString(14)).isEqualTo(targetPackage); 926 // Target Class 927 assertThat(cursor.getString(15)).isEqualTo(targetClass); 928 // Enabled 929 assertThat(cursor.getInt(16) == 1).isEqualTo(enabled); 930 // Data ref key 931 assertThat(cursor.getString(17)).isNotNull(); 932 // User Id 933 assertThat(cursor.getInt(18)).isEqualTo(userId); 934 // Payload Type - default is 0 935 assertThat(cursor.getInt(19)).isEqualTo(0); 936 // Payload 937 byte[] payload = cursor.getBlob(20); 938 ResultPayload unmarshalledPayload = ResultPayloadUtils.unmarshall(payload, 939 ResultPayload.CREATOR); 940 assertThat(unmarshalledPayload).isInstanceOf(ResultPayload.class); 941 } 942 943 @Test 944 public void testUpdateDataInDatabase_enabledResultsAreNonIndexable_becomeDisabled() { 945 // Both results are enabled, and then TITLE_ONE gets disabled. 946 final boolean enabled = true; 947 insertSpecialCase(TITLE_ONE, enabled, KEY_ONE); 948 insertSpecialCase(TITLE_TWO, enabled, KEY_TWO); 949 Map<String, Set<String>> niks = new ArrayMap<>(); 950 Set<String> keys = new HashSet<>(); 951 keys.add(KEY_ONE); 952 niks.put(targetPackage, keys); 953 954 mManager.updateDataInDatabase(mDb, niks); 955 956 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 0", null); 957 cursor.moveToPosition(0); 958 959 assertThat(cursor.getString(2)).isEqualTo(TITLE_ONE); 960 } 961 962 @Test 963 public void testUpdateDataInDatabase_disabledResultsAreIndexable_becomeEnabled() { 964 // Both results are initially disabled, and then TITLE_TWO gets enabled. 965 final boolean enabled = false; 966 insertSpecialCase(TITLE_ONE, enabled, KEY_ONE); 967 insertSpecialCase(TITLE_TWO, enabled, KEY_TWO); 968 Map<String, Set<String>> niks = new ArrayMap<>(); 969 Set<String> keys = new HashSet<>(); 970 keys.add(KEY_ONE); 971 niks.put(targetPackage, keys); 972 973 mManager.updateDataInDatabase(mDb, niks); 974 975 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null); 976 cursor.moveToPosition(0); 977 978 assertThat(cursor.getString(2)).isEqualTo(TITLE_TWO); 979 } 980 981 @Test 982 @Config(shadows = {ShadowContentResolver.class}) 983 public void testEmptyNonIndexableKeys_emptyDataKeyResources_addedToDatabase() { 984 insertSpecialCase(TITLE_ONE, true /* enabled */, null /* dataReferenceKey */); 985 986 mManager.updateDatabase(false, localeStr); 987 988 Cursor cursor = mDb.rawQuery("SELECT * FROM prefs_index WHERE enabled = 1", null); 989 cursor.moveToPosition(0); 990 assertThat(cursor.getCount()).isEqualTo(1); 991 assertThat(cursor.getString(2)).isEqualTo(TITLE_ONE); 992 } 993 994 @Test 995 public void testUpdateAsyncTask_onPostExecute_performsCallback() { 996 IndexingCallback callback = mock(IndexingCallback.class); 997 998 DatabaseIndexingManager.IndexingTask task = mManager.new IndexingTask(callback); 999 task.execute(); 1000 1001 Robolectric.flushForegroundThreadScheduler(); 1002 1003 verify(callback).onIndexingFinished(); 1004 } 1005 1006 @Test 1007 public void testUpdateAsyncTask_onPostExecute_setsIndexingComplete() { 1008 SearchFeatureProviderImpl provider = new SearchFeatureProviderImpl(); 1009 DatabaseIndexingManager manager = spy(provider.getIndexingManager(mContext)); 1010 DatabaseIndexingManager.IndexingTask task = manager.new IndexingTask(null); 1011 doNothing().when(manager).performIndexing(); 1012 1013 task.execute(); 1014 Robolectric.flushForegroundThreadScheduler(); 1015 1016 assertThat(provider.isIndexingComplete(mContext)).isTrue(); 1017 } 1018 1019 // Util functions 1020 1021 private SearchIndexableRaw getFakeRaw() { 1022 return getFakeRaw(localeStr); 1023 } 1024 1025 private SearchIndexableRaw getFakeRaw(String localeStr) { 1026 SearchIndexableRaw data = new SearchIndexableRaw(mContext); 1027 data.locale = new Locale(localeStr); 1028 data.rank = rank; 1029 data.title = title; 1030 data.summaryOn = summaryOn; 1031 data.summaryOff = summaryOff; 1032 data.entries = entries; 1033 data.keywords = keywords; 1034 data.screenTitle = screenTitle; 1035 data.className = className; 1036 data.packageName = packageName; 1037 data.iconResId = iconResId; 1038 data.intentAction = action; 1039 data.intentTargetPackage = targetPackage; 1040 data.intentTargetClass = targetClass; 1041 data.key = key; 1042 data.userId = userId; 1043 data.enabled = enabled; 1044 return data; 1045 } 1046 1047 private SearchIndexableResource getFakeResource(int xml) { 1048 SearchIndexableResource sir = new SearchIndexableResource(mContext); 1049 sir.rank = rank; 1050 sir.xmlResId = xml; 1051 sir.className = className; 1052 sir.packageName = packageName; 1053 sir.iconResId = iconResId; 1054 sir.intentAction = action; 1055 sir.intentTargetPackage = targetPackage; 1056 sir.intentTargetClass = targetClass; 1057 sir.enabled = enabled; 1058 return sir; 1059 } 1060 1061 private Map<String, Set<String>> getNonIndexableKeys(String[] keys) { 1062 Map<String, Set<String>> niks = new HashMap<>(); 1063 Set<String> keysList = new HashSet<>(); 1064 keysList.addAll(Arrays.asList(keys)); 1065 niks.put(packageName, keysList); 1066 return niks; 1067 } 1068 1069 private List<ResolveInfo> getDummyResolveInfo() { 1070 List<ResolveInfo> infoList = new ArrayList<>(); 1071 ResolveInfo info = new ResolveInfo(); 1072 info.providerInfo = new ProviderInfo(); 1073 info.providerInfo.exported = true; 1074 info.providerInfo.authority = AUTHORITY_ONE; 1075 info.providerInfo.packageName = PACKAGE_ONE; 1076 infoList.add(info); 1077 1078 return infoList; 1079 } 1080 1081 // TODO move this method and its counterpart in CursorToSearchResultConverterTest into 1082 // a util class with public fields to assert values. 1083 private Cursor getDummyCursor() { 1084 MatrixCursor cursor = new MatrixCursor(INDEXABLES_RAW_COLUMNS); 1085 final String BLANK = ""; 1086 1087 ArrayList<String> item = 1088 new ArrayList<>(INDEXABLES_RAW_COLUMNS.length); 1089 item.add("42"); // Rank 1090 item.add(TITLE_ONE); // Title 1091 item.add(BLANK); // Summary on 1092 item.add(BLANK); // summary off 1093 item.add(BLANK); // entries 1094 item.add(BLANK); // keywords 1095 item.add(BLANK); // screen title 1096 item.add(BLANK); // classname 1097 item.add("123"); // Icon 1098 item.add(BLANK); // Intent action 1099 item.add(BLANK); // target package 1100 item.add(BLANK); // target class 1101 item.add(KEY_ONE); // Key 1102 item.add("-1"); // userId 1103 cursor.addRow(item); 1104 1105 return cursor; 1106 } 1107 1108 private void insertSpecialCase(String specialCase, boolean enabled, String key) { 1109 ContentValues values = new ContentValues(); 1110 values.put(IndexDatabaseHelper.IndexColumns.DOCID, specialCase.hashCode()); 1111 values.put(IndexDatabaseHelper.IndexColumns.LOCALE, localeStr); 1112 values.put(IndexDatabaseHelper.IndexColumns.DATA_RANK, 1); 1113 values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE, specialCase); 1114 values.put(IndexDatabaseHelper.IndexColumns.DATA_TITLE_NORMALIZED, ""); 1115 values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON, ""); 1116 values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_ON_NORMALIZED, ""); 1117 values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF, ""); 1118 values.put(IndexDatabaseHelper.IndexColumns.DATA_SUMMARY_OFF_NORMALIZED, ""); 1119 values.put(IndexDatabaseHelper.IndexColumns.DATA_ENTRIES, ""); 1120 values.put(IndexDatabaseHelper.IndexColumns.DATA_KEYWORDS, ""); 1121 values.put(IndexDatabaseHelper.IndexColumns.CLASS_NAME, ""); 1122 values.put(IndexDatabaseHelper.IndexColumns.SCREEN_TITLE, "Moves"); 1123 values.put(IndexDatabaseHelper.IndexColumns.INTENT_ACTION, ""); 1124 values.put(IndexDatabaseHelper.IndexColumns.INTENT_TARGET_PACKAGE, targetPackage); 1125 values.put(IndexDatabaseHelper.IndexColumns.INTENT_TARGET_CLASS, ""); 1126 values.put(IndexDatabaseHelper.IndexColumns.ICON, ""); 1127 values.put(IndexDatabaseHelper.IndexColumns.ENABLED, enabled); 1128 values.put(IndexDatabaseHelper.IndexColumns.DATA_KEY_REF, key); 1129 values.put(IndexDatabaseHelper.IndexColumns.USER_ID, 0); 1130 values.put(IndexDatabaseHelper.IndexColumns.PAYLOAD_TYPE, 0); 1131 values.put(IndexDatabaseHelper.IndexColumns.PAYLOAD, (String) null); 1132 1133 mDb.replaceOrThrow(IndexDatabaseHelper.Tables.TABLE_PREFS_INDEX, null, values); 1134 } 1135 1136 private class DummyProvider extends ContentProvider { 1137 1138 @Override 1139 public boolean onCreate() { 1140 return false; 1141 } 1142 1143 @Override 1144 public Cursor query(@NonNull Uri uri, @Nullable String[] projection, 1145 @Nullable String selection, @Nullable String[] selectionArgs, 1146 @Nullable String sortOrder) { 1147 if (uri.toString().contains("xml")) { 1148 return null; 1149 } 1150 return getDummyCursor(); 1151 } 1152 1153 @Override 1154 public String getType(@NonNull Uri uri) { 1155 return null; 1156 } 1157 1158 @Override 1159 public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { 1160 return null; 1161 } 1162 1163 @Override 1164 public int delete(@NonNull Uri uri, @Nullable String selection, 1165 @Nullable String[] selectionArgs) { 1166 return 0; 1167 } 1168 1169 @Override 1170 public int update(@NonNull Uri uri, @Nullable ContentValues values, 1171 @Nullable String selection, @Nullable String[] selectionArgs) { 1172 return 0; 1173 } 1174 } 1175} 1176