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