| /* |
| * Copyright (C) 2015 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.providers.settings; |
| |
| import static junit.framework.Assert.assertEquals; |
| import static junit.framework.Assert.assertSame; |
| import static junit.framework.Assert.assertNull; |
| import static junit.framework.Assert.fail; |
| |
| import android.content.ContentResolver; |
| import android.content.ContentValues; |
| import android.database.ContentObserver; |
| import android.database.Cursor; |
| import android.net.Uri; |
| import android.os.Handler; |
| import android.os.Looper; |
| import android.os.SystemClock; |
| import android.os.UserHandle; |
| import android.provider.Settings; |
| import android.util.Log; |
| import org.junit.Test; |
| |
| import java.util.concurrent.atomic.AtomicBoolean; |
| |
| /** |
| * Tests for the SettingContentProvider. |
| * |
| * Before you run this test you must add a secondary user. |
| */ |
| public class SettingsProviderTest extends BaseSettingsProviderTest { |
| private static final String LOG_TAG = "SettingsProviderTest"; |
| |
| private static final long WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS = 2000; // 2 sec |
| |
| private static final String[] NAME_VALUE_COLUMNS = new String[]{ |
| Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE |
| }; |
| |
| private final Object mLock = new Object(); |
| |
| @Test |
| public void testSetAndGetGlobalViaFrontEndApiForSystemUser() throws Exception { |
| performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, UserHandle.USER_SYSTEM); |
| } |
| |
| @Test |
| public void testSetAndGetGlobalViaFrontEndApiForNonSystemUser() throws Exception { |
| final int secondaryUserId = getSecondaryUserId(); |
| if (secondaryUserId == UserHandle.USER_SYSTEM) { |
| Log.w(LOG_TAG, "No secondary user. Skipping " |
| + "testSetAndGetGlobalViaFrontEndApiForNonSystemUser"); |
| return; |
| } |
| performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, secondaryUserId); |
| } |
| |
| @Test |
| public void testSetAndGetSecureViaFrontEndApiForSystemUser() throws Exception { |
| performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, UserHandle.USER_SYSTEM); |
| } |
| |
| @Test |
| public void testSetAndGetSecureViaFrontEndApiForNonSystemUser() throws Exception { |
| final int secondaryUserId = getSecondaryUserId(); |
| if (secondaryUserId == UserHandle.USER_SYSTEM) { |
| Log.w(LOG_TAG, "No secondary user. Skipping " |
| + "testSetAndGetSecureViaFrontEndApiForNonSystemUser"); |
| return; |
| } |
| performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, secondaryUserId); |
| } |
| |
| @Test |
| public void testSetAndGetSystemViaFrontEndApiForSystemUser() throws Exception { |
| performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, UserHandle.USER_SYSTEM); |
| } |
| |
| @Test |
| public void testSetAndGetSystemViaFrontEndApiForNonSystemUser() throws Exception { |
| final int secondaryUserId = getSecondaryUserId(); |
| if (secondaryUserId == UserHandle.USER_SYSTEM) { |
| Log.w(LOG_TAG, "No secondary user. Skipping " |
| + "testSetAndGetSystemViaFrontEndApiForNonSystemUser"); |
| return; |
| } |
| performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, secondaryUserId); |
| } |
| |
| @Test |
| public void testSetAndGetGlobalViaProviderApi() throws Exception { |
| performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_GLOBAL); |
| } |
| |
| @Test |
| public void testSetAndGetSecureViaProviderApi() throws Exception { |
| performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_SECURE); |
| } |
| |
| @Test |
| public void testSetAndGetSystemViaProviderApi() throws Exception { |
| performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_SYSTEM); |
| } |
| |
| @Test |
| public void testSelectAllGlobalViaProviderApi() throws Exception { |
| setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_GLOBAL, |
| FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false); |
| try { |
| queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_GLOBAL, |
| FAKE_SETTING_NAME); |
| } finally { |
| deleteStringViaProviderApi(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME); |
| } |
| } |
| |
| @Test |
| public void testSelectAllSecureViaProviderApi() throws Exception { |
| setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_SECURE, |
| FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false); |
| try { |
| queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_SECURE, |
| FAKE_SETTING_NAME); |
| } finally { |
| deleteStringViaProviderApi(SETTING_TYPE_SECURE, FAKE_SETTING_NAME); |
| } |
| } |
| |
| @Test |
| public void testSelectAllSystemViaProviderApi() throws Exception { |
| setSettingViaProviderApiAndAssertSuccessfulChange(SETTING_TYPE_SYSTEM, |
| FAKE_SETTING_NAME, FAKE_SETTING_VALUE, true); |
| try { |
| queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(SETTING_TYPE_SYSTEM, |
| FAKE_SETTING_NAME); |
| } finally { |
| deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME); |
| } |
| } |
| |
| @Test |
| public void testQueryUpdateDeleteGlobalViaProviderApi() throws Exception { |
| doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_GLOBAL); |
| } |
| |
| @Test |
| public void testQueryUpdateDeleteSecureViaProviderApi() throws Exception { |
| doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SECURE); |
| } |
| |
| @Test |
| public void testQueryUpdateDeleteSystemViaProviderApi() throws Exception { |
| doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SYSTEM); |
| } |
| |
| @Test |
| public void testBulkInsertGlobalViaProviderApi() throws Exception { |
| toTestBulkInsertViaProviderApiForType(SETTING_TYPE_GLOBAL); |
| } |
| |
| @Test |
| public void testBulkInsertSystemViaProviderApi() throws Exception { |
| toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SYSTEM); |
| } |
| |
| @Test |
| public void testBulkInsertSecureViaProviderApi() throws Exception { |
| toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SECURE); |
| } |
| |
| @Test |
| public void testAppCannotRunsSystemOutOfMemoryWritingSystemSettings() throws Exception { |
| int insertedCount = 0; |
| try { |
| for (; insertedCount < 1200; insertedCount++) { |
| Log.w(LOG_TAG, "Adding app specific setting: " + insertedCount); |
| insertStringViaProviderApi(SETTING_TYPE_SYSTEM, |
| String.valueOf(insertedCount), FAKE_SETTING_VALUE, false); |
| } |
| fail("Adding app specific settings must be bound."); |
| } catch (Exception e) { |
| // expected |
| } finally { |
| for (; insertedCount >= 0; insertedCount--) { |
| Log.w(LOG_TAG, "Removing app specific setting: " + insertedCount); |
| deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, |
| String.valueOf(insertedCount)); |
| } |
| } |
| } |
| |
| @Test |
| public void testQueryStringInBracketsGlobalViaProviderApiForType() throws Exception { |
| doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_GLOBAL); |
| } |
| |
| @Test |
| public void testQueryStringInBracketsSecureViaProviderApiForType() throws Exception { |
| doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SECURE); |
| } |
| |
| @Test |
| public void testQueryStringInBracketsSystemViaProviderApiForType() throws Exception { |
| doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SYSTEM); |
| } |
| |
| @Test |
| public void testQueryStringWithAppendedNameToUriViaProviderApi() throws Exception { |
| // Make sure we have a clean slate. |
| deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME); |
| |
| try { |
| // Insert the setting. |
| final Uri uri = insertStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME, |
| FAKE_SETTING_VALUE, false); |
| Uri expectUri = Uri.withAppendedPath(getBaseUriForType(SETTING_TYPE_SYSTEM), |
| FAKE_SETTING_NAME); |
| assertEquals("Did not get expected Uri.", expectUri, uri); |
| |
| // Make sure the first setting is there. |
| String firstValue = queryStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME, |
| false, true); |
| assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue); |
| } finally { |
| // Clean up. |
| deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME); |
| } |
| } |
| |
| @Test |
| public void testResetModePackageDefaultsGlobal() throws Exception { |
| testResetModePackageDefaultsCommon(SETTING_TYPE_GLOBAL); |
| } |
| |
| @Test |
| public void testResetModePackageDefaultsSecure() throws Exception { |
| testResetModePackageDefaultsCommon(SETTING_TYPE_SECURE); |
| } |
| |
| private void testResetModePackageDefaultsCommon(int type) throws Exception { |
| // Make sure we have a clean slate. |
| setSettingViaShell(type, FAKE_SETTING_NAME, null, true); |
| try { |
| // Set a value but don't make it the default |
| setSettingViaShell(type, FAKE_SETTING_NAME, |
| FAKE_SETTING_VALUE, false); |
| |
| // Reset the changes made by the "shell/root" package |
| resetToDefaultsViaShell(type, "shell"); |
| resetToDefaultsViaShell(type, "root"); |
| |
| // Make sure the old APIs don't set defaults |
| assertNull(getSetting(type, FAKE_SETTING_NAME)); |
| |
| // Set a value and make it the default |
| setSettingViaShell(type, FAKE_SETTING_NAME, |
| FAKE_SETTING_VALUE, true); |
| // Change the setting from the default |
| setSettingViaShell(type, FAKE_SETTING_NAME, |
| FAKE_SETTING_VALUE_2, false); |
| |
| // Reset the changes made by this package |
| resetToDefaultsViaShell(type, "shell"); |
| resetToDefaultsViaShell(type, "root"); |
| |
| // Make sure the old APIs don't set defaults |
| assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME)); |
| } finally { |
| // Make sure we have a clean slate. |
| setSettingViaShell(type, FAKE_SETTING_NAME, null, true); |
| } |
| } |
| |
| @Test |
| public void testResetModePackageDefaultsWithTokensGlobal() throws Exception { |
| testResetModePackageDefaultsWithTokensCommon(SETTING_TYPE_GLOBAL); |
| } |
| |
| @Test |
| public void testResetModePackageDefaultsWithTokensSecure() throws Exception { |
| testResetModePackageDefaultsWithTokensCommon(SETTING_TYPE_SECURE); |
| } |
| |
| private void testResetModePackageDefaultsWithTokensCommon(int type) throws Exception { |
| // Make sure we have a clean slate. |
| setSettingViaShell(type, FAKE_SETTING_NAME, null, true); |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); |
| try { |
| // Set a default value |
| setSettingViaShell(type, FAKE_SETTING_NAME, |
| FAKE_SETTING_VALUE, true); |
| // Change the default and associate a token |
| setSettingViaShell(type, FAKE_SETTING_NAME, |
| FAKE_SETTING_VALUE_2, "TOKEN1", false); |
| |
| // Set a default value |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, |
| FAKE_SETTING_VALUE, "TOKEN2", true); |
| // Change the default and associate a token |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, |
| FAKE_SETTING_VALUE_2, "TOKEN2", false); |
| |
| // Reset settings associated with TOKEN1 |
| resetToDefaultsViaShell(type, "shell", "TOKEN1"); |
| resetToDefaultsViaShell(type, "root", "TOKEN1"); |
| |
| // Make sure TOKEN1 settings are reset |
| assertEquals(FAKE_SETTING_VALUE, getSetting(type, |
| FAKE_SETTING_NAME)); |
| |
| // Make sure TOKEN2 settings are not reset |
| assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, |
| FAKE_SETTING_NAME_1)); |
| |
| // Reset settings associated with TOKEN2 |
| resetToDefaultsViaShell(type, "shell", "TOKEN2"); |
| resetToDefaultsViaShell(type, "root", "TOKEN2"); |
| |
| // Make sure TOKEN2 settings are reset |
| assertEquals(FAKE_SETTING_VALUE, getSetting(type, |
| FAKE_SETTING_NAME_1)); |
| } finally { |
| // Make sure we have a clean slate. |
| setSettingViaShell(type, FAKE_SETTING_NAME, null, true); |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); |
| } |
| } |
| |
| @Test |
| public void testResetModeUntrustedDefaultsGlobal() throws Exception { |
| testResetModeUntrustedDefaultsCommon(SETTING_TYPE_GLOBAL); |
| } |
| |
| @Test |
| public void testResetModeUntrustedDefaultsSecure() throws Exception { |
| testResetModeUntrustedDefaultsCommon(SETTING_TYPE_SECURE); |
| } |
| |
| private void testResetModeUntrustedDefaultsCommon(int type) throws Exception { |
| // Make sure we have a clean slate. |
| putSetting(type, FAKE_SETTING_NAME, null); |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); |
| try { |
| // Set a default setting as a trusted component |
| putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE); |
| // Change the setting as a trusted component |
| putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2); |
| |
| // Set a default setting as an untrusted component |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, |
| FAKE_SETTING_VALUE, true); |
| // Change the setting as an untrusted component |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, |
| FAKE_SETTING_VALUE_2, false); |
| |
| // Reset the untrusted changes to defaults |
| resetSettingsViaShell(type, |
| Settings.RESET_MODE_UNTRUSTED_DEFAULTS); |
| |
| // Check whether only the untrusted changes set to defaults |
| assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, FAKE_SETTING_NAME)); |
| assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME_1)); |
| } finally { |
| // Make sure we have a clean slate. |
| putSetting(type, FAKE_SETTING_NAME, null); |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); |
| } |
| } |
| |
| @Test |
| public void testResetModeUntrustedClearGlobal() throws Exception { |
| testResetModeUntrustedClearCommon(SETTING_TYPE_GLOBAL); |
| } |
| |
| @Test |
| public void testResetModeUntrustedClearSecure() throws Exception { |
| testResetModeUntrustedClearCommon(SETTING_TYPE_SECURE); |
| } |
| |
| private void testResetModeUntrustedClearCommon(int type) throws Exception { |
| // Make sure we have a clean slate. |
| putSetting(type, FAKE_SETTING_NAME, null); |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); |
| try { |
| // Set a default setting as a trusted component |
| putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE); |
| // Change the setting as a trusted component |
| putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2); |
| |
| // Set a default setting as an untrusted component |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, |
| FAKE_SETTING_VALUE, true); |
| // Change the setting as an untrusted component |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, |
| FAKE_SETTING_VALUE_2, false); |
| |
| // Clear the untrusted changes |
| resetSettingsViaShell(type, |
| Settings.RESET_MODE_UNTRUSTED_CHANGES); |
| |
| // Check whether only the untrusted changes set to defaults |
| assertEquals(FAKE_SETTING_VALUE_2, getSetting(type, FAKE_SETTING_NAME)); |
| assertNull(getSetting(type, FAKE_SETTING_NAME_1)); |
| } finally { |
| // Make sure we have a clean slate. |
| putSetting(type, FAKE_SETTING_NAME, null); |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); |
| } |
| } |
| |
| @Test |
| public void testResetModeTrustedDefaultsGlobal() throws Exception { |
| testResetModeTrustedDefaultsCommon(SETTING_TYPE_GLOBAL); |
| } |
| |
| @Test |
| public void testResetModeTrustedDefaultsSecure() throws Exception { |
| testResetModeTrustedDefaultsCommon(SETTING_TYPE_SECURE); |
| } |
| |
| private void testResetModeTrustedDefaultsCommon(int type) throws Exception { |
| // Make sure we have a clean slate. |
| putSetting(type, FAKE_SETTING_NAME, null); |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); |
| try { |
| // Set a default setting as a trusted component |
| putSetting(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE); |
| // Change the setting as a trusted component |
| setSettingViaShell(type, FAKE_SETTING_NAME, FAKE_SETTING_VALUE_2, false); |
| |
| // Set a default setting as an untrusted component |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, |
| FAKE_SETTING_VALUE, true); |
| // Change the setting as an untrusted component |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, |
| FAKE_SETTING_VALUE_2, false); |
| |
| // Reset to trusted defaults |
| resetSettingsViaShell(type, |
| Settings.RESET_MODE_TRUSTED_DEFAULTS); |
| |
| // Check whether snapped to trusted defaults |
| assertEquals(FAKE_SETTING_VALUE, getSetting(type, FAKE_SETTING_NAME)); |
| assertNull(getSetting(type, FAKE_SETTING_NAME_1)); |
| } finally { |
| // Make sure we have a clean slate. |
| putSetting(type, FAKE_SETTING_NAME, null); |
| setSettingViaShell(type, FAKE_SETTING_NAME_1, null, true); |
| } |
| } |
| |
| private void doTestQueryStringInBracketsViaProviderApiForType(int type) { |
| // Make sure we have a clean slate. |
| deleteStringViaProviderApi(type, FAKE_SETTING_NAME); |
| |
| try { |
| // Insert the setting. |
| final Uri uri = insertStringViaProviderApi(type, FAKE_SETTING_NAME, |
| FAKE_SETTING_VALUE, false); |
| Uri expectUri = Uri.withAppendedPath(getBaseUriForType(type), FAKE_SETTING_NAME); |
| assertEquals("Did not get expected Uri.", expectUri, uri); |
| |
| // Make sure the first setting is there. |
| String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME, true, false); |
| assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue); |
| } finally { |
| // Clean up. |
| deleteStringViaProviderApi(type, FAKE_SETTING_NAME); |
| } |
| } |
| |
| private void toTestBulkInsertViaProviderApiForType(int type) { |
| // Make sure we have a clean slate. |
| deleteStringViaProviderApi(type, FAKE_SETTING_NAME); |
| deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1); |
| deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2); |
| |
| try { |
| Uri uri = getBaseUriForType(type); |
| ContentValues[] allValues = new ContentValues[3]; |
| |
| // Insert the first setting. |
| ContentValues firstValues = new ContentValues(); |
| firstValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME); |
| firstValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE); |
| allValues[0] = firstValues; |
| |
| // Insert the second setting. |
| ContentValues secondValues = new ContentValues(); |
| secondValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_1); |
| secondValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_1); |
| allValues[1] = secondValues; |
| |
| // Insert the third setting. (null) |
| ContentValues thirdValues = new ContentValues(); |
| thirdValues.put(Settings.NameValueTable.NAME, FAKE_SETTING_NAME_2); |
| thirdValues.put(Settings.NameValueTable.VALUE, FAKE_SETTING_VALUE_2); |
| allValues[2] = thirdValues; |
| |
| // Verify insertion count. |
| final int insertCount = getContext().getContentResolver().bulkInsert(uri, allValues); |
| assertSame("Couldn't insert both values", 3, insertCount); |
| |
| // Make sure the first setting is there. |
| String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME); |
| assertEquals("First setting must be present", FAKE_SETTING_VALUE, firstValue); |
| |
| // Make sure the second setting is there. |
| String secondValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_1); |
| assertEquals("Second setting must be present", FAKE_SETTING_VALUE_1, secondValue); |
| |
| // Make sure the third setting is there. |
| String thirdValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME_2); |
| assertEquals("Third setting must be present", FAKE_SETTING_VALUE_2, thirdValue); |
| } finally { |
| // Clean up. |
| deleteStringViaProviderApi(type, FAKE_SETTING_NAME); |
| deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1); |
| deleteStringViaProviderApi(type, FAKE_SETTING_NAME_2); |
| } |
| } |
| |
| private void doTestQueryUpdateDeleteGlobalViaProviderApiForType(int type) throws Exception { |
| // Make sure it is not there. |
| deleteStringViaProviderApi(type, FAKE_SETTING_NAME); |
| |
| // Now selection should return nothing. |
| String value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); |
| assertNull("Setting should not be present.", value); |
| |
| // Insert the setting. |
| Uri uri = insertStringViaProviderApi(type, |
| FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false); |
| Uri expectUri = Uri.withAppendedPath(getBaseUriForType(type), FAKE_SETTING_NAME); |
| assertEquals("Did not get expected Uri.", expectUri, uri); |
| |
| // Now selection should return the setting. |
| value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); |
| assertEquals("Setting should be present.", FAKE_SETTING_VALUE, value); |
| |
| // Update the setting. |
| final int changeCount = updateStringViaProviderApiSetting(type, |
| FAKE_SETTING_NAME, FAKE_SETTING_VALUE_1); |
| assertEquals("Did not get expected change count.", 1, changeCount); |
| |
| // Now selection should return the new setting. |
| value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); |
| assertEquals("Setting should be present.", FAKE_SETTING_VALUE_1, value); |
| |
| // Delete the setting. |
| final int deletedCount = deleteStringViaProviderApi(type, |
| FAKE_SETTING_NAME); |
| assertEquals("Did not get expected deleted count", 1, deletedCount); |
| |
| // Now selection should return nothing. |
| value = queryStringViaProviderApi(type, FAKE_SETTING_NAME); |
| assertNull("Setting should not be present.", value); |
| } |
| |
| private void performSetAndGetSettingTestViaFrontEndApi(int type, int userId) |
| throws Exception { |
| try { |
| // Change the setting and assert a successful change. |
| setSettingViaFrontEndApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, |
| FAKE_SETTING_VALUE, userId); |
| } finally { |
| // Remove the setting. |
| setStringViaFrontEndApiSetting(type, FAKE_SETTING_NAME, null, userId); |
| } |
| } |
| |
| private void performSetAndGetSettingTestViaProviderApi(int type) |
| throws Exception { |
| try { |
| // Change the setting and assert a successful change. |
| setSettingViaProviderApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, |
| FAKE_SETTING_VALUE, true); |
| } finally { |
| // Remove the setting. |
| setSettingViaProviderApiAndAssertSuccessfulChange(type, FAKE_SETTING_NAME, null, |
| true); |
| } |
| } |
| |
| private void setSettingViaFrontEndApiAndAssertSuccessfulChange(final int type, |
| final String name, final String value, final int userId) throws Exception { |
| setSettingAndAssertSuccessfulChange(() -> { |
| setStringViaFrontEndApiSetting(type, name, value, userId); |
| }, type, name, value, userId); |
| } |
| |
| private void setSettingViaProviderApiAndAssertSuccessfulChange(final int type, |
| final String name, final String value, final boolean withTableRowUri) |
| throws Exception { |
| setSettingAndAssertSuccessfulChange(() -> { |
| insertStringViaProviderApi(type, name, value, withTableRowUri); |
| }, type, name, value, UserHandle.USER_SYSTEM); |
| } |
| |
| private void setSettingAndAssertSuccessfulChange(Runnable setCommand, final int type, |
| final String name, final String value, final int userId) throws Exception { |
| ContentResolver contentResolver = getContext().getContentResolver(); |
| |
| final Uri settingUri = getBaseUriForType(type); |
| |
| final AtomicBoolean success = new AtomicBoolean(); |
| |
| ContentObserver contentObserver = new ContentObserver(new Handler(Looper.getMainLooper())) { |
| public void onChange(boolean selfChange, Uri changeUri, int changeId) { |
| Log.i(LOG_TAG, "onChange(" + selfChange + ", " + changeUri + ", " + changeId + ")"); |
| assertEquals("Wrong change Uri", changeUri, settingUri); |
| assertEquals("Wrong user id", userId, changeId); |
| String changeValue = getStringViaFrontEndApiSetting(type, name, userId); |
| assertEquals("Wrong setting value", value, changeValue); |
| |
| success.set(true); |
| |
| synchronized (mLock) { |
| mLock.notifyAll(); |
| } |
| } |
| }; |
| |
| contentResolver.registerContentObserver(settingUri, false, contentObserver, userId); |
| |
| try { |
| setCommand.run(); |
| |
| final long startTimeMillis = SystemClock.uptimeMillis(); |
| synchronized (mLock) { |
| if (success.get()) { |
| return; |
| } |
| final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis; |
| if (elapsedTimeMillis > WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS) { |
| fail("Could not change setting for " |
| + WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS + " ms"); |
| } |
| final long remainingTimeMillis = WAIT_FOR_SETTING_URI_CHANGE_TIMEOUT_MILLIS |
| - elapsedTimeMillis; |
| try { |
| mLock.wait(remainingTimeMillis); |
| } catch (InterruptedException ie) { |
| /* ignore */ |
| } |
| } |
| } finally { |
| contentResolver.unregisterContentObserver(contentObserver); |
| } |
| } |
| |
| private void queryAllSettingsViaProviderApiSettingAndAssertSettingPresent(int type, |
| String name) { |
| Uri uri = getBaseUriForType(type); |
| |
| Cursor cursor = getContext().getContentResolver().query(uri, NAME_VALUE_COLUMNS, |
| null, null, null); |
| |
| if (cursor == null || !cursor.moveToFirst()) { |
| fail("Nothing selected"); |
| } |
| |
| try { |
| final int nameColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.NAME); |
| |
| while (cursor.moveToNext()) { |
| String currentName = cursor.getString(nameColumnIdx); |
| if (name.equals(currentName)) { |
| return; |
| } |
| } |
| |
| fail("Not found setting: " + name); |
| } finally { |
| cursor.close(); |
| } |
| } |
| } |