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