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