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 @Test testSelectAllSecureViaProviderApi()132 public void testSelectAllSecureViaProviderApi() throws Exception { 133 setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_SECURE, 134 FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false); 135 try { 136 queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_SECURE, 137 FAKE_SETTING_NAME); 138 } finally { 139 deleteStringViaProviderApi(SETTING_TYPE_SECURE, FAKE_SETTING_NAME); 140 } 141 } 142 143 @Test testSelectAllSystemViaProviderApi()144 public void testSelectAllSystemViaProviderApi() throws Exception { 145 setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_SYSTEM, 146 FAKE_SETTING_NAME, FAKE_SETTING_VALUE, true); 147 try { 148 queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_SYSTEM, 149 FAKE_SETTING_NAME); 150 } finally { 151 deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME); 152 } 153 } 154 155 @Test testQueryUpdateDeleteGlobalViaProviderApi()156 public void testQueryUpdateDeleteGlobalViaProviderApi() throws Exception { 157 doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_GLOBAL); 158 } 159 160 @Test testQueryUpdateDeleteSecureViaProviderApi()161 public void testQueryUpdateDeleteSecureViaProviderApi() throws Exception { 162 doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SECURE); 163 } 164 165 @Test testQueryUpdateDeleteSystemViaProviderApi()166 public void testQueryUpdateDeleteSystemViaProviderApi() throws Exception { 167 doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SYSTEM); 168 } 169 170 @Test testBulkInsertGlobalViaProviderApi()171 public void testBulkInsertGlobalViaProviderApi() throws Exception { 172 toTestBulkInsertViaProviderApiForType(SETTING_TYPE_GLOBAL); 173 } 174 175 @Test testBulkInsertSystemViaProviderApi()176 public void testBulkInsertSystemViaProviderApi() throws Exception { 177 toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SYSTEM); 178 } 179 180 @Test testBulkInsertSecureViaProviderApi()181 public void testBulkInsertSecureViaProviderApi() throws Exception { 182 toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SECURE); 183 } 184 185 @Test testAppCannotRunsSystemOutOfMemoryWritingSystemSettings()186 public void testAppCannotRunsSystemOutOfMemoryWritingSystemSettings() throws Exception { 187 int insertedCount = 0; 188 try { 189 for (; insertedCount < 1200; insertedCount++) { 190 Log.w(LOG_TAG, "Adding app specific setting: " + 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 Log.w(LOG_TAG, "Removing app specific setting: " + insertedCount); 200 deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, 201 String.valueOf(insertedCount)); 202 } 203 } 204 } 205 206 @Test testQueryStringInBracketsGlobalViaProviderApiForType()207 public void testQueryStringInBracketsGlobalViaProviderApiForType() throws Exception { 208 doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_GLOBAL); 209 } 210 211 @Test testQueryStringInBracketsSecureViaProviderApiForType()212 public void testQueryStringInBracketsSecureViaProviderApiForType() throws Exception { 213 doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SECURE); 214 } 215 216 @Test testQueryStringInBracketsSystemViaProviderApiForType()217 public void testQueryStringInBracketsSystemViaProviderApiForType() throws Exception { 218 doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SYSTEM); 219 } 220 221 @Test testQueryStringWithAppendedNameToUriViaProviderApi()222 public void testQueryStringWithAppendedNameToUriViaProviderApi() throws Exception { 223 // Make sure we have a clean slate. 224 deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME); 225 226 try { 227 // Insert the setting. 228 final Uri uri = insertStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME, 229 FAKE_SETTING_VALUE, false); 230 Uri expectUri = Uri.withAppendedPath(getBaseUriForType(SETTING_TYPE_SYSTEM), 231 FAKE_SETTING_NAME); 232 assertEquals("Did not get expected Uri.", expectUri, uri); 233 234 // Make sure the first setting is there. 235 String firstValue = queryStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME, 236 false, true); 237 assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue); 238 } finally { 239 // Clean up. 240 deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME); 241 } 242 } 243 244 @Test testResetModePackageDefaultsGlobal()245 public void testResetModePackageDefaultsGlobal() throws Exception { 246 testResetModePackageDefaultsCommon(SETTING_TYPE_GLOBAL); 247 } 248 249 @Test testResetModePackageDefaultsSecure()250 public void testResetModePackageDefaultsSecure() throws Exception { 251 testResetModePackageDefaultsCommon(SETTING_TYPE_SECURE); 252 } 253 testResetModePackageDefaultsCommon(int type)254 private void testResetModePackageDefaultsCommon(int type) throws Exception { 255 // Make sure we have a clean slate. 256 setSettingViaShell(type, FAKE_SETTING_NAME, null, true); 257 try { 258 // Set a value but don't make it the default 259 setSettingViaShell(type, FAKE_SETTING_NAME, 260 FAKE_SETTING_VALUE, false); 261 262 // Reset the changes made by the "shell/root" package 263 resetToDefaultsViaShell(type, "com.android.shell"); 264 resetToDefaultsViaShell(type, "root"); 265 266 // Make sure the old APIs don't set defaults 267 assertNull(getSetting(type, FAKE_SETTING_NAME)); 268 269 // Set a value and make it the default 270 setSettingViaShell(type, FAKE_SETTING_NAME, 271 FAKE_SETTING_VALUE, true); 272 // Change the setting from the default 273 setSettingViaShell(type, FAKE_SETTING_NAME, 274 FAKE_SETTING_VALUE_2, false); 275 276 // Reset the changes made by this package 277 resetToDefaultsViaShell(type, "com.android.shell"); 278 resetToDefaultsViaShell(type, "root"); 279 280 // Make sure the old APIs don't set defaults 281 assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME)); 282 } finally { 283 // Make sure we have a clean slate. 284 setSettingViaShell(type, FAKE_SETTING_NAME, null, true); 285 } 286 } 287 288 @Test testResetModePackageDefaultsWithTokensGlobal()289 public void testResetModePackageDefaultsWithTokensGlobal() throws Exception { 290 testResetModePackageDefaultsWithTokensCommon(SETTING_TYPE_GLOBAL); 291 } 292 293 @Test testResetModePackageDefaultsWithTokensSecure()294 public void testResetModePackageDefaultsWithTokensSecure() throws Exception { 295 testResetModePackageDefaultsWithTokensCommon(SETTING_TYPE_SECURE); 296 } 297 testResetModePackageDefaultsWithTokensCommon(int type)298 private void testResetModePackageDefaultsWithTokensCommon(int type) throws Exception { 299 // Make sure we have a clean slate. 300 setSettingViaShell(type, FAKE_SETTING_NAME, null, true); 301 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 302 try { 303 // Set a default value 304 setSettingViaShell(type, FAKE_SETTING_NAME, 305 FAKE_SETTING_VALUE, true); 306 // Change the default and associate a token 307 setSettingViaShell(type, FAKE_SETTING_NAME, 308 FAKE_SETTING_VALUE_2, "TOKEN1", false); 309 310 // Set a default value 311 setSettingViaShell(type, FAKE_SETTING_NAME_1, 312 FAKE_SETTING_VALUE, "TOKEN2", true); 313 // Change the default and associate a token 314 setSettingViaShell(type, FAKE_SETTING_NAME_1, 315 FAKE_SETTING_VALUE_2, "TOKEN2", false); 316 317 // Reset settings associated with TOKEN1 318 resetToDefaultsViaShell(type, "com.android.shell", "TOKEN1"); 319 resetToDefaultsViaShell(type, "root", "TOKEN1"); 320 321 // Make sure TOKEN1 settings are reset 322 assertEquals(FAKE_SETTING_VALUE, getSetting(type, 323 FAKE_SETTING_NAME)); 324 325 // Make sure TOKEN2 settings are not reset 326 assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, 327 FAKE_SETTING_NAME_1)); 328 329 // Reset settings associated with TOKEN2 330 resetToDefaultsViaShell(type, "com.android.shell", "TOKEN2"); 331 resetToDefaultsViaShell(type, "root", "TOKEN2"); 332 333 // Make sure TOKEN2 settings are reset 334 assertEquals(FAKE_SETTING_VALUE, getSetting(type, 335 FAKE_SETTING_NAME_1)); 336 } finally { 337 // Make sure we have a clean slate. 338 setSettingViaShell(type, FAKE_SETTING_NAME, null, true); 339 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 340 } 341 } 342 343 @Test testResetModeUntrustedDefaultsGlobal()344 public void testResetModeUntrustedDefaultsGlobal() throws Exception { 345 testResetModeUntrustedDefaultsCommon(SETTING_TYPE_GLOBAL); 346 } 347 348 @Test testResetModeUntrustedDefaultsSecure()349 public void testResetModeUntrustedDefaultsSecure() throws Exception { 350 testResetModeUntrustedDefaultsCommon(SETTING_TYPE_SECURE); 351 } 352 testResetModeUntrustedDefaultsCommon(int type)353 private void testResetModeUntrustedDefaultsCommon(int type) throws Exception { 354 // Make sure we have a clean slate. 355 putSetting(type, FAKE_SETTING_NAME, null); 356 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 357 try { 358 // Set a default setting as a trusted component 359 putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE); 360 // Change the setting as a trusted component 361 putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2); 362 363 // Set a default setting as an untrusted component 364 setSettingViaShell(type, FAKE_SETTING_NAME_1, 365 FAKE_SETTING_VALUE, true); 366 // Change the setting as an untrusted component 367 setSettingViaShell(type, FAKE_SETTING_NAME_1, 368 FAKE_SETTING_VALUE_2, false); 369 370 // Reset the untrusted changes to defaults 371 resetSettingsViaShell(type, 372 Settings.RESET_MODE_UNTRUSTED_DEFAULTS); 373 374 // Check whether only the untrusted changes set to defaults 375 assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, FAKE_SETTING_NAME)); 376 assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME_1)); 377 } finally { 378 // Make sure we have a clean slate. 379 putSetting(type, FAKE_SETTING_NAME, null); 380 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 381 } 382 } 383 384 @Test testResetModeUntrustedClearGlobal()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 @Test testResetModeTrustedDefaultsGlobal()426 public void testResetModeTrustedDefaultsGlobal() throws Exception { 427 testResetModeTrustedDefaultsCommon(SETTING_TYPE_GLOBAL); 428 } 429 430 @Test testResetModeTrustedDefaultsSecure()431 public void testResetModeTrustedDefaultsSecure() throws Exception { 432 testResetModeTrustedDefaultsCommon(SETTING_TYPE_SECURE); 433 } 434 testResetModeTrustedDefaultsCommon(int type)435 private void testResetModeTrustedDefaultsCommon(int type) throws Exception { 436 // Make sure we have a clean slate. 437 putSetting(type, FAKE_SETTING_NAME, null); 438 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 439 try { 440 // Set a default setting as a trusted component 441 putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE); 442 // Change the setting as a trusted component 443 setSettingViaShell(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2, false); 444 445 // Set a default setting as an untrusted component 446 setSettingViaShell(type, FAKE_SETTING_NAME_1, 447 FAKE_SETTING_VALUE, true); 448 // Change the setting as an untrusted component 449 setSettingViaShell(type, FAKE_SETTING_NAME_1, 450 FAKE_SETTING_VALUE_2, false); 451 452 // Reset to trusted defaults 453 resetSettingsViaShell(type, 454 Settings.RESET_MODE_TRUSTED_DEFAULTS); 455 456 // Check whether snapped to trusted defaults 457 assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME)); 458 assertNull(getSetting(type, FAKE_SETTING_NAME_1)); 459 } finally { 460 // Make sure we have a clean slate. 461 putSetting(type, FAKE_SETTING_NAME, null); 462 setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); 463 } 464 } 465 doTestQueryStringInBracketsViaProviderApiForType(int type)466 private void doTestQueryStringInBracketsViaProviderApiForType(int type) { 467 // Make sure we have a clean slate. 468 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 469 470 try { 471 // Insert the setting. 472 final Uri uri = insertStringViaProviderApi(type, FAKE_SETTING_NAME, 473 FAKE_SETTING_VALUE, false); 474 Uri expectUri = Uri.withAppendedPath(getBaseUriForType(type), FAKE_SETTING_NAME); 475 assertEquals("Did not get expected Uri.", expectUri, uri); 476 477 // Make sure the first setting is there. 478 String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME, true, false); 479 assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue); 480 } finally { 481 // Clean up. 482 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 483 } 484 } 485 toTestBulkInsertViaProviderApiForType(int type)486 private void toTestBulkInsertViaProviderApiForType(int type) { 487 // Make sure we have a clean slate. 488 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 489 deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1); 490 deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2); 491 492 try { 493 Uri uri = getBaseUriForType(type); 494 ContentValues[] allValues = new ContentValues[3]; 495 496 // Insert the first setting. 497 ContentValues firstValues = new ContentValues(); 498 firstValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME); 499 firstValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE); 500 allValues[0] = firstValues; 501 502 // Insert the second setting. 503 ContentValues secondValues = new ContentValues(); 504 secondValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_1); 505 secondValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_1); 506 allValues[1] = secondValues; 507 508 // Insert the third setting. (null) 509 ContentValues thirdValues = new ContentValues(); 510 thirdValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_2); 511 thirdValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_2); 512 allValues[2] = thirdValues; 513 514 // Verify insertion count. 515 final int insertCount = getContext().getContentResolver().bulkInsert(uri, allValues); 516 assertSame("Couldn't insert both values", 3, insertCount); 517 518 // Make sure the first setting is there. 519 String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 520 assertEquals("First setting must be present", FAKE_SETTING_VALUE, firstValue); 521 522 // Make sure the second setting is there. 523 String secondValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_1); 524 assertEquals("Second setting must be present", FAKE_SETTING_VALUE_1, secondValue); 525 526 // Make sure the third setting is there. 527 String thirdValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_2); 528 assertEquals("Third setting must be present", FAKE_SETTING_VALUE_2, thirdValue); 529 } finally { 530 // Clean up. 531 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 532 deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1); 533 deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2); 534 } 535 } 536 doTestQueryUpdateDeleteGlobalViaProviderApiForType(int type)537 private void doTestQueryUpdateDeleteGlobalViaProviderApiForType(int type) throws Exception { 538 // Make sure it is not there. 539 deleteStringViaProviderApi(type, FAKE_SETTING_NAME); 540 541 // Now selection should return nothing. 542 String value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 543 assertNull("Setting should not be present.", value); 544 545 // Insert the setting. 546 Uri uri = insertStringViaProviderApi(type, 547 FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false); 548 Uri expectUri = Uri.withAppendedPath(getBaseUriForType(type), FAKE_SETTING_NAME); 549 assertEquals("Did not get expected Uri.", expectUri, uri); 550 551 // Now selection should return the setting. 552 value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 553 assertEquals("Setting should be present.", FAKE_SETTING_VALUE, value); 554 555 // Update the setting. 556 final int changeCount = updateStringViaProviderApiSetting(type, 557 FAKE_SETTING_NAME, FAKE_SETTING_VALUE_1); 558 assertEquals("Did not get expected change count.", 1, changeCount); 559 560 // Now selection should return the new setting. 561 value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 562 assertEquals("Setting should be present.", FAKE_SETTING_VALUE_1, value); 563 564 // Delete the setting. 565 final int deletedCount = deleteStringViaProviderApi(type, 566 FAKE_SETTING_NAME); 567 assertEquals("Did not get expected deleted count", 1, deletedCount); 568 569 // Now selection should return nothing. 570 value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); 571 assertNull("Setting should not be present.", value); 572 } 573 performSetAndGetSettingTestViaFrontEndApi(int type, int userId)574 private void performSetAndGetSettingTestViaFrontEndApi(int type, int userId) 575 throws Exception { 576 try { 577 // Change the setting and assert a successful change. 578 setSettingViaFrontEndApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, 579 FAKE_SETTING_VALUE, userId); 580 } finally { 581 // Remove the setting. 582 setStringViaFrontEndApiSetting(type, FAKE_SETTING_NAME, null, userId); 583 } 584 } 585 performSetAndGetSettingTestViaProviderApi(int type)586 private void performSetAndGetSettingTestViaProviderApi(int type) 587 throws Exception { 588 try { 589 // Change the setting and assert a successful change. 590 setSettingViaProviderApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, 591 FAKE_SETTING_VALUE, true); 592 } finally { 593 // Remove the setting. 594 setSettingViaProviderApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, null, 595 true); 596 } 597 } 598 setSettingViaFrontEndApiAndAssertSuccessfulChange(final int type, final String name, final String value, final int userId)599 private void setSettingViaFrontEndApiAndAssertSuccessfulChange(final int type, 600 final String name, final String value, final int userId) throws Exception { 601 setSettingAndAssertSuccessfulChange(() -> { 602 setStringViaFrontEndApiSetting(type, name, value, userId); 603 }, type, name, value, userId); 604 } 605 setSettingViaProviderApiAndAssertSuccessfulChange(final int type, final String name, final String value, final boolean withTableRowUri)606 private void setSettingViaProviderApiAndAssertSuccessfulChange(final int type, 607 final String name, final String value, final boolean withTableRowUri) 608 throws Exception { 609 setSettingAndAssertSuccessfulChange(() -> { 610 insertStringViaProviderApi(type, name, value, withTableRowUri); 611 }, type, name, value, UserHandle.USER_SYSTEM); 612 } 613 setSettingAndAssertSuccessfulChange(Runnable setCommand, final int type, final String name, final String value, final int userId)614 private void setSettingAndAssertSuccessfulChange(Runnable setCommand, final int type, 615 final String name, final String value, final int userId) throws Exception { 616 ContentResolver contentResolver = getContext().getContentResolver(); 617 618 final Uri settingUri = getBaseUriForType(type).buildUpon().appendPath(name).build(); 619 620 final AtomicBoolean success = new AtomicBoolean(); 621 622 ContentObserver contentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { 623 public void onChange(boolean selfChange, Uri changeUri, int changeId) { 624 Log.i(LOG_TAG, "onChange(" + selfChange + ", " + changeUri + ", " + changeId + ")"); 625 assertEquals("Wrong change Uri", changeUri, settingUri); 626 assertEquals("Wrong user id", userId, changeId); 627 String changeValue = getStringViaFrontEndApiSetting(type, name, userId); 628 assertEquals("Wrong setting value", value, changeValue); 629 630 success.set(true); 631 632 synchronized (mLock) { 633 mLock.notifyAll(); 634 } 635 } 636 }; 637 638 contentResolver.registerContentObserver(settingUri, false, contentObserver, userId); 639 640 try { 641 setCommand.run(); 642 643 final long startTimeMillis = SystemClock.uptimeMillis(); 644 synchronized (mLock) { 645 while (true) { 646 if (success.get()) { 647 return; 648 } 649 final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; 650 if (elapsedTimeMillis >= WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS) { 651 fail("Could not change setting for " 652 + WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS + " ms"); 653 } 654 final long remainingTimeMillis = WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS 655 - elapsedTimeMillis; 656 try { 657 mLock.wait(remainingTimeMillis); 658 } catch (InterruptedException ie) { 659 /* ignore */ 660 } 661 } 662 } 663 } finally { 664 contentResolver.unregisterContentObserver(contentObserver); 665 } 666 } 667 queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(int type, String name)668 private void queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(int type, 669 String name) { 670 Uri uri = getBaseUriForType(type); 671 672 Cursor cursor = getContext().getContentResolver().query(uri, NAME_VALUE_COLUMNS, 673 null, null, null); 674 675 if (cursor == null || !cursor.moveToFirst()) { 676 fail("Nothing selected"); 677 } 678 679 try { 680 final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME); 681 682 while (cursor.moveToNext()) { 683 String currentName = cursor.getString(nameColumnIdx); 684 if (name.equals(currentName)) { 685 return; 686 } 687 } 688 689 fail("Not found setting: " + name); 690 } finally { 691 cursor.close(); 692 } 693 } 694 695 @Test testLocationModeChanges_viaFrontEndApi()696 public void testLocationModeChanges_viaFrontEndApi() throws Exception { 697 setStringViaFrontEndApiSetting( 698 SETTING_TYPE_SECURE, 699 Settings.Secure.LOCATION_MODE, 700 String.valueOf(Settings.Secure.LOCATION_MODE_OFF), 701 UserHandle.USER_SYSTEM); 702 assertEquals( 703 "Wrong location providers", 704 "", 705 getStringViaFrontEndApiSetting( 706 SETTING_TYPE_SECURE, 707 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 708 UserHandle.USER_SYSTEM)); 709 710 setStringViaFrontEndApiSetting( 711 SETTING_TYPE_SECURE, 712 Settings.Secure.LOCATION_MODE, 713 String.valueOf(Settings.Secure.LOCATION_MODE_BATTERY_SAVING), 714 UserHandle.USER_SYSTEM); 715 assertEquals( 716 "Wrong location providers", 717 "network", 718 getStringViaFrontEndApiSetting( 719 SETTING_TYPE_SECURE, 720 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 721 UserHandle.USER_SYSTEM)); 722 723 setStringViaFrontEndApiSetting( 724 SETTING_TYPE_SECURE, 725 Settings.Secure.LOCATION_MODE, 726 String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY), 727 UserHandle.USER_SYSTEM); 728 assertEquals( 729 "Wrong location providers", 730 "gps,network", 731 getStringViaFrontEndApiSetting( 732 SETTING_TYPE_SECURE, 733 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 734 UserHandle.USER_SYSTEM)); 735 } 736 737 @Test testLocationProvidersAllowed_disableProviders()738 public void testLocationProvidersAllowed_disableProviders() throws Exception { 739 setStringViaFrontEndApiSetting( 740 SETTING_TYPE_SECURE, 741 Settings.Secure.LOCATION_MODE, 742 String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY), 743 UserHandle.USER_SYSTEM); 744 745 // Disable providers that were enabled 746 updateStringViaProviderApiSetting( 747 SETTING_TYPE_SECURE, 748 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 749 "-gps,-network"); 750 assertEquals( 751 "Wrong location providers", 752 "", 753 queryStringViaProviderApi( 754 SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)); 755 756 // Disable a provider that was not enabled 757 updateStringViaProviderApiSetting( 758 SETTING_TYPE_SECURE, 759 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 760 "-test"); 761 assertEquals( 762 "Wrong location providers", 763 "", 764 queryStringViaProviderApi( 765 SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)); 766 } 767 768 @Test testLocationProvidersAllowed_enableAndDisable()769 public void testLocationProvidersAllowed_enableAndDisable() throws Exception { 770 setStringViaFrontEndApiSetting( 771 SETTING_TYPE_SECURE, 772 Settings.Secure.LOCATION_MODE, 773 String.valueOf(Settings.Secure.LOCATION_MODE_OFF), 774 UserHandle.USER_SYSTEM); 775 776 updateStringViaProviderApiSetting( 777 SETTING_TYPE_SECURE, 778 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 779 "+gps,+network,+test"); 780 updateStringViaProviderApiSetting( 781 SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test"); 782 783 assertEquals( 784 "Wrong location providers", 785 "gps,network", 786 queryStringViaProviderApi( 787 SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)); 788 } 789 790 @Test testLocationProvidersAllowedLocked_invalidInput()791 public void testLocationProvidersAllowedLocked_invalidInput() throws Exception { 792 setStringViaFrontEndApiSetting( 793 SETTING_TYPE_SECURE, 794 Settings.Secure.LOCATION_MODE, 795 String.valueOf(Settings.Secure.LOCATION_MODE_OFF), 796 UserHandle.USER_SYSTEM); 797 798 // update providers with a invalid string 799 updateStringViaProviderApiSetting( 800 SETTING_TYPE_SECURE, 801 Settings.Secure.LOCATION_PROVIDERS_ALLOWED, 802 "+gps, invalid-string"); 803 804 // Verifies providers list does not change 805 assertEquals( 806 "Wrong location providers", 807 "", 808 queryStringViaProviderApi( 809 SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED)); 810 } 811 } 812