1683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav/*
2683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * Copyright (C) 2015 The Android Open Source Project
3683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav *
4683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * Licensed under the Apache License, Version 2.0 (the "License");
5683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * you may not use this file except in compliance with the License.
6683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * You may obtain a copy of the License at
7683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav *
8683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav *      http://www.apache.org/licenses/LICENSE-2.0
9683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav *
10683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * Unless required by applicable law or agreed to in writing, software
11683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * distributed under the License is distributed on an "AS IS" BASIS,
12683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * See the License for the specific language governing permissions and
14683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * limitations under the License.
15683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav */
16683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
17683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavpackage com.android.providers.settings;
18683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
19e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganovimport static junit.framework.Assert.assertEquals;
20e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganovimport static junit.framework.Assert.assertNull;
2183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggieimport static junit.framework.Assert.assertSame;
22e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganovimport static junit.framework.Assert.fail;
23e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
24683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.content.ContentResolver;
25683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.content.ContentValues;
26683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.database.ContentObserver;
27683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.database.Cursor;
28683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.net.Uri;
29683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.os.Handler;
30683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.os.Looper;
31683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.os.SystemClock;
32683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.os.UserHandle;
33683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.provider.Settings;
34683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport android.util.Log;
35683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavimport java.util.concurrent.atomic.AtomicBoolean;
3683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggieimport org.junit.Test;
37683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
38683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav/**
39683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * Tests for the SettingContentProvider.
40683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav *
41683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav * Before you run this test you must add a secondary user.
42683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav */
43683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslavpublic class SettingsProviderTest extends BaseSettingsProviderTest {
44683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private static final String LOG_TAG = "SettingsProviderTest";
45683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
46683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private static final long WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec
47683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
48683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private static final String[] NAME_VALUE_COLUMNS = new String[]{
49683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE
50683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    };
51683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
52683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private final Object mLock = new Object();
53683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
54e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
5543765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen    public void testSetAndGetGlobalViaFrontEndApiForSystemUser() throws Exception {
5643765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, UserHandle.USER_SYSTEM);
57683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
58683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
59e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
6043765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen    public void testSetAndGetGlobalViaFrontEndApiForNonSystemUser() throws Exception {
61e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        final int secondaryUserId = getSecondaryUserId();
62e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        if (secondaryUserId == UserHandle.USER_SYSTEM) {
63683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            Log.w(LOG_TAG, "No secondary user. Skipping "
6443765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen                    + "testSetAndGetGlobalViaFrontEndApiForNonSystemUser");
65683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            return;
66683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
67e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, secondaryUserId);
68683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
69683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
70e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
7143765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen    public void testSetAndGetSecureViaFrontEndApiForSystemUser() throws Exception {
7243765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, UserHandle.USER_SYSTEM);
73683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
74683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
75e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
7643765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen    public void testSetAndGetSecureViaFrontEndApiForNonSystemUser() throws Exception {
77e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        final int secondaryUserId = getSecondaryUserId();
78e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        if (secondaryUserId == UserHandle.USER_SYSTEM) {
79683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            Log.w(LOG_TAG, "No secondary user. Skipping "
8043765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen                    + "testSetAndGetSecureViaFrontEndApiForNonSystemUser");
81683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            return;
82683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
83e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, secondaryUserId);
84683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
85683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
86e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
8743765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen    public void testSetAndGetSystemViaFrontEndApiForSystemUser() throws Exception {
8843765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, UserHandle.USER_SYSTEM);
89683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
90683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
91e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
9243765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen    public void testSetAndGetSystemViaFrontEndApiForNonSystemUser() throws Exception {
93e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        final int secondaryUserId = getSecondaryUserId();
94e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        if (secondaryUserId == UserHandle.USER_SYSTEM) {
95683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            Log.w(LOG_TAG, "No secondary user. Skipping "
9643765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen                    + "testSetAndGetSystemViaFrontEndApiForNonSystemUser");
97683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            return;
98683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
99e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, secondaryUserId);
100683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
101683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
102e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
103683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testSetAndGetGlobalViaProviderApi() throws Exception {
104683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_GLOBAL);
105683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
106683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
107e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
108683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testSetAndGetSecureViaProviderApi() throws Exception {
109683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_SECURE);
110683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
111683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
112e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
113683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testSetAndGetSystemViaProviderApi() throws Exception {
114683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_SYSTEM);
115683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
116683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
117e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
118683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testSelectAllGlobalViaProviderApi() throws Exception {
119683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_GLOBAL,
120683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false);
121683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
122683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_GLOBAL,
123683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    FAKE_SETTING_NAME);
124683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } finally {
125683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            deleteStringViaProviderApi(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME);
126683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
127683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
128683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
129e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
130683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testSelectAllSecureViaProviderApi() throws Exception {
131683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_SECURE,
132683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false);
133683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
134683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_SECURE,
135683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    FAKE_SETTING_NAME);
136683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } finally {
137683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            deleteStringViaProviderApi(SETTING_TYPE_SECURE, FAKE_SETTING_NAME);
138683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
139683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
140683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
141e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
142683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testSelectAllSystemViaProviderApi() throws Exception {
143683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_SYSTEM,
144683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                FAKE_SETTING_NAME, FAKE_SETTING_VALUE, true);
145683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
146683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_SYSTEM,
147683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    FAKE_SETTING_NAME);
148683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } finally {
149683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME);
150683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
151683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
152683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
153e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
154683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testQueryUpdateDeleteGlobalViaProviderApi() throws Exception {
155683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_GLOBAL);
156683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
157683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
158e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
159683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testQueryUpdateDeleteSecureViaProviderApi() throws Exception {
160683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SECURE);
161683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
162683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
163e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
164683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testQueryUpdateDeleteSystemViaProviderApi() throws Exception {
165683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SYSTEM);
166683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
167683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
168e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
169683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testBulkInsertGlobalViaProviderApi() throws Exception {
170683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        toTestBulkInsertViaProviderApiForType(SETTING_TYPE_GLOBAL);
171683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
172683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
173e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
174683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testBulkInsertSystemViaProviderApi() throws Exception {
175683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SYSTEM);
176683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
177683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
178e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
179683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testBulkInsertSecureViaProviderApi() throws Exception {
180683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SECURE);
181683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
182683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
183e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
184683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testAppCannotRunsSystemOutOfMemoryWritingSystemSettings() throws Exception {
185683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        int insertedCount = 0;
186683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
187683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            for (; insertedCount < 1200; insertedCount++) {
188683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                Log.w(LOG_TAG, "Adding app specific setting: " + insertedCount);
189683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                insertStringViaProviderApi(SETTING_TYPE_SYSTEM,
190683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                        String.valueOf(insertedCount), FAKE_SETTING_VALUE, false);
191683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            }
192683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            fail("Adding app specific settings must be bound.");
193683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } catch (Exception e) {
194e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // expected
195e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        } finally {
196683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            for (; insertedCount >= 0; insertedCount--) {
197683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                Log.w(LOG_TAG, "Removing app specific setting: " + insertedCount);
198683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                deleteStringViaProviderApi(SETTING_TYPE_SYSTEM,
199683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                        String.valueOf(insertedCount));
200683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            }
201683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
202683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
203683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
204e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
205683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testQueryStringInBracketsGlobalViaProviderApiForType() throws Exception {
206683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_GLOBAL);
207683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
208683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
209e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
210683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testQueryStringInBracketsSecureViaProviderApiForType() throws Exception {
211683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SECURE);
212683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
213683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
214e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
215683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    public void testQueryStringInBracketsSystemViaProviderApiForType() throws Exception {
216683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SYSTEM);
217683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
218683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
219e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
2202849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav    public void testQueryStringWithAppendedNameToUriViaProviderApi() throws Exception {
2212849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav        // Make sure we have a clean slate.
2222849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav        deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME);
2232849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav
2242849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav        try {
2252849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            // Insert the setting.
2262849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            final Uri uri = insertStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME,
2272849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav                    FAKE_SETTING_VALUE, false);
2282849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            Uri expectUri = Uri.withAppendedPath(getBaseUriForType(SETTING_TYPE_SYSTEM),
2292849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav                    FAKE_SETTING_NAME);
2302849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            assertEquals("Did not get expected Uri.", expectUri, uri);
2312849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav
2322849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            // Make sure the first setting is there.
2332849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            String firstValue = queryStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME,
2342849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav                    false, true);
2352849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue);
2362849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav        } finally {
2372849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            // Clean up.
2382849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME);
2392849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav        }
2402849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav    }
2412849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav
242e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
243e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModePackageDefaultsGlobal() throws Exception {
244e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModePackageDefaultsCommon(SETTING_TYPE_GLOBAL);
245e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
246e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
247e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
248e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModePackageDefaultsSecure() throws Exception {
249e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModePackageDefaultsCommon(SETTING_TYPE_SECURE);
250e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
251e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
252e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    private void testResetModePackageDefaultsCommon(int type) throws Exception {
253e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        // Make sure we have a clean slate.
254e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        setSettingViaShell(type, FAKE_SETTING_NAME, null, true);
255e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        try {
256e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a value but don't make it the default
257e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME,
258e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE, false);
259e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
260e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Reset the changes made by the "shell/root" package
261e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetToDefaultsViaShell(type, "shell");
262e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetToDefaultsViaShell(type, "root");
263e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
264e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure the old APIs don't set defaults
265e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertNull(getSetting(type, FAKE_SETTING_NAME));
266e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
267e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a value and make it the default
268e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME,
269e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE, true);
270e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Change the setting from the default
271e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME,
272e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE_2, false);
273e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
274e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Reset the changes made by this package
275e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetToDefaultsViaShell(type, "shell");
276e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetToDefaultsViaShell(type, "root");
277e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
278e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure the old APIs don't set defaults
279e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME));
280e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        } finally {
281e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure we have a clean slate.
282e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME, null, true);
283e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        }
284e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
285e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
286e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
287e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModePackageDefaultsWithTokensGlobal() throws Exception {
288e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModePackageDefaultsWithTokensCommon(SETTING_TYPE_GLOBAL);
289e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
290e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
291e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
292e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModePackageDefaultsWithTokensSecure() throws Exception {
293e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModePackageDefaultsWithTokensCommon(SETTING_TYPE_SECURE);
294e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
295e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
296e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    private void testResetModePackageDefaultsWithTokensCommon(int type) throws Exception {
297e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        // Make sure we have a clean slate.
298e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        setSettingViaShell(type, FAKE_SETTING_NAME, null, true);
299e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true);
300e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        try {
301e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a default value
302e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME,
303e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE, true);
304e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Change the default and associate a token
305e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME,
306e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE_2, "TOKEN1", false);
307e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
308e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a default value
309e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1,
310e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE, "TOKEN2", true);
311e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Change the default and associate a token
312e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1,
313e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE_2, "TOKEN2", false);
314e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
315e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Reset settings associated with TOKEN1
316e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetToDefaultsViaShell(type, "shell", "TOKEN1");
317e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetToDefaultsViaShell(type, "root", "TOKEN1");
318e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
319e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure TOKEN1 settings are reset
320e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertEquals(FAKE_SETTING_VALUE, getSetting(type,
321e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_NAME));
322e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
323e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure TOKEN2 settings are not reset
324e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertEquals(FAKE_SETTING_VALUE_2, getSetting(type,
325e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_NAME_1));
326e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
327e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Reset settings associated with TOKEN2
328e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetToDefaultsViaShell(type, "shell", "TOKEN2");
329e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetToDefaultsViaShell(type, "root", "TOKEN2");
330e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
331e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure TOKEN2 settings are reset
332e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertEquals(FAKE_SETTING_VALUE, getSetting(type,
333e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_NAME_1));
334e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        } finally {
335e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure we have a clean slate.
336e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME, null, true);
337e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true);
338e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        }
339e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
340e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
341e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
342e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModeUntrustedDefaultsGlobal() throws Exception {
343e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModeUntrustedDefaultsCommon(SETTING_TYPE_GLOBAL);
344e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
345e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
346e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
347e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModeUntrustedDefaultsSecure() throws Exception {
348e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModeUntrustedDefaultsCommon(SETTING_TYPE_SECURE);
349e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
350e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
351e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    private void testResetModeUntrustedDefaultsCommon(int type) throws Exception {
352e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        // Make sure we have a clean slate.
353e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        putSetting(type, FAKE_SETTING_NAME, null);
354e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true);
355e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        try {
356e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a default setting as a trusted component
357e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE);
358e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Change the setting as a trusted component
359e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2);
360e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
361e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a default setting as an untrusted component
362e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1,
363e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE, true);
364e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Change the setting as an untrusted component
365e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1,
366e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE_2, false);
367e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
368e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Reset the untrusted changes to defaults
369e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetSettingsViaShell(type,
370e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    Settings.RESET_MODE_UNTRUSTED_DEFAULTS);
371e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
372e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Check whether only the untrusted changes set to defaults
373e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, FAKE_SETTING_NAME));
374e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME_1));
375e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        } finally {
376e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure we have a clean slate.
377e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            putSetting(type, FAKE_SETTING_NAME, null);
378e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true);
379e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        }
380e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
381e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
382e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
383e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModeUntrustedClearGlobal() throws Exception {
384e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModeUntrustedClearCommon(SETTING_TYPE_GLOBAL);
385e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
386e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
387e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
388e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModeUntrustedClearSecure() throws Exception {
389e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModeUntrustedClearCommon(SETTING_TYPE_SECURE);
390e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
391e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
392e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    private void testResetModeUntrustedClearCommon(int type) throws Exception {
393e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        // Make sure we have a clean slate.
394e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        putSetting(type, FAKE_SETTING_NAME, null);
395e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true);
396e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        try {
397e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a default setting as a trusted component
398e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE);
399e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Change the setting as a trusted component
400e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2);
401e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
402e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a default setting as an untrusted component
403e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1,
404e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE, true);
405e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Change the setting as an untrusted component
406e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1,
407e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE_2, false);
408e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
409e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Clear the untrusted changes
410e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetSettingsViaShell(type,
411e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    Settings.RESET_MODE_UNTRUSTED_CHANGES);
412e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
413e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Check whether only the untrusted changes set to defaults
414e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, FAKE_SETTING_NAME));
415e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertNull(getSetting(type, FAKE_SETTING_NAME_1));
416e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        } finally {
417e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure we have a clean slate.
418e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            putSetting(type, FAKE_SETTING_NAME, null);
419e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true);
420e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        }
421e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
422e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
423e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
424e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModeTrustedDefaultsGlobal() throws Exception {
425e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModeTrustedDefaultsCommon(SETTING_TYPE_GLOBAL);
426e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
427e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
428e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    @Test
429e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    public void testResetModeTrustedDefaultsSecure() throws Exception {
430e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        testResetModeTrustedDefaultsCommon(SETTING_TYPE_SECURE);
431e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
432e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
433e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    private void testResetModeTrustedDefaultsCommon(int type) throws Exception {
434e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        // Make sure we have a clean slate.
435e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        putSetting(type, FAKE_SETTING_NAME, null);
436e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true);
437e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        try {
438e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a default setting as a trusted component
439e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE);
440e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Change the setting as a trusted component
441e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2, false);
442e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
443e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Set a default setting as an untrusted component
444e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1,
445e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE, true);
446e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Change the setting as an untrusted component
447e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1,
448e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    FAKE_SETTING_VALUE_2, false);
449e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
450e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Reset to trusted defaults
451e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            resetSettingsViaShell(type,
452e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov                    Settings.RESET_MODE_TRUSTED_DEFAULTS);
453e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
454e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Check whether snapped to trusted defaults
455e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME));
456e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            assertNull(getSetting(type, FAKE_SETTING_NAME_1));
457e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        } finally {
458e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            // Make sure we have a clean slate.
459e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            putSetting(type, FAKE_SETTING_NAME, null);
460e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true);
461e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        }
462e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov    }
463e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov
464683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private void doTestQueryStringInBracketsViaProviderApiForType(int type) {
465683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Make sure we have a clean slate.
466683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        deleteStringViaProviderApi(type, FAKE_SETTING_NAME);
467683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
468683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
469683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Insert the setting.
470683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            final Uri uri = insertStringViaProviderApi(type, FAKE_SETTING_NAME,
471683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    FAKE_SETTING_VALUE, false);
472683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            Uri expectUri = Uri.withAppendedPath(getBaseUriForType(type), FAKE_SETTING_NAME);
473683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            assertEquals("Did not get expected Uri.", expectUri, uri);
474683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
475683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Make sure the first setting is there.
4762849465ee19febd5135cb6ab8cb548a3c8ac6a24Svetoslav            String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME, true, false);
477683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue);
478683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } finally {
479683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Clean up.
480683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            deleteStringViaProviderApi(type, FAKE_SETTING_NAME);
481683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
482683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
483683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
484683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private void toTestBulkInsertViaProviderApiForType(int type) {
485683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Make sure we have a clean slate.
486683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        deleteStringViaProviderApi(type, FAKE_SETTING_NAME);
487683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1);
4883a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki        deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2);
489683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
490683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
491683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            Uri uri = getBaseUriForType(type);
4923a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            ContentValues[] allValues = new ContentValues[3];
493683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
494683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Insert the first setting.
495683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            ContentValues firstValues = new ContentValues();
496683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            firstValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME);
497683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            firstValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE);
498683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            allValues[0] = firstValues;
499683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
5003a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            // Insert the second setting.
501683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            ContentValues secondValues = new ContentValues();
502683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            secondValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_1);
503683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            secondValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_1);
504683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            allValues[1] = secondValues;
505683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
5063a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            // Insert the third setting. (null)
5073a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            ContentValues thirdValues = new ContentValues();
5083a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            thirdValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_2);
5093a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            thirdValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_2);
5103a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            allValues[2] = thirdValues;
5113a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki
512683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Verify insertion count.
513683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            final int insertCount = getContext().getContentResolver().bulkInsert(uri, allValues);
5143a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            assertSame("Couldn't insert both values", 3, insertCount);
515683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
516683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Make sure the first setting is there.
517683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME);
518683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            assertEquals("First setting must be present", FAKE_SETTING_VALUE, firstValue);
519683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
520683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Make sure the second setting is there.
521683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            String secondValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_1);
522683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            assertEquals("Second setting must be present", FAKE_SETTING_VALUE_1, secondValue);
5233a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki
5243a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            // Make sure the third setting is there.
5253a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            String thirdValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_2);
5263a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            assertEquals("Third setting must be present", FAKE_SETTING_VALUE_2, thirdValue);
527683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } finally {
528683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Clean up.
529683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            deleteStringViaProviderApi(type, FAKE_SETTING_NAME);
530683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1);
5313a2c3578ba5bf8642c994fa357a96eaa4a38cdc9Makoto Onuki            deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2);
532683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
533683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
534683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
535683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private void doTestQueryUpdateDeleteGlobalViaProviderApiForType(int type) throws Exception {
536683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Make sure it is not there.
537683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        deleteStringViaProviderApi(type, FAKE_SETTING_NAME);
538683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
539683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Now selection should return nothing.
540683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        String value = queryStringViaProviderApi(type, FAKE_SETTING_NAME);
541683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        assertNull("Setting should not be present.", value);
542683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
543683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Insert the setting.
544683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        Uri uri = insertStringViaProviderApi(type,
545683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false);
546683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        Uri expectUri = Uri.withAppendedPath(getBaseUriForType(type), FAKE_SETTING_NAME);
547683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        assertEquals("Did not get expected Uri.", expectUri, uri);
548683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
549683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Now selection should return the setting.
550683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        value = queryStringViaProviderApi(type, FAKE_SETTING_NAME);
551683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        assertEquals("Setting should be present.", FAKE_SETTING_VALUE, value);
552683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
553683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Update the setting.
554683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        final int changeCount = updateStringViaProviderApiSetting(type,
555683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                FAKE_SETTING_NAME, FAKE_SETTING_VALUE_1);
556683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        assertEquals("Did not get expected change count.", 1, changeCount);
557683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
558683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Now selection should return the new setting.
559683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        value = queryStringViaProviderApi(type, FAKE_SETTING_NAME);
560683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        assertEquals("Setting should be present.", FAKE_SETTING_VALUE_1, value);
561683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
562683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Delete the setting.
563683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        final int deletedCount = deleteStringViaProviderApi(type,
564683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                FAKE_SETTING_NAME);
565683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        assertEquals("Did not get expected deleted count", 1, deletedCount);
566683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
567683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        // Now selection should return nothing.
568683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        value = queryStringViaProviderApi(type, FAKE_SETTING_NAME);
569683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        assertNull("Setting should not be present.", value);
570683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
571683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
572683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private void performSetAndGetSettingTestViaFrontEndApi(int type, int userId)
573683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            throws Exception {
574683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
575683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Change the setting and assert a successful change.
576683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            setSettingViaFrontEndApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME,
577683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    FAKE_SETTING_VALUE, userId);
578683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } finally {
579683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Remove the setting.
580683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            setStringViaFrontEndApiSetting(type, FAKE_SETTING_NAME, null, userId);
581683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
582683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
583683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
584683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private void performSetAndGetSettingTestViaProviderApi(int type)
585683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            throws Exception {
586683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
587683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Change the setting and assert a successful change.
588683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            setSettingViaProviderApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME,
589683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    FAKE_SETTING_VALUE, true);
590683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } finally {
591683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            // Remove the setting.
592683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            setSettingViaProviderApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, null,
593683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    true);
594683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
595683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
596683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
597683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private void setSettingViaFrontEndApiAndAssertSuccessfulChange(final int type,
598683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            final String name, final String value, final int userId) throws Exception {
599e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        setSettingAndAssertSuccessfulChange(() -> {
600e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            setStringViaFrontEndApiSetting(type, name, value, userId);
601683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }, type, name, value, userId);
602683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
603683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
604683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private void setSettingViaProviderApiAndAssertSuccessfulChange(final int type,
605683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            final String name, final String value, final boolean withTableRowUri)
606683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            throws Exception {
607e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov        setSettingAndAssertSuccessfulChange(() -> {
608e080da9ee027fcd030aa92ea26fd0ed9f031674fSvetoslav Ganov            insertStringViaProviderApi(type, name, value, withTableRowUri);
60943765b77a0286403fd9f7f5305219f0d9a10c953Xiaohui Chen        }, type, name, value, UserHandle.USER_SYSTEM);
610683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
611683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
612683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private void setSettingAndAssertSuccessfulChange(Runnable setCommand, final int type,
613683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            final String name, final String value, final int userId) throws Exception {
614683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        ContentResolver contentResolver = getContext().getContentResolver();
615683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
616683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        final Uri settingUri = getBaseUriForType(type);
617683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
618683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        final AtomicBoolean success = new AtomicBoolean();
619683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
620683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        ContentObserver contentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) {
621683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            public void onChange(boolean selfChange, Uri changeUri, int changeId) {
622683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                Log.i(LOG_TAG, "onChange(" + selfChange + ", " + changeUri + ", " + changeId + ")");
623683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                assertEquals("Wrong change Uri", changeUri, settingUri);
624683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                assertEquals("Wrong user id", userId, changeId);
625683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                String changeValue = getStringViaFrontEndApiSetting(type, name, userId);
626683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                assertEquals("Wrong setting value", value, changeValue);
627683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
628683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                success.set(true);
629683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
630683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                synchronized (mLock) {
631683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    mLock.notifyAll();
632683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                }
633683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            }
634683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        };
635683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
636683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        contentResolver.registerContentObserver(settingUri, false, contentObserver, userId);
637683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
638683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
639683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            setCommand.run();
640683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
641683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            final long startTimeMillis = SystemClock.uptimeMillis();
642683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            synchronized (mLock) {
643683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                if (success.get()) {
644683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    return;
645683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                }
646683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
647683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                if (elapsedTimeMillis > WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS) {
648683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    fail("Could not change setting for "
649683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                            + WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS + " ms");
650683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                }
651683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                final long remainingTimeMillis = WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS
652683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                        - elapsedTimeMillis;
653683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                try {
654683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    mLock.wait(remainingTimeMillis);
655683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                } catch (InterruptedException ie) {
656683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    /* ignore */
657683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                }
658683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            }
659683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } finally {
660683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            contentResolver.unregisterContentObserver(contentObserver);
661683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
662683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
663683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
664683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    private void queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(int type,
665683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            String name) {
666683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        Uri uri = getBaseUriForType(type);
667683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
668683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        Cursor cursor = getContext().getContentResolver().query(uri, NAME_VALUE_COLUMNS,
669683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                null, null, null);
670683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
671683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        if (cursor == null || !cursor.moveToFirst()) {
672683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            fail("Nothing selected");
673683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
674683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
675683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        try {
676683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME);
677683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
678683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            while (cursor.moveToNext()) {
679683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                String currentName = cursor.getString(nameColumnIdx);
680683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                if (name.equals(currentName)) {
681683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                    return;
682683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav                }
683683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            }
684683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav
685683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            fail("Not found setting: " + name);
686683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        } finally {
687683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav            cursor.close();
688683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav        }
689683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav    }
69083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
69183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    @Test
69283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    public void testUpdateLocationProvidersAllowedLocked_enableProviders() throws Exception {
69383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        setSettingViaFrontEndApiAndAssertSuccessfulChange(
69483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE,
69583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                Settings.Secure.LOCATION_MODE,
69683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                String.valueOf(Settings.Secure.LOCATION_MODE_OFF),
69783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                UserHandle.USER_SYSTEM);
69883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
69983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        // Enable one provider
70083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        updateStringViaProviderApiSetting(
70183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "+gps");
70283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
70383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        assertEquals(
70483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "Wrong location providers",
70583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "gps",
70683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                queryStringViaProviderApi(
70783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                        SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
70883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
70983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        // Enable a list of providers, including the one that is already enabled
71083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        updateStringViaProviderApiSetting(
71183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE,
71283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
71383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "+gps,+network,+network");
71483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
71583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        assertEquals(
71683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "Wrong location providers",
71783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "gps,network",
71883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                queryStringViaProviderApi(
71983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                        SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
72083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    }
72183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
72283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    @Test
72383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    public void testUpdateLocationProvidersAllowedLocked_disableProviders() throws Exception {
72483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        setSettingViaFrontEndApiAndAssertSuccessfulChange(
72583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE,
72683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                Settings.Secure.LOCATION_MODE,
72783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                String.valueOf(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY),
72883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                UserHandle.USER_SYSTEM);
72983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
73083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        // Disable providers that were enabled
73183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        updateStringViaProviderApiSetting(
73283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE,
73383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
73483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "-gps,-network");
73583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
73683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        assertEquals(
73783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "Wrong location providers",
73883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "",
73983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                queryStringViaProviderApi(
74083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                        SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
74183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
74283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        // Disable a provider that was not enabled
74383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        updateStringViaProviderApiSetting(
74483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE,
74583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
74683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "-test");
74783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
74883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        assertEquals(
74983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "Wrong location providers",
75083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "",
75183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                queryStringViaProviderApi(
75283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                        SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
75383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    }
75483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
75583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    @Test
75683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    public void testUpdateLocationProvidersAllowedLocked_enableAndDisable() throws Exception {
75783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        setSettingViaFrontEndApiAndAssertSuccessfulChange(
75883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE,
75983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                Settings.Secure.LOCATION_MODE,
76083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                String.valueOf(Settings.Secure.LOCATION_MODE_OFF),
76183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                UserHandle.USER_SYSTEM);
76283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
76383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        updateStringViaProviderApiSetting(
76483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE,
76583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
76683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "+gps,+network,+test");
76783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        updateStringViaProviderApiSetting(
76883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED, "-test");
76983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
77083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        assertEquals(
77183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "Wrong location providers",
77283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "gps,network",
77383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                queryStringViaProviderApi(
77483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                        SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
77583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    }
77683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
77783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    @Test
77883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    public void testUpdateLocationProvidersAllowedLocked_invalidInput() throws Exception {
77983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        setSettingViaFrontEndApiAndAssertSuccessfulChange(
78083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE,
78183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                Settings.Secure.LOCATION_MODE,
78283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                String.valueOf(Settings.Secure.LOCATION_MODE_OFF),
78383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                UserHandle.USER_SYSTEM);
78483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
78583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        // update providers with a invalid string
78683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        updateStringViaProviderApiSetting(
78783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                SETTING_TYPE_SECURE,
78883e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                Settings.Secure.LOCATION_PROVIDERS_ALLOWED,
78983e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "+gps, invalid-string");
79083e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie
79183e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        // Verifies providers list does not change
79283e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie        assertEquals(
79383e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "Wrong location providers",
79483e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                "",
79583e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                queryStringViaProviderApi(
79683e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie                        SETTING_TYPE_SECURE, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
79783e03f55597a69bf1e1f2df2cd24e83e84d21914Maggie    }
798683914bfb13908bf380a25258cd45bcf43f13dc9Svetoslav}
799