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