1 /* 2 * Copyright (C) 2015 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.providers.settings; 18 19 import static junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertSame; 21 import static junit.framework.Assert.assertNull; 22 import static junit.framework.Assert.fail; 23 24 import android.content.ContentResolver; 25 import android.content.ContentValues; 26 import android.database.ContentObserver; 27 import android.database.Cursor; 28 import android.net.Uri; 29 import android.os.Handler; 30 import android.os.Looper; 31 import android.os.SystemClock; 32 import android.os.UserHandle; 33 import android.provider.Settings; 34 import android.util.Log; 35 import org.junit.Test; 36 37 import java.util.concurrent.atomic.AtomicBoolean; 38 39 /** 40 * Tests for the SettingContentProvider. 41 * 42 * Before you run this test you must add a secondary user. 43 */ 44 public class SettingsProviderTest extends BaseSettingsProviderTest { 45 private static final String LOG_TAG = "SettingsProviderTest"; 46 47 private static final long WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec 48 49 private static final String[] NAME_VALUE_COLUMNS = new String[]{ 50 Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE 51 }; 52 53 private final Object mLock = new Object(); 54 55 @Test 56 public void testSetAndGetGlobalViaFrontEndApiForSystemUser() throws Exception { 57 performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, UserHandle.USER_SYSTEM); 58 } 59 60 @Test 61 public void testSetAndGetGlobalViaFrontEndApiForNonSystemUser() throws Exception { 62 final int secondaryUserId = getSecondaryUserId(); 63 if (secondaryUserId == UserHandle.USER_SYSTEM) { 64 Log.w(LOG_TAG, "No secondary user. Skipping " 65 + "testSetAndGetGlobalViaFrontEndApiForNonSystemUser"); 66 return; 67 } 68 performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, secondaryUserId); 69 } 70 71 @Test 72 public void testSetAndGetSecureViaFrontEndApiForSystemUser() throws Exception { 73 performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, UserHandle.USER_SYSTEM); 74 } 75 76 @Test 77 public void testSetAndGetSecureViaFrontEndApiForNonSystemUser() throws Exception { 78 final int secondaryUserId = getSecondaryUserId(); 79 if (secondaryUserId == UserHandle.USER_SYSTEM) { 80 Log.w(LOG_TAG, "No secondary user. Skipping " 81 + "testSetAndGetSecureViaFrontEndApiForNonSystemUser"); 82 return; 83 } 84 performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, secondaryUserId); 85 } 86 87 @Test 88 public void testSetAndGetSystemViaFrontEndApiForSystemUser() throws Exception { 89 performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, UserHandle.USER_SYSTEM); 90 } 91 92 @Test 93 public void testSetAndGetSystemViaFrontEndApiForNonSystemUser() throws Exception { 94 final int secondaryUserId = getSecondaryUserId(); 95 if (secondaryUserId == UserHandle.USER_SYSTEM) { 96 Log.w(LOG_TAG, "No secondary user. Skipping " 97 + "testSetAndGetSystemViaFrontEndApiForNonSystemUser"); 98 return; 99 } 100 performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, secondaryUserId); 101 } 102 103 @Test 104 public void testSetAndGetGlobalViaProviderApi() throws Exception { 105 performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_GLOBAL); 106 } 107 108 @Test 109 public void testSetAndGetSecureViaProviderApi() throws Exception { 110 performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_SECURE); 111 } 112 113 @Test 114 public void testSetAndGetSystemViaProviderApi() throws Exception { 115 performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_SYSTEM); 116 } 117 118 @Test 119 public void testSelectAllGlobalViaProviderApi() throws Exception { 120 setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_GLOBAL, 121 FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false); 122 try { 123 queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_GLOBAL, 124 FAKE_SETTING_NAME); 125 } finally { 126 deleteStringViaProviderApi(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME); 127 } 128 } 129 130 @Test 131 public void testSelectAllSecureViaProviderApi() throws Exception { 132 setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_SECURE, 133 FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false); 134 try { 135 queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_SECURE, 136 FAKE_SETTING_NAME); 137 } finally { 138 deleteStringViaProviderApi(SETTING_TYPE_SECURE, FAKE_SETTING_NAME); 139 } 140 } 141 142 @Test 143 public void testSelectAllSystemViaProviderApi() throws Exception { 144 setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_SYSTEM, 145 FAKE_SETTING_NAME, FAKE_SETTING_VALUE, true); 146 try { 147 queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_SYSTEM, 148 FAKE_SETTING_NAME); 149 } finally { 150 deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME); 151 } 152 } 153 154 @Test 155 public void testQueryUpdateDeleteGlobalViaProviderApi() throws Exception { 156 doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_GLOBAL); 157 } 158 159 @Test 160 public void testQueryUpdateDeleteSecureViaProviderApi() throws Exception { 161 doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SECURE); 162 } 163 164 @Test 165 public void testQueryUpdateDeleteSystemViaProviderApi() throws Exception { 166 doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SYSTEM); 167 } 168 169 @Test 170 public void testBulkInsertGlobalViaProviderApi() throws Exception { 171 toTestBulkInsertViaProviderApiForType(SETTING_TYPE_GLOBAL); 172 } 173 174 @Test 175 public void testBulkInsertSystemViaProviderApi() throws Exception { 176 toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SYSTEM); 177 } 178 179 @Test 180 public void testBulkInsertSecureViaProviderApi() throws Exception { 181 toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SECURE); 182 } 183 184 @Test 185 public void testAppCannotRunsSystemOutOfMemoryWritingSystemSettings() throws Exception { 186 int insertedCount = 0; 187 try { 188 for (; insertedCount < 1200; insertedCount++) { 189 Log.w(LOG_TAG, "Adding app specific setting: " + insertedCount); 190 insertStringViaProviderApi(SETTING_TYPE_SYSTEM, 191 String.valueOf(insertedCount), FAKE_SETTING_VALUE, false); 192 } 193 fail("Adding app specific settings must be bound."); 194 } catch (Exception e) { 195 // expected 196 } finally { 197 for (; insertedCount >= 0; insertedCount--) { 198 Log.w(LOG_TAG, "Removing app specific setting: " + insertedCount); 199 deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, 200 String.valueOf(insertedCount)); 201 } 202 } 203 } 204 205 @Test 206 public void testQueryStringInBracketsGlobalViaProviderApiForType() throws Exception { 207 doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_GLOBAL); 208 } 209 210 @Test 211 public void testQueryStringInBracketsSecureViaProviderApiForType() throws Exception { 212 doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SECURE); 213 } 214 215 @Test 216 public void testQueryStringInBracketsSystemViaProviderApiForType() throws Exception { 217 doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SYSTEM); 218 } 219 220 @Test 221 public void testQueryStringWithAppendedNameToUriViaProviderApi() throws Exception { 222 // Make sure we have a clean slate. 223 deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME); 224 225 try { 226 // Insert the setting. 227 final Uri uri = insertStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME, 228 FAKE_SETTING_VALUE, false); 229 Uri expectUri = Uri.withAppendedPath(getBaseUriForType(SETTING_TYPE_SYSTEM), 230 FAKE_SETTING_NAME); 231 assertEquals("Did not get expected Uri.", expectUri, uri); 232 233 // Make sure the first setting is there. 234 String firstValue = queryStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME, 235 false, true); 236 assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue); 237 } finally { 238 // Clean up. 239 deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME); 240 } 241 } 242 243 @Test 244 public void testResetModePackageDefaultsGlobal() throws Exception { 245 testResetModePackageDefaultsCommon(SETTING_TYPE_GLOBAL); 246 } 247 248 @Test 249 public void testResetModePackageDefaultsSecure() throws Exception { 250 testResetModePackageDefaultsCommon(SETTING_TYPE_SECURE); 251 } 252 253 private void testResetModePackageDefaultsCommon(int type) throws Exception { 254 // Make sure we have a clean slate. 255 setSettingViaShell(type, FAKE_SETTING_NAME, null, true); 256 try { 257 // Set a value but don't make it the default 258 setSettingViaShell(type, FAKE_SETTING_NAME, 259 FAKE_SETTING_VALUE, false); 260 261 // Reset the changes made by the "shell/root" package 262 resetToDefaultsViaShell(type, "shell"); 263 resetToDefaultsViaShell(type, "root"); 264 265 // Make sure the old APIs don't set defaults 266 assertNull(getSetting(type, FAKE_SETTING_NAME)); 267 268 // Set a value and make it the default 269 setSettingViaShell(type, FAKE_SETTING_NAME, 270 FAKE_SETTING_VALUE, true); 271 // Change the setting from the default 272 setSettingViaShell(type, FAKE_SETTING_NAME, 273 FAKE_SETTING_VALUE_2, false); 274 275 // Reset the changes made by this package 276 resetToDefaultsViaShell(type, "shell"); 277 resetToDefaultsViaShell(type, "root"); 278 279 // Make sure the old APIs don't set defaults 280 assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME)); 281 } finally { 282 // Make sure we have a clean slate. 283 setSettingViaShell(type, FAKE_SETTING_NAME, null, true); 284 } 285 } 286 287 @Test 288 public void testResetModePackageDefaultsWithTokensGlobal() throws Exception { 289 testResetModePackageDefaultsWithTokensCommon(SETTING_TYPE_GLOBAL); 290 } 291 292 @Test 293 public void testResetModePackageDefaultsWithTokensSecure() throws Exception { 294 testResetModePackageDefaultsWithTokensCommon(SETTING_TYPE_SECURE); 295 } 296 297 private void testResetModePackageDefaultsWithTokensCommon(int type) throws Exception { 298 // Make sure we have a clean slate. 299 setSettingViaShell(type, FAKE_SETTING_NAME, null, true); 300 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 301 try { 302 // Set a default value 303 setSettingViaShell(type, FAKE_SETTING_NAME, 304 FAKE_SETTING_VALUE, true); 305 // Change the default and associate a token 306 setSettingViaShell(type, FAKE_SETTING_NAME, 307 FAKE_SETTING_VALUE_2, "TOKEN1", false); 308 309 // Set a default value 310 setSettingViaShell(type, FAKE_SETTING_NAME_1, 311 FAKE_SETTING_VALUE, "TOKEN2", true); 312 // Change the default and associate a token 313 setSettingViaShell(type, FAKE_SETTING_NAME_1, 314 FAKE_SETTING_VALUE_2, "TOKEN2", false); 315 316 // Reset settings associated with TOKEN1 317 resetToDefaultsViaShell(type, "shell", "TOKEN1"); 318 resetToDefaultsViaShell(type, "root", "TOKEN1"); 319 320 // Make sure TOKEN1 settings are reset 321 assertEquals(FAKE_SETTING_VALUE, getSetting(type, 322 FAKE_SETTING_NAME)); 323 324 // Make sure TOKEN2 settings are not reset 325 assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, 326 FAKE_SETTING_NAME_1)); 327 328 // Reset settings associated with TOKEN2 329 resetToDefaultsViaShell(type, "shell", "TOKEN2"); 330 resetToDefaultsViaShell(type, "root", "TOKEN2"); 331 332 // Make sure TOKEN2 settings are reset 333 assertEquals(FAKE_SETTING_VALUE, getSetting(type, 334 FAKE_SETTING_NAME_1)); 335 } finally { 336 // Make sure we have a clean slate. 337 setSettingViaShell(type, FAKE_SETTING_NAME, null, true); 338 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 339 } 340 } 341 342 @Test 343 public void testResetModeUntrustedDefaultsGlobal() throws Exception { 344 testResetModeUntrustedDefaultsCommon(SETTING_TYPE_GLOBAL); 345 } 346 347 @Test 348 public void testResetModeUntrustedDefaultsSecure() throws Exception { 349 testResetModeUntrustedDefaultsCommon(SETTING_TYPE_SECURE); 350 } 351 352 private void testResetModeUntrustedDefaultsCommon(int type) throws Exception { 353 // Make sure we have a clean slate. 354 putSetting(type, FAKE_SETTING_NAME, null); 355 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 356 try { 357 // Set a default setting as a trusted component 358 putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE); 359 // Change the setting as a trusted component 360 putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2); 361 362 // Set a default setting as an untrusted component 363 setSettingViaShell(type, FAKE_SETTING_NAME_1, 364 FAKE_SETTING_VALUE, true); 365 // Change the setting as an untrusted component 366 setSettingViaShell(type, FAKE_SETTING_NAME_1, 367 FAKE_SETTING_VALUE_2, false); 368 369 // Reset the untrusted changes to defaults 370 resetSettingsViaShell(type, 371 Settings.RESET_MODE_UNTRUSTED_DEFAULTS); 372 373 // Check whether only the untrusted changes set to defaults 374 assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, FAKE_SETTING_NAME)); 375 assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME_1)); 376 } finally { 377 // Make sure we have a clean slate. 378 putSetting(type, FAKE_SETTING_NAME, null); 379 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 380 } 381 } 382 383 @Test 384 public void testResetModeUntrustedClearGlobal() throws Exception { 385 testResetModeUntrustedClearCommon(SETTING_TYPE_GLOBAL); 386 } 387 388 @Test 389 public void testResetModeUntrustedClearSecure() throws Exception { 390 testResetModeUntrustedClearCommon(SETTING_TYPE_SECURE); 391 } 392 393 private void testResetModeUntrustedClearCommon(int type) throws Exception { 394 // Make sure we have a clean slate. 395 putSetting(type, FAKE_SETTING_NAME, null); 396 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 397 try { 398 // Set a default setting as a trusted component 399 putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE); 400 // Change the setting as a trusted component 401 putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2); 402 403 // Set a default setting as an untrusted component 404 setSettingViaShell(type, FAKE_SETTING_NAME_1, 405 FAKE_SETTING_VALUE, true); 406 // Change the setting as an untrusted component 407 setSettingViaShell(type, FAKE_SETTING_NAME_1, 408 FAKE_SETTING_VALUE_2, false); 409 410 // Clear the untrusted changes 411 resetSettingsViaShell(type, 412 Settings.RESET_MODE_UNTRUSTED_CHANGES); 413 414 // Check whether only the untrusted changes set to defaults 415 assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, FAKE_SETTING_NAME)); 416 assertNull(getSetting(type, FAKE_SETTING_NAME_1)); 417 } finally { 418 // Make sure we have a clean slate. 419 putSetting(type, FAKE_SETTING_NAME, null); 420 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 421 } 422 } 423 424 @Test 425 public void testResetModeTrustedDefaultsGlobal() throws Exception { 426 testResetModeTrustedDefaultsCommon(SETTING_TYPE_GLOBAL); 427 } 428 429 @Test 430 public void testResetModeTrustedDefaultsSecure() throws Exception { 431 testResetModeTrustedDefaultsCommon(SETTING_TYPE_SECURE); 432 } 433 434 private void testResetModeTrustedDefaultsCommon(int type) throws Exception { 435 // Make sure we have a clean slate. 436 putSetting(type, FAKE_SETTING_NAME, null); 437 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 438 try { 439 // Set a default setting as a trusted component 440 putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE); 441 // Change the setting as a trusted component 442 setSettingViaShell(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2, false); 443 444 // Set a default setting as an untrusted component 445 setSettingViaShell(type, FAKE_SETTING_NAME_1, 446 FAKE_SETTING_VALUE, true); 447 // Change the setting as an untrusted component 448 setSettingViaShell(type, FAKE_SETTING_NAME_1, 449 FAKE_SETTING_VALUE_2, false); 450 451 // Reset to trusted defaults 452 resetSettingsViaShell(type, 453 Settings.RESET_MODE_TRUSTED_DEFAULTS); 454 455 // Check whether snapped to trusted defaults 456 assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME)); 457 assertNull(getSetting(type, FAKE_SETTING_NAME_1)); 458 } finally { 459 // Make sure we have a clean slate. 460 putSetting(type, FAKE_SETTING_NAME, null); 461 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 462 } 463 } 464 465 private void doTestQueryStringInBracketsViaProviderApiForType(int type) { 466 // Make sure we have a clean slate. 467 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 468 469 try { 470 // Insert the setting. 471 final Uri uri = insertStringViaProviderApi(type, FAKE_SETTING_NAME, 472 FAKE_SETTING_VALUE, false); 473 Uri expectUri = Uri.withAppendedPath(getBaseUriForType(type), FAKE_SETTING_NAME); 474 assertEquals("Did not get expected Uri.", expectUri, uri); 475 476 // Make sure the first setting is there. 477 String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME, true, false); 478 assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue); 479 } finally { 480 // Clean up. 481 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 482 } 483 } 484 485 private void toTestBulkInsertViaProviderApiForType(int type) { 486 // Make sure we have a clean slate. 487 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 488 deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1); 489 deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2); 490 491 try { 492 Uri uri = getBaseUriForType(type); 493 ContentValues[] allValues = new ContentValues[3]; 494 495 // Insert the first setting. 496 ContentValues firstValues = new ContentValues(); 497 firstValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME); 498 firstValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE); 499 allValues[0] = firstValues; 500 501 // Insert the second setting. 502 ContentValues secondValues = new ContentValues(); 503 secondValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_1); 504 secondValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_1); 505 allValues[1] = secondValues; 506 507 // Insert the third setting. (null) 508 ContentValues thirdValues = new ContentValues(); 509 thirdValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_2); 510 thirdValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_2); 511 allValues[2] = thirdValues; 512 513 // Verify insertion count. 514 final int insertCount = getContext().getContentResolver().bulkInsert(uri, allValues); 515 assertSame("Couldn't insert both values", 3, insertCount); 516 517 // Make sure the first setting is there. 518 String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 519 assertEquals("First setting must be present", FAKE_SETTING_VALUE, firstValue); 520 521 // Make sure the second setting is there. 522 String secondValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_1); 523 assertEquals("Second setting must be present", FAKE_SETTING_VALUE_1, secondValue); 524 525 // Make sure the third setting is there. 526 String thirdValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_2); 527 assertEquals("Third setting must be present", FAKE_SETTING_VALUE_2, thirdValue); 528 } finally { 529 // Clean up. 530 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 531 deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1); 532 deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2); 533 } 534 } 535 536 private void doTestQueryUpdateDeleteGlobalViaProviderApiForType(int type) throws Exception { 537 // Make sure it is not there. 538 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 539 540 // Now selection should return nothing. 541 String value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 542 assertNull("Setting should not be present.", value); 543 544 // Insert the setting. 545 Uri uri = insertStringViaProviderApi(type, 546 FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false); 547 Uri expectUri = Uri.withAppendedPath(getBaseUriForType(type), FAKE_SETTING_NAME); 548 assertEquals("Did not get expected Uri.", expectUri, uri); 549 550 // Now selection should return the setting. 551 value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 552 assertEquals("Setting should be present.", FAKE_SETTING_VALUE, value); 553 554 // Update the setting. 555 final int changeCount = updateStringViaProviderApiSetting(type, 556 FAKE_SETTING_NAME, FAKE_SETTING_VALUE_1); 557 assertEquals("Did not get expected change count.", 1, changeCount); 558 559 // Now selection should return the new setting. 560 value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 561 assertEquals("Setting should be present.", FAKE_SETTING_VALUE_1, value); 562 563 // Delete the setting. 564 final int deletedCount = deleteStringViaProviderApi(type, 565 FAKE_SETTING_NAME); 566 assertEquals("Did not get expected deleted count", 1, deletedCount); 567 568 // Now selection should return nothing. 569 value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 570 assertNull("Setting should not be present.", value); 571 } 572 573 private void performSetAndGetSettingTestViaFrontEndApi(int type, int userId) 574 throws Exception { 575 try { 576 // Change the setting and assert a successful change. 577 setSettingViaFrontEndApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, 578 FAKE_SETTING_VALUE, userId); 579 } finally { 580 // Remove the setting. 581 setStringViaFrontEndApiSetting(type, FAKE_SETTING_NAME, null, userId); 582 } 583 } 584 585 private void performSetAndGetSettingTestViaProviderApi(int type) 586 throws Exception { 587 try { 588 // Change the setting and assert a successful change. 589 setSettingViaProviderApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, 590 FAKE_SETTING_VALUE, true); 591 } finally { 592 // Remove the setting. 593 setSettingViaProviderApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, null, 594 true); 595 } 596 } 597 598 private void setSettingViaFrontEndApiAndAssertSuccessfulChange(final int type, 599 final String name, final String value, final int userId) throws Exception { 600 setSettingAndAssertSuccessfulChange(() -> { 601 setStringViaFrontEndApiSetting(type, name, value, userId); 602 }, type, name, value, userId); 603 } 604 605 private void setSettingViaProviderApiAndAssertSuccessfulChange(final int type, 606 final String name, final String value, final boolean withTableRowUri) 607 throws Exception { 608 setSettingAndAssertSuccessfulChange(() -> { 609 insertStringViaProviderApi(type, name, value, withTableRowUri); 610 }, type, name, value, UserHandle.USER_SYSTEM); 611 } 612 613 private void setSettingAndAssertSuccessfulChange(Runnable setCommand, final int type, 614 final String name, final String value, final int userId) throws Exception { 615 ContentResolver contentResolver = getContext().getContentResolver(); 616 617 final Uri settingUri = getBaseUriForType(type); 618 619 final AtomicBoolean success = new AtomicBoolean(); 620 621 ContentObserver contentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { 622 public void onChange(boolean selfChange, Uri changeUri, int changeId) { 623 Log.i(LOG_TAG, "onChange(" + selfChange + ", " + changeUri + ", " + changeId + ")"); 624 assertEquals("Wrong change Uri", changeUri, settingUri); 625 assertEquals("Wrong user id", userId, changeId); 626 String changeValue = getStringViaFrontEndApiSetting(type, name, userId); 627 assertEquals("Wrong setting value", value, changeValue); 628 629 success.set(true); 630 631 synchronized (mLock) { 632 mLock.notifyAll(); 633 } 634 } 635 }; 636 637 contentResolver.registerContentObserver(settingUri, false, contentObserver, userId); 638 639 try { 640 setCommand.run(); 641 642 final long startTimeMillis = SystemClock.uptimeMillis(); 643 synchronized (mLock) { 644 if (success.get()) { 645 return; 646 } 647 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; 648 if (elapsedTimeMillis > WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS) { 649 fail("Could not change setting for " 650 + WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS + " ms"); 651 } 652 final long remainingTimeMillis = WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS 653 - elapsedTimeMillis; 654 try { 655 mLock.wait(remainingTimeMillis); 656 } catch (InterruptedException ie) { 657 /* ignore */ 658 } 659 } 660 } finally { 661 contentResolver.unregisterContentObserver(contentObserver); 662 } 663 } 664 665 private void queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(int type, 666 String name) { 667 Uri uri = getBaseUriForType(type); 668 669 Cursor cursor = getContext().getContentResolver().query(uri, NAME_VALUE_COLUMNS, 670 null, null, null); 671 672 if (cursor == null || !cursor.moveToFirst()) { 673 fail("Nothing selected"); 674 } 675 676 try { 677 final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME); 678 679 while (cursor.moveToNext()) { 680 String currentName = cursor.getString(nameColumnIdx); 681 if (name.equals(currentName)) { 682 return; 683 } 684 } 685 686 fail("Not found setting: " + name); 687 } finally { 688 cursor.close(); 689 } 690 } 691 } 692