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