1 /* 2 * Copyright (C) 2018 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 android.provider; 18 19 import static android.provider.DeviceConfig.Properties; 20 21 import static com.google.common.truth.Truth.assertThat; 22 23 import static org.testng.Assert.assertThrows; 24 25 import android.content.ContentResolver; 26 import android.os.Bundle; 27 import android.platform.test.annotations.Presubmit; 28 29 import androidx.test.InstrumentationRegistry; 30 import androidx.test.filters.SmallTest; 31 import androidx.test.runner.AndroidJUnit4; 32 33 import org.junit.After; 34 import org.junit.Assert; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 38 /** Tests that ensure appropriate settings are backed up. */ 39 @Presubmit 40 @RunWith(AndroidJUnit4.class) 41 @SmallTest 42 public class DeviceConfigTest { 43 private static final long WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec 44 private static final String DEFAULT_VALUE = "test_default_value"; 45 private static final String NAMESPACE = "namespace1"; 46 private static final String KEY = "key1"; 47 private static final String KEY2 = "key2"; 48 private static final String KEY3 = "key3"; 49 private static final String KEY4 = "key4"; 50 private static final String VALUE = "value1"; 51 private static final String VALUE2 = "value2"; 52 private static final String VALUE3 = "value3"; 53 private static final String NULL_VALUE = "null"; 54 55 @After cleanUp()56 public void cleanUp() { 57 deleteViaContentProvider(NAMESPACE, KEY); 58 deleteViaContentProvider(NAMESPACE, KEY2); 59 deleteViaContentProvider(NAMESPACE, KEY3); 60 } 61 62 @Test getProperty_empty()63 public void getProperty_empty() { 64 String result = DeviceConfig.getProperty(NAMESPACE, KEY); 65 assertThat(result).isNull(); 66 } 67 68 @Test getProperty_nullNamespace()69 public void getProperty_nullNamespace() { 70 try { 71 DeviceConfig.getProperty(null, KEY); 72 Assert.fail("Null namespace should have resulted in an NPE."); 73 } catch (NullPointerException e) { 74 // expected 75 } 76 } 77 78 @Test getProperty_nullName()79 public void getProperty_nullName() { 80 try { 81 DeviceConfig.getProperty(NAMESPACE, null); 82 Assert.fail("Null name should have resulted in an NPE."); 83 } catch (NullPointerException e) { 84 // expected 85 } 86 } 87 88 @Test getString_empty()89 public void getString_empty() { 90 final String default_value = "default_value"; 91 final String result = DeviceConfig.getString(NAMESPACE, KEY, default_value); 92 assertThat(result).isEqualTo(default_value); 93 } 94 95 @Test getString_nullDefault()96 public void getString_nullDefault() { 97 final String result = DeviceConfig.getString(NAMESPACE, KEY, null); 98 assertThat(result).isNull(); 99 } 100 101 @Test getString_nonEmpty()102 public void getString_nonEmpty() { 103 final String value = "new_value"; 104 final String default_value = "default"; 105 DeviceConfig.setProperty(NAMESPACE, KEY, value, false); 106 107 final String result = DeviceConfig.getString(NAMESPACE, KEY, default_value); 108 assertThat(result).isEqualTo(value); 109 } 110 111 @Test getString_nullNamespace()112 public void getString_nullNamespace() { 113 try { 114 DeviceConfig.getString(null, KEY, "default_value"); 115 Assert.fail("Null namespace should have resulted in an NPE."); 116 } catch (NullPointerException e) { 117 // expected 118 } 119 } 120 121 @Test getString_nullName()122 public void getString_nullName() { 123 try { 124 DeviceConfig.getString(NAMESPACE, null, "default_value"); 125 Assert.fail("Null name should have resulted in an NPE."); 126 } catch (NullPointerException e) { 127 // expected 128 } 129 } 130 131 @Test getBoolean_empty()132 public void getBoolean_empty() { 133 final boolean default_value = true; 134 final boolean result = DeviceConfig.getBoolean(NAMESPACE, KEY, default_value); 135 assertThat(result).isEqualTo(default_value); 136 } 137 138 @Test getBoolean_valid()139 public void getBoolean_valid() { 140 final boolean value = true; 141 final boolean default_value = false; 142 DeviceConfig.setProperty(NAMESPACE, KEY, String.valueOf(value), false); 143 144 final boolean result = DeviceConfig.getBoolean(NAMESPACE, KEY, default_value); 145 assertThat(result).isEqualTo(value); 146 } 147 148 @Test getBoolean_invalid()149 public void getBoolean_invalid() { 150 final boolean default_value = true; 151 DeviceConfig.setProperty(NAMESPACE, KEY, "not_a_boolean", false); 152 153 final boolean result = DeviceConfig.getBoolean(NAMESPACE, KEY, default_value); 154 // Anything non-null other than case insensitive "true" parses to false. 155 assertThat(result).isFalse(); 156 } 157 158 @Test getBoolean_nullNamespace()159 public void getBoolean_nullNamespace() { 160 try { 161 DeviceConfig.getBoolean(null, KEY, false); 162 Assert.fail("Null namespace should have resulted in an NPE."); 163 } catch (NullPointerException e) { 164 // expected 165 } 166 } 167 168 @Test getBoolean_nullName()169 public void getBoolean_nullName() { 170 try { 171 DeviceConfig.getBoolean(NAMESPACE, null, false); 172 Assert.fail("Null name should have resulted in an NPE."); 173 } catch (NullPointerException e) { 174 // expected 175 } 176 } 177 178 @Test getInt_empty()179 public void getInt_empty() { 180 final int default_value = 999; 181 final int result = DeviceConfig.getInt(NAMESPACE, KEY, default_value); 182 assertThat(result).isEqualTo(default_value); 183 } 184 185 @Test getInt_valid()186 public void getInt_valid() { 187 final int value = 123; 188 final int default_value = 999; 189 DeviceConfig.setProperty(NAMESPACE, KEY, String.valueOf(value), false); 190 191 final int result = DeviceConfig.getInt(NAMESPACE, KEY, default_value); 192 assertThat(result).isEqualTo(value); 193 } 194 195 @Test getInt_invalid()196 public void getInt_invalid() { 197 final int default_value = 999; 198 DeviceConfig.setProperty(NAMESPACE, KEY, "not_an_int", false); 199 200 final int result = DeviceConfig.getInt(NAMESPACE, KEY, default_value); 201 // Failure to parse results in using the default value 202 assertThat(result).isEqualTo(default_value); 203 } 204 205 @Test getInt_nullNamespace()206 public void getInt_nullNamespace() { 207 try { 208 DeviceConfig.getInt(null, KEY, 0); 209 Assert.fail("Null namespace should have resulted in an NPE."); 210 } catch (NullPointerException e) { 211 // expected 212 } 213 } 214 215 @Test getInt_nullName()216 public void getInt_nullName() { 217 try { 218 DeviceConfig.getInt(NAMESPACE, null, 0); 219 Assert.fail("Null name should have resulted in an NPE."); 220 } catch (NullPointerException e) { 221 // expected 222 } 223 } 224 225 @Test getLong_empty()226 public void getLong_empty() { 227 final long default_value = 123456; 228 final long result = DeviceConfig.getLong(NAMESPACE, KEY, default_value); 229 assertThat(result).isEqualTo(default_value); 230 } 231 232 @Test getLong_valid()233 public void getLong_valid() { 234 final long value = 456789; 235 final long default_value = 123456; 236 DeviceConfig.setProperty(NAMESPACE, KEY, String.valueOf(value), false); 237 238 final long result = DeviceConfig.getLong(NAMESPACE, KEY, default_value); 239 assertThat(result).isEqualTo(value); 240 } 241 242 @Test getLong_invalid()243 public void getLong_invalid() { 244 final long default_value = 123456; 245 DeviceConfig.setProperty(NAMESPACE, KEY, "not_a_long", false); 246 247 final long result = DeviceConfig.getLong(NAMESPACE, KEY, default_value); 248 // Failure to parse results in using the default value 249 assertThat(result).isEqualTo(default_value); 250 } 251 252 @Test getLong_nullNamespace()253 public void getLong_nullNamespace() { 254 try { 255 DeviceConfig.getLong(null, KEY, 0); 256 Assert.fail("Null namespace should have resulted in an NPE."); 257 } catch (NullPointerException e) { 258 // expected 259 } 260 } 261 262 @Test getLong_nullName()263 public void getLong_nullName() { 264 try { 265 DeviceConfig.getLong(NAMESPACE, null, 0); 266 Assert.fail("Null name should have resulted in an NPE."); 267 } catch (NullPointerException e) { 268 // expected 269 } 270 } 271 272 @Test getFloat_empty()273 public void getFloat_empty() { 274 final float default_value = 123.456f; 275 final float result = DeviceConfig.getFloat(NAMESPACE, KEY, default_value); 276 assertThat(result).isEqualTo(default_value); 277 } 278 279 @Test getFloat_valid()280 public void getFloat_valid() { 281 final float value = 456.789f; 282 final float default_value = 123.456f; 283 DeviceConfig.setProperty(NAMESPACE, KEY, String.valueOf(value), false); 284 285 final float result = DeviceConfig.getFloat(NAMESPACE, KEY, default_value); 286 assertThat(result).isEqualTo(value); 287 } 288 289 @Test getFloat_invalid()290 public void getFloat_invalid() { 291 final float default_value = 123.456f; 292 DeviceConfig.setProperty(NAMESPACE, KEY, "not_a_float", false); 293 294 final float result = DeviceConfig.getFloat(NAMESPACE, KEY, default_value); 295 // Failure to parse results in using the default value 296 assertThat(result).isEqualTo(default_value); 297 } 298 299 @Test getFloat_nullNamespace()300 public void getFloat_nullNamespace() { 301 try { 302 DeviceConfig.getFloat(null, KEY, 0); 303 Assert.fail("Null namespace should have resulted in an NPE."); 304 } catch (NullPointerException e) { 305 // expected 306 } 307 } 308 309 @Test getFloat_nullName()310 public void getFloat_nullName() { 311 try { 312 DeviceConfig.getFloat(NAMESPACE, null, 0); 313 Assert.fail("Null name should have resulted in an NPE."); 314 } catch (NullPointerException e) { 315 // expected 316 } 317 } 318 319 @Test setProperty_nullNamespace()320 public void setProperty_nullNamespace() { 321 try { 322 DeviceConfig.setProperty(null, KEY, VALUE, false); 323 Assert.fail("Null namespace should have resulted in an NPE."); 324 } catch (NullPointerException e) { 325 // expected 326 } 327 } 328 329 @Test setProperty_nullName()330 public void setProperty_nullName() { 331 try { 332 DeviceConfig.setProperty(NAMESPACE, null, VALUE, false); 333 Assert.fail("Null name should have resulted in an NPE."); 334 } catch (NullPointerException e) { 335 // expected 336 } 337 } 338 339 @Test setAndGetProperty_sameNamespace()340 public void setAndGetProperty_sameNamespace() { 341 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 342 String result = DeviceConfig.getProperty(NAMESPACE, KEY); 343 assertThat(result).isEqualTo(VALUE); 344 } 345 346 @Test setAndGetProperty_differentNamespace()347 public void setAndGetProperty_differentNamespace() { 348 String newNamespace = "namespace2"; 349 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 350 String result = DeviceConfig.getProperty(newNamespace, KEY); 351 assertThat(result).isNull(); 352 } 353 354 @Test setAndGetProperty_multipleNamespaces()355 public void setAndGetProperty_multipleNamespaces() { 356 String newNamespace = "namespace2"; 357 String newValue = "value2"; 358 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 359 DeviceConfig.setProperty(newNamespace, KEY, newValue, false); 360 String result = DeviceConfig.getProperty(NAMESPACE, KEY); 361 assertThat(result).isEqualTo(VALUE); 362 result = DeviceConfig.getProperty(newNamespace, KEY); 363 assertThat(result).isEqualTo(newValue); 364 365 // clean up 366 deleteViaContentProvider(newNamespace, KEY); 367 } 368 369 @Test setAndGetProperty_overrideValue()370 public void setAndGetProperty_overrideValue() { 371 String newValue = "value2"; 372 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 373 DeviceConfig.setProperty(NAMESPACE, KEY, newValue, false); 374 String result = DeviceConfig.getProperty(NAMESPACE, KEY); 375 assertThat(result).isEqualTo(newValue); 376 } 377 378 @Test resetToDefault_makeDefault()379 public void resetToDefault_makeDefault() { 380 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, true); 381 assertThat(DeviceConfig.getProperty(NAMESPACE, KEY)).isEqualTo(VALUE); 382 383 DeviceConfig.resetToDefaults(Settings.RESET_MODE_PACKAGE_DEFAULTS, NAMESPACE); 384 assertThat(DeviceConfig.getProperty(NAMESPACE, KEY)).isEqualTo(VALUE); 385 } 386 387 @Test resetToDefault_doNotMakeDefault()388 public void resetToDefault_doNotMakeDefault() { 389 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 390 assertThat(DeviceConfig.getProperty(NAMESPACE, KEY)).isEqualTo(VALUE); 391 392 DeviceConfig.resetToDefaults(Settings.RESET_MODE_PACKAGE_DEFAULTS, NAMESPACE); 393 assertThat(DeviceConfig.getProperty(NAMESPACE, KEY)).isNull(); 394 } 395 396 @Test getProperties_fullNamespace()397 public void getProperties_fullNamespace() { 398 Properties properties = DeviceConfig.getProperties(NAMESPACE); 399 assertThat(properties.getKeyset()).isEmpty(); 400 401 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 402 DeviceConfig.setProperty(NAMESPACE, KEY2, VALUE2, false); 403 properties = DeviceConfig.getProperties(NAMESPACE); 404 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2); 405 assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE); 406 assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 407 408 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE3, false); 409 properties = DeviceConfig.getProperties(NAMESPACE); 410 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2); 411 assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE3); 412 assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 413 414 DeviceConfig.setProperty(NAMESPACE, KEY3, VALUE, false); 415 properties = DeviceConfig.getProperties(NAMESPACE); 416 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2, KEY3); 417 assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE3); 418 assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 419 assertThat(properties.getString(KEY3, DEFAULT_VALUE)).isEqualTo(VALUE); 420 } 421 422 @Test getProperties_getString()423 public void getProperties_getString() { 424 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 425 DeviceConfig.setProperty(NAMESPACE, KEY2, VALUE2, false); 426 427 Properties properties = DeviceConfig.getProperties(NAMESPACE, KEY, KEY2); 428 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2); 429 assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE); 430 assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 431 } 432 433 @Test getProperties_getBoolean()434 public void getProperties_getBoolean() { 435 DeviceConfig.setProperty(NAMESPACE, KEY, "true", false); 436 DeviceConfig.setProperty(NAMESPACE, KEY2, "false", false); 437 DeviceConfig.setProperty(NAMESPACE, KEY3, "not a valid boolean", false); 438 439 Properties properties = DeviceConfig.getProperties(NAMESPACE, KEY, KEY2, KEY3); 440 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2, KEY3); 441 assertThat(properties.getBoolean(KEY, true)).isTrue(); 442 assertThat(properties.getBoolean(KEY, false)).isTrue(); 443 assertThat(properties.getBoolean(KEY2, true)).isFalse(); 444 assertThat(properties.getBoolean(KEY2, false)).isFalse(); 445 // KEY3 was set to garbage, anything nonnull but "true" will parse as false 446 assertThat(properties.getBoolean(KEY3, true)).isFalse(); 447 assertThat(properties.getBoolean(KEY3, false)).isFalse(); 448 // If a key was not set, it will return the default value 449 assertThat(properties.getBoolean("missing_key", true)).isTrue(); 450 assertThat(properties.getBoolean("missing_key", false)).isFalse(); 451 } 452 453 @Test getProperties_getInt()454 public void getProperties_getInt() { 455 final int value = 101; 456 457 DeviceConfig.setProperty(NAMESPACE, KEY, Integer.toString(value), false); 458 DeviceConfig.setProperty(NAMESPACE, KEY2, "not a valid int", false); 459 460 Properties properties = DeviceConfig.getProperties(NAMESPACE, KEY, KEY2); 461 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2); 462 assertThat(properties.getInt(KEY, -1)).isEqualTo(value); 463 // KEY2 was set to garbage, the default value is returned if an int cannot be parsed 464 assertThat(properties.getInt(KEY2, -1)).isEqualTo(-1); 465 } 466 467 @Test getProperties_getFloat()468 public void getProperties_getFloat() { 469 final float value = 101.010f; 470 471 DeviceConfig.setProperty(NAMESPACE, KEY, Float.toString(value), false); 472 DeviceConfig.setProperty(NAMESPACE, KEY2, "not a valid float", false); 473 474 Properties properties = DeviceConfig.getProperties(NAMESPACE, KEY, KEY2); 475 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2); 476 assertThat(properties.getFloat(KEY, -1.0f)).isEqualTo(value); 477 // KEY2 was set to garbage, the default value is returned if a float cannot be parsed 478 assertThat(properties.getFloat(KEY2, -1.0f)).isEqualTo(-1.0f); 479 } 480 481 @Test getProperties_getLong()482 public void getProperties_getLong() { 483 final long value = 101; 484 485 DeviceConfig.setProperty(NAMESPACE, KEY, Long.toString(value), false); 486 DeviceConfig.setProperty(NAMESPACE, KEY2, "not a valid long", false); 487 488 Properties properties = DeviceConfig.getProperties(NAMESPACE, KEY, KEY2); 489 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2); 490 assertThat(properties.getLong(KEY, -1)).isEqualTo(value); 491 // KEY2 was set to garbage, the default value is returned if a long cannot be parsed 492 assertThat(properties.getLong(KEY2, -1)).isEqualTo(-1); 493 } 494 495 @Test getProperties_defaults()496 public void getProperties_defaults() { 497 DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 498 DeviceConfig.setProperty(NAMESPACE, KEY3, VALUE3, false); 499 500 Properties properties = DeviceConfig.getProperties(NAMESPACE, KEY, KEY2); 501 assertThat(properties.getKeyset()).containsExactly(KEY); 502 assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE); 503 // not set in DeviceConfig, but requested in getProperties 504 assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 505 // set in DeviceConfig, but not requested in getProperties 506 assertThat(properties.getString(KEY3, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 507 } 508 509 @Test setProperties()510 public void setProperties() throws DeviceConfig.BadConfigException { 511 Properties properties = new Properties.Builder(NAMESPACE).setString(KEY, VALUE) 512 .setString(KEY2, VALUE2).build(); 513 514 DeviceConfig.setProperties(properties); 515 properties = DeviceConfig.getProperties(NAMESPACE); 516 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2); 517 assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE); 518 assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 519 520 properties = new Properties.Builder(NAMESPACE).setString(KEY, VALUE2) 521 .setString(KEY3, VALUE3).build(); 522 523 DeviceConfig.setProperties(properties); 524 properties = DeviceConfig.getProperties(NAMESPACE); 525 assertThat(properties.getKeyset()).containsExactly(KEY, KEY3); 526 assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE2); 527 assertThat(properties.getString(KEY3, DEFAULT_VALUE)).isEqualTo(VALUE3); 528 529 assertThat(properties.getKeyset()).doesNotContain(KEY2); 530 assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 531 } 532 533 @Test setProperties_multipleNamespaces()534 public void setProperties_multipleNamespaces() throws DeviceConfig.BadConfigException { 535 final String namespace2 = "namespace2"; 536 Properties properties1 = new Properties.Builder(NAMESPACE).setString(KEY, VALUE) 537 .setString(KEY2, VALUE2).build(); 538 Properties properties2 = new Properties.Builder(namespace2).setString(KEY2, VALUE) 539 .setString(KEY3, VALUE2).build(); 540 541 DeviceConfig.setProperties(properties1); 542 DeviceConfig.setProperties(properties2); 543 544 Properties properties = DeviceConfig.getProperties(NAMESPACE); 545 assertThat(properties.getKeyset()).containsExactly(KEY, KEY2); 546 assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE); 547 assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 548 549 assertThat(properties.getKeyset()).doesNotContain(KEY3); 550 assertThat(properties.getString(KEY3, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 551 552 properties = DeviceConfig.getProperties(namespace2); 553 assertThat(properties.getKeyset()).containsExactly(KEY2, KEY3); 554 assertThat(properties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE); 555 assertThat(properties.getString(KEY3, DEFAULT_VALUE)).isEqualTo(VALUE2); 556 557 assertThat(properties.getKeyset()).doesNotContain(KEY); 558 assertThat(properties.getString(KEY, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 559 560 // clean up 561 deleteViaContentProvider(namespace2, KEY); 562 deleteViaContentProvider(namespace2, KEY2); 563 deleteViaContentProvider(namespace2, KEY3); 564 } 565 566 @Test propertiesBuilder()567 public void propertiesBuilder() { 568 boolean booleanValue = true; 569 int intValue = 123; 570 float floatValue = 4.56f; 571 long longValue = -789L; 572 String key4 = "key4"; 573 String key5 = "key5"; 574 575 Properties properties = new Properties.Builder(NAMESPACE).setString(KEY, VALUE) 576 .setBoolean(KEY2, booleanValue).setInt(KEY3, intValue).setLong(key4, longValue) 577 .setFloat(key5, floatValue).build(); 578 assertThat(properties.getNamespace()).isEqualTo(NAMESPACE); 579 assertThat(properties.getString(KEY, "defaultValue")).isEqualTo(VALUE); 580 assertThat(properties.getBoolean(KEY2, false)).isEqualTo(booleanValue); 581 assertThat(properties.getInt(KEY3, 0)).isEqualTo(intValue); 582 assertThat(properties.getLong("key4", 0L)).isEqualTo(longValue); 583 assertThat(properties.getFloat("key5", 0f)).isEqualTo(floatValue); 584 } 585 586 @Test banNamespaceProperties()587 public void banNamespaceProperties() throws DeviceConfig.BadConfigException { 588 // Given namespace will be permanently banned, thus it needs to be different every time 589 final String namespaceToBan = NAMESPACE + System.currentTimeMillis(); 590 Properties properties = new Properties.Builder(namespaceToBan).setString(KEY, VALUE) 591 .setString(KEY4, NULL_VALUE).build(); 592 // Set namespace properties 593 DeviceConfig.setProperties(properties); 594 // Ban namespace with related properties 595 DeviceConfig.resetToDefaults(Settings.RESET_MODE_PACKAGE_DEFAULTS, namespaceToBan); 596 // Verify given namespace properties are banned 597 assertThrows(DeviceConfig.BadConfigException.class, 598 () -> DeviceConfig.setProperties(properties)); 599 // Modify properties and verify we can set them 600 Properties modifiedProperties = new Properties.Builder(namespaceToBan).setString(KEY, VALUE) 601 .setString(KEY4, NULL_VALUE).setString(KEY2, VALUE2).build(); 602 DeviceConfig.setProperties(modifiedProperties); 603 modifiedProperties = DeviceConfig.getProperties(namespaceToBan); 604 assertThat(modifiedProperties.getKeyset()).containsExactly(KEY, KEY2, KEY4); 605 assertThat(modifiedProperties.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE); 606 assertThat(modifiedProperties.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 607 // Since value is null DEFAULT_VALUE should be returned 608 assertThat(modifiedProperties.getString(KEY4, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 609 } 610 611 @Test banEntireDeviceConfig()612 public void banEntireDeviceConfig() throws DeviceConfig.BadConfigException { 613 // Given namespaces will be permanently banned, thus they need to be different every time 614 final String namespaceToBan1 = NAMESPACE + System.currentTimeMillis(); 615 final String namespaceToBan2 = NAMESPACE + System.currentTimeMillis() + 1; 616 617 // Set namespaces properties 618 Properties properties1 = new Properties.Builder(namespaceToBan1).setString(KEY, VALUE) 619 .setString(KEY4, NULL_VALUE).build(); 620 DeviceConfig.setProperties(properties1); 621 Properties properties2 = new Properties.Builder(namespaceToBan2).setString(KEY2, VALUE2) 622 .setString(KEY4, NULL_VALUE).build(); 623 DeviceConfig.setProperties(properties2); 624 625 // Ban entire DeviceConfig 626 DeviceConfig.resetToDefaults(Settings.RESET_MODE_PACKAGE_DEFAULTS, null); 627 628 // Verify given namespace properties are banned 629 assertThrows(DeviceConfig.BadConfigException.class, 630 () -> DeviceConfig.setProperties(properties1)); 631 assertThrows(DeviceConfig.BadConfigException.class, 632 () -> DeviceConfig.setProperties(properties2)); 633 634 // Modify properties and verify we can set them 635 Properties modifiedProperties1 = new Properties.Builder(namespaceToBan1).setString(KEY, 636 VALUE) 637 .setString(KEY4, NULL_VALUE).setString(KEY2, VALUE2).build(); 638 DeviceConfig.setProperties(modifiedProperties1); 639 modifiedProperties1 = DeviceConfig.getProperties(namespaceToBan1); 640 assertThat(modifiedProperties1.getKeyset()).containsExactly(KEY, KEY2, KEY4); 641 assertThat(modifiedProperties1.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE); 642 assertThat(modifiedProperties1.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 643 // Since value is null DEFAULT_VALUE should be returned 644 assertThat(modifiedProperties1.getString(KEY4, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 645 646 Properties modifiedProperties2 = new Properties.Builder(namespaceToBan2).setString(KEY, 647 VALUE) 648 .setString(KEY3, NULL_VALUE).setString(KEY4, VALUE2).build(); 649 DeviceConfig.setProperties(modifiedProperties2); 650 modifiedProperties2 = DeviceConfig.getProperties(namespaceToBan2); 651 assertThat(modifiedProperties2.getKeyset()).containsExactly(KEY, KEY3, KEY4); 652 assertThat(modifiedProperties2.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE); 653 assertThat(modifiedProperties2.getString(KEY4, DEFAULT_VALUE)).isEqualTo(VALUE2); 654 // Since value is null DEFAULT_VALUE should be returned 655 assertThat(modifiedProperties2.getString(KEY3, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 656 } 657 658 @Test allConfigsUnbannedIfAnyUnbannedConfigUpdated()659 public void allConfigsUnbannedIfAnyUnbannedConfigUpdated() 660 throws DeviceConfig.BadConfigException { 661 // Given namespaces will be permanently banned, thus they need to be different every time 662 final String namespaceToBan1 = NAMESPACE + System.currentTimeMillis(); 663 final String namespaceToBan2 = NAMESPACE + System.currentTimeMillis() + 1; 664 665 // Set namespaces properties 666 Properties properties1 = new Properties.Builder(namespaceToBan1).setString(KEY, VALUE) 667 .setString(KEY4, NULL_VALUE).build(); 668 DeviceConfig.setProperties(properties1); 669 Properties properties2 = new Properties.Builder(namespaceToBan2).setString(KEY2, VALUE2) 670 .setString(KEY4, NULL_VALUE).build(); 671 DeviceConfig.setProperties(properties2); 672 673 // Ban namespace with related properties 674 DeviceConfig.resetToDefaults(Settings.RESET_MODE_PACKAGE_DEFAULTS, namespaceToBan1); 675 DeviceConfig.resetToDefaults(Settings.RESET_MODE_PACKAGE_DEFAULTS, namespaceToBan2); 676 677 // Verify given namespace properties are banned 678 assertThrows(DeviceConfig.BadConfigException.class, 679 () -> DeviceConfig.setProperties(properties1)); 680 assertThrows(DeviceConfig.BadConfigException.class, 681 () -> DeviceConfig.setProperties(properties2)); 682 683 // Modify properties and verify we can set them 684 Properties modifiedProperties1 = new Properties.Builder(namespaceToBan1).setString(KEY, 685 VALUE) 686 .setString(KEY4, NULL_VALUE).setString(KEY2, VALUE2).build(); 687 DeviceConfig.setProperties(modifiedProperties1); 688 modifiedProperties1 = DeviceConfig.getProperties(namespaceToBan1); 689 assertThat(modifiedProperties1.getKeyset()).containsExactly(KEY, KEY2, KEY4); 690 assertThat(modifiedProperties1.getString(KEY, DEFAULT_VALUE)).isEqualTo(VALUE); 691 assertThat(modifiedProperties1.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 692 // Since value is null DEFAULT_VALUE should be returned 693 assertThat(modifiedProperties1.getString(KEY4, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 694 695 // verify that other banned namespaces are unbanned now. 696 DeviceConfig.setProperties(properties2); 697 Properties result = DeviceConfig.getProperties(namespaceToBan2); 698 assertThat(result.getKeyset()).containsExactly(KEY2, KEY4); 699 assertThat(result.getString(KEY2, DEFAULT_VALUE)).isEqualTo(VALUE2); 700 // Since value is null DEFAULT_VALUE should be returned 701 assertThat(result.getString(KEY4, DEFAULT_VALUE)).isEqualTo(DEFAULT_VALUE); 702 } 703 704 // TODO(mpape): resolve b/142727848 and re-enable listener tests 705 // @Test 706 // public void onPropertiesChangedListener_setPropertyCallback() throws InterruptedException { 707 // final CountDownLatch countDownLatch = new CountDownLatch(1); 708 // 709 // DeviceConfig.OnPropertiesChangedListener changeListener = (properties) -> { 710 // assertThat(properties.getNamespace()).isEqualTo(NAMESPACE); 711 // assertThat(properties.getKeyset()).contains(KEY); 712 // assertThat(properties.getString(KEY, "default_value")).isEqualTo(VALUE); 713 // countDownLatch.countDown(); 714 // }; 715 // 716 // try { 717 // DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, 718 // ActivityThread.currentApplication().getMainExecutor(), changeListener); 719 // DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 720 // assertThat(countDownLatch.await( 721 // WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue(); 722 // } catch (InterruptedException e) { 723 // Assert.fail(e.getMessage()); 724 // } finally { 725 // DeviceConfig.removeOnPropertiesChangedListener(changeListener); 726 // } 727 // } 728 // 729 // @Test 730 // public void onPropertiesChangedListener_setPropertiesCallback() throws InterruptedException { 731 // final CountDownLatch countDownLatch = new CountDownLatch(1); 732 // DeviceConfig.setProperty(NAMESPACE, KEY, VALUE, false); 733 // DeviceConfig.setProperty(NAMESPACE, KEY2, VALUE2, false); 734 // 735 // Map<String, String> keyValues = new HashMap<>(2); 736 // keyValues.put(KEY, VALUE2); 737 // keyValues.put(KEY3, VALUE3); 738 // Properties setProperties = new Properties(NAMESPACE, keyValues); 739 // 740 // DeviceConfig.OnPropertiesChangedListener changeListener = (properties) -> { 741 // assertThat(properties.getNamespace()).isEqualTo(NAMESPACE); 742 // assertThat(properties.getKeyset()).containsExactly(KEY, KEY2, KEY3); 743 // // KEY updated from VALUE to VALUE2 744 // assertThat(properties.getString(KEY, "default_value")).isEqualTo(VALUE2); 745 // // KEY2 deleted (returns default_value) 746 // assertThat(properties.getString(KEY2, "default_value")).isEqualTo("default_value"); 747 // //KEY3 added with VALUE3 748 // assertThat(properties.getString(KEY3, "default_value")).isEqualTo(VALUE3); 749 // countDownLatch.countDown(); 750 // }; 751 // 752 // try { 753 // DeviceConfig.addOnPropertiesChangedListener(NAMESPACE, 754 // ActivityThread.currentApplication().getMainExecutor(), changeListener); 755 // DeviceConfig.setProperties(setProperties); 756 // assertThat(countDownLatch.await( 757 // WAIT_FOR_PROPERTY_CHANGE_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS)).isTrue(); 758 // } catch (InterruptedException e) { 759 // Assert.fail(e.getMessage()); 760 // } finally { 761 // DeviceConfig.removeOnPropertiesChangedListener(changeListener); 762 // } 763 // } 764 765 @Test syncDisabling()766 public void syncDisabling() throws Exception { 767 Properties properties1 = new Properties.Builder(NAMESPACE) 768 .setString(KEY, VALUE) 769 .build(); 770 Properties properties2 = new Properties.Builder(NAMESPACE) 771 .setString(KEY, VALUE2) 772 .build(); 773 774 try { 775 // Ensure the device starts in a known state. 776 DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_NONE); 777 778 // Assert starting state. 779 assertThat(DeviceConfig.isSyncDisabled()).isFalse(); 780 assertThat(DeviceConfig.setProperties(properties1)).isTrue(); 781 assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE)) 782 .isEqualTo(VALUE); 783 784 // Test disabled (persistent). Persistence is not actually tested, that would require 785 // a host test. 786 DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_PERSISTENT); 787 assertThat(DeviceConfig.isSyncDisabled()).isTrue(); 788 assertThat(DeviceConfig.setProperties(properties2)).isFalse(); 789 assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE)) 790 .isEqualTo(VALUE); 791 792 // Return to not disabled. 793 DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_NONE); 794 assertThat(DeviceConfig.isSyncDisabled()).isFalse(); 795 assertThat(DeviceConfig.setProperties(properties2)).isTrue(); 796 assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE)) 797 .isEqualTo(VALUE2); 798 799 // Test disabled (persistent). Absence of persistence is not actually tested, that would 800 // require a host test. 801 DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT); 802 assertThat(DeviceConfig.isSyncDisabled()).isTrue(); 803 assertThat(DeviceConfig.setProperties(properties1)).isFalse(); 804 assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE)) 805 .isEqualTo(VALUE2); 806 807 // Return to not disabled. 808 DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_NONE); 809 assertThat(DeviceConfig.isSyncDisabled()).isFalse(); 810 assertThat(DeviceConfig.setProperties(properties1)).isTrue(); 811 assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE)) 812 .isEqualTo(VALUE); 813 } finally { 814 // Try to return to the default sync disabled state in case of failure. 815 DeviceConfig.setSyncDisabled(Settings.Config.SYNC_DISABLED_MODE_NONE); 816 817 // NAMESPACE will be cleared by cleanUp() 818 } 819 } 820 deleteViaContentProvider(String namespace, String key)821 private static boolean deleteViaContentProvider(String namespace, String key) { 822 ContentResolver resolver = InstrumentationRegistry.getContext().getContentResolver(); 823 String compositeName = namespace + "/" + key; 824 Bundle result = resolver.call( 825 DeviceConfig.CONTENT_URI, Settings.CALL_METHOD_DELETE_CONFIG, compositeName, null); 826 assertThat(result).isNotNull(); 827 return compositeName.equals(result.getString(Settings.NameValueTable.VALUE)); 828 } 829 830 } 831