diff options
Diffstat (limited to 'packages/SettingsProvider/test')
5 files changed, 794 insertions, 0 deletions
diff --git a/packages/SettingsProvider/test/Android.mk b/packages/SettingsProvider/test/Android.mk new file mode 100644 index 0000000..01c6ccf --- /dev/null +++ b/packages/SettingsProvider/test/Android.mk @@ -0,0 +1,13 @@ +LOCAL_PATH:= $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := SettingsProviderTest + +LOCAL_MODULE_TAGS := tests + +LOCAL_CERTIFICATE := platform + +include $(BUILD_PACKAGE)
\ No newline at end of file diff --git a/packages/SettingsProvider/test/AndroidManifest.xml b/packages/SettingsProvider/test/AndroidManifest.xml new file mode 100644 index 0000000..7a86b5f --- /dev/null +++ b/packages/SettingsProvider/test/AndroidManifest.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.providers.setting.test"> + + <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" /> + + <uses-permission android:name="android.permission.WRITE_SETTINGS"/> + <uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS"/> + <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"/> + <uses-permission android:name="android.permission.MANAGE_USERS"/> + + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation + android:name="android.test.InstrumentationTestRunner" + android:targetPackage="com.android.providers.setting.test" + android:label="Settings Provider Tests" /> +</manifest> diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java new file mode 100644 index 0000000..8473db4 --- /dev/null +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java @@ -0,0 +1,196 @@ +/* + * 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 android.content.ContentResolver; +import android.content.ContentValues; +import android.content.Context; +import android.content.pm.UserInfo; +import android.database.Cursor; +import android.net.Uri; +import android.os.UserHandle; +import android.os.UserManager; +import android.provider.Settings; +import android.test.AndroidTestCase; + +import java.util.List; + +/** + * Base class for the SettingContentProvider tests. + */ +abstract class BaseSettingsProviderTest extends AndroidTestCase { + protected static final int SETTING_TYPE_GLOBAL = 1; + protected static final int SETTING_TYPE_SECURE = 2; + protected static final int SETTING_TYPE_SYSTEM = 3; + + protected static final String FAKE_SETTING_NAME = "fake_setting_name"; + protected static final String FAKE_SETTING_NAME_1 = "fake_setting_name1"; + protected static final String FAKE_SETTING_VALUE = "fake_setting_value"; + protected static final String FAKE_SETTING_VALUE_1 = "fake_setting_value_1"; + + private static final String[] NAME_VALUE_COLUMNS = new String[] { + Settings.NameValueTable.NAME, Settings.NameValueTable.VALUE + }; + + protected int mSecondaryUserId = UserHandle.USER_OWNER; + + @Override + public void setContext(Context context) { + super.setContext(context); + + UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE); + List<UserInfo> users = userManager.getUsers(); + final int userCount = users.size(); + for (int i = 0; i < userCount; i++) { + UserInfo user = users.get(i); + if (!user.isPrimary() && !user.isManagedProfile()) { + mSecondaryUserId = user.id; + break; + } + } + } + + protected void setStringViaFrontEndApiSetting(int type, String name, String value, int userId) { + ContentResolver contentResolver = getContext().getContentResolver(); + + switch (type) { + case SETTING_TYPE_GLOBAL: { + Settings.Global.putStringForUser(contentResolver, name, value, userId); + } break; + + case SETTING_TYPE_SECURE: { + Settings.Secure.putStringForUser(contentResolver, name, value, userId); + } break; + + case SETTING_TYPE_SYSTEM: { + Settings.System.putStringForUser(contentResolver, name, value, userId); + } break; + + default: { + throw new IllegalArgumentException("Invalid type: " + type); + } + } + } + + protected String getStringViaFrontEndApiSetting(int type, String name, int userId) { + ContentResolver contentResolver = getContext().getContentResolver(); + + switch (type) { + case SETTING_TYPE_GLOBAL: { + return Settings.Global.getStringForUser(contentResolver, name, userId); + } + + case SETTING_TYPE_SECURE: { + return Settings.Secure.getStringForUser(contentResolver, name, userId); + } + + case SETTING_TYPE_SYSTEM: { + return Settings.System.getStringForUser(contentResolver, name, userId); + } + + default: { + throw new IllegalArgumentException("Invalid type: " + type); + } + } + } + + protected Uri insertStringViaProviderApi(int type, String name, String value, + boolean withTableRowUri) { + Uri uri = getBaseUriForType(type); + if (withTableRowUri) { + uri = Uri.withAppendedPath(uri, name); + } + ContentValues values = new ContentValues(); + values.put(Settings.NameValueTable.NAME, name); + values.put(Settings.NameValueTable.VALUE, value); + + return getContext().getContentResolver().insert(uri, values); + } + + protected int deleteStringViaProviderApi(int type, String name) { + Uri uri = getBaseUriForType(type); + return getContext().getContentResolver().delete(uri, "name=?", new String[]{name}); + } + + protected int updateStringViaProviderApiSetting(int type, String name, String value) { + Uri uri = getBaseUriForType(type); + ContentValues values = new ContentValues(); + values.put(Settings.NameValueTable.NAME, name); + values.put(Settings.NameValueTable.VALUE, value); + return getContext().getContentResolver().update(uri, values, "name=?", + new String[]{name}); + } + + protected String queryStringViaProviderApi(int type, String name) { + return queryStringViaProviderApi(type, name, false, false); + } + + protected String queryStringViaProviderApi(int type, String name, boolean queryStringInQuotes, + boolean appendNameToUri) { + final Uri uri; + final String queryString; + final String[] queryArgs; + + if (appendNameToUri) { + uri = Uri.withAppendedPath(getBaseUriForType(type), name); + queryString = null; + queryArgs = null; + } else { + uri = getBaseUriForType(type); + queryString = queryStringInQuotes ? "(name=?)" : "name=?"; + queryArgs = new String[]{name}; + } + + Cursor cursor = getContext().getContentResolver().query(uri, NAME_VALUE_COLUMNS, + queryString, queryArgs, null); + + if (cursor == null) { + return null; + } + + try { + if (cursor.moveToFirst()) { + final int valueColumnIdx = cursor.getColumnIndex(Settings.NameValueTable.VALUE); + return cursor.getString(valueColumnIdx); + } + } finally { + cursor.close(); + } + + return null; + } + + protected static Uri getBaseUriForType(int type) { + switch (type) { + case SETTING_TYPE_GLOBAL: { + return Settings.Global.CONTENT_URI; + } + + case SETTING_TYPE_SECURE: { + return Settings.Secure.CONTENT_URI; + } + + case SETTING_TYPE_SYSTEM: { + return Settings.System.CONTENT_URI; + } + + default: { + throw new IllegalArgumentException("Invalid type: " + type); + } + } + } +} diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java new file mode 100644 index 0000000..d581f3b --- /dev/null +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderPerformanceTest.java @@ -0,0 +1,121 @@ +/* + * 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 android.os.SystemClock; +import android.os.UserHandle; +import android.util.Log; + +/** +* Performance tests for the SettingContentProvider. +*/ +public class SettingsProviderPerformanceTest extends BaseSettingsProviderTest { + private static final String LOG_TAG = "SettingsProviderPerformanceTest"; + + private static final int ITERATION_COUNT = 100; + + private static final int MICRO_SECONDS_IN_MILLISECOND = 1000; + + private static final long MAX_AVERAGE_SET_AND_GET_SETTING_DURATION_MILLIS = 20; + + public void testSetAndGetPerformanceForGlobalViaFrontEndApi() throws Exception { + // Start with a clean slate. + insertStringViaProviderApi(SETTING_TYPE_GLOBAL, + FAKE_SETTING_NAME, FAKE_SETTING_VALUE, false); + + final long startTimeMicro = SystemClock.currentTimeMicro(); + + try { + for (int i = 0; i < ITERATION_COUNT; i++) { + // Set the setting to its first value. + updateStringViaProviderApiSetting(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME, + FAKE_SETTING_VALUE); + + // Make sure the setting changed. + String firstValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, + FAKE_SETTING_NAME, UserHandle.USER_OWNER); + assertEquals("Setting value didn't change", FAKE_SETTING_VALUE, firstValue); + + // Set the setting to its second value. + updateStringViaProviderApiSetting(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME, + FAKE_SETTING_VALUE_1); + + // Make sure the setting changed. + String secondValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, + FAKE_SETTING_NAME, UserHandle.USER_OWNER); + assertEquals("Setting value didn't change", FAKE_SETTING_VALUE_1, secondValue); + } + } finally { + // Clean up. + deleteStringViaProviderApi(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME); + } + + final long elapsedTimeMicro = SystemClock.currentTimeMicro() - startTimeMicro; + + final long averageTimePerIterationMillis = (long) ((((float) elapsedTimeMicro) + / ITERATION_COUNT) / MICRO_SECONDS_IN_MILLISECOND); + + Log.i(LOG_TAG, "Average time to set and get setting via provider APIs: " + + averageTimePerIterationMillis + " ms"); + + assertTrue("Setting and getting a settings takes too long.", averageTimePerIterationMillis + < MAX_AVERAGE_SET_AND_GET_SETTING_DURATION_MILLIS); + } + + public void testSetAndGetPerformanceForGlobalViaProviderApi() throws Exception { + // Start with a clean slate. + deleteStringViaProviderApi(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME); + + final long startTimeMicro = SystemClock.currentTimeMicro(); + + try { + for (int i = 0; i < ITERATION_COUNT; i++) { + // Set the setting to its first value. + setStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME, + FAKE_SETTING_VALUE, UserHandle.USER_OWNER); + + // Make sure the setting changed. + String firstValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, + FAKE_SETTING_NAME, UserHandle.USER_OWNER); + assertEquals("Setting value didn't change", FAKE_SETTING_VALUE, firstValue); + + // Set the setting to its second value. + setStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME, + FAKE_SETTING_VALUE_1, UserHandle.USER_OWNER); + + // Make sure the setting changed. + String secondValue = getStringViaFrontEndApiSetting(SETTING_TYPE_GLOBAL, + FAKE_SETTING_NAME, UserHandle.USER_OWNER); + assertEquals("Setting value didn't change", FAKE_SETTING_VALUE_1, secondValue); + } + } finally { + // Clean up. + deleteStringViaProviderApi(SETTING_TYPE_GLOBAL, FAKE_SETTING_NAME); + } + + final long elapsedTimeMicro = SystemClock.currentTimeMicro() - startTimeMicro; + + final long averageTimePerIterationMillis = (long) ((((float) elapsedTimeMicro) + / ITERATION_COUNT) / MICRO_SECONDS_IN_MILLISECOND); + + Log.i(LOG_TAG, "Average time to set and get setting via front-eng APIs: " + + averageTimePerIterationMillis + " ms"); + + assertTrue("Setting and getting a settings takes too long.", averageTimePerIterationMillis + < MAX_AVERAGE_SET_AND_GET_SETTING_DURATION_MILLIS); + } +} diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java new file mode 100644 index 0000000..b89fb10 --- /dev/null +++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java @@ -0,0 +1,429 @@ +/* + * 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 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 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(); + + public void testSetAndGetGlobalViaFrontEndApiForOwnerUser() throws Exception { + performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, UserHandle.USER_OWNER); + } + + public void testSetAndGetGlobalViaFrontEndApiForNonOwnerUser() throws Exception { + if (mSecondaryUserId == UserHandle.USER_OWNER) { + Log.w(LOG_TAG, "No secondary user. Skipping " + + "testSetAndGetGlobalViaFrontEndApiForNonOwnerUser"); + return; + } + performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_GLOBAL, mSecondaryUserId); + } + + public void testSetAndGetSecureViaFrontEndApiForOwnerUser() throws Exception { + performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, UserHandle.USER_OWNER); + } + + public void testSetAndGetSecureViaFrontEndApiForNonOwnerUser() throws Exception { + if (mSecondaryUserId == UserHandle.USER_OWNER) { + Log.w(LOG_TAG, "No secondary user. Skipping " + + "testSetAndGetSecureViaFrontEndApiForNonOwnerUser"); + return; + } + performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SECURE, mSecondaryUserId); + } + + public void testSetAndGetSystemViaFrontEndApiForOwnerUser() throws Exception { + performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, UserHandle.USER_OWNER); + } + + public void testSetAndGetSystemViaFrontEndApiForNonOwnerUser() throws Exception { + if (mSecondaryUserId == UserHandle.USER_OWNER) { + Log.w(LOG_TAG, "No secondary user. Skipping " + + "testSetAndGetSystemViaFrontEndApiForNonOwnerUser"); + return; + } + performSetAndGetSettingTestViaFrontEndApi(SETTING_TYPE_SYSTEM, mSecondaryUserId); + } + + public void testSetAndGetGlobalViaProviderApi() throws Exception { + performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_GLOBAL); + } + + public void testSetAndGetSecureViaProviderApi() throws Exception { + performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_SECURE); + } + + public void testSetAndGetSystemViaProviderApi() throws Exception { + performSetAndGetSettingTestViaProviderApi(SETTING_TYPE_SYSTEM); + } + + 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); + } + } + + 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); + } + } + + 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); + } + } + + public void testQueryUpdateDeleteGlobalViaProviderApi() throws Exception { + doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_GLOBAL); + } + + public void testQueryUpdateDeleteSecureViaProviderApi() throws Exception { + doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SECURE); + } + + public void testQueryUpdateDeleteSystemViaProviderApi() throws Exception { + doTestQueryUpdateDeleteGlobalViaProviderApiForType(SETTING_TYPE_SYSTEM); + } + + public void testBulkInsertGlobalViaProviderApi() throws Exception { + toTestBulkInsertViaProviderApiForType(SETTING_TYPE_GLOBAL); + } + + public void testBulkInsertSystemViaProviderApi() throws Exception { + toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SYSTEM); + } + + public void testBulkInsertSecureViaProviderApi() throws Exception { + toTestBulkInsertViaProviderApiForType(SETTING_TYPE_SECURE); + } + + 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) { + for (; insertedCount >= 0; insertedCount--) { + Log.w(LOG_TAG, "Removing app specific setting: " + insertedCount); + deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, + String.valueOf(insertedCount)); + } + } + } + + public void testQueryStringInBracketsGlobalViaProviderApiForType() throws Exception { + doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_GLOBAL); + } + + public void testQueryStringInBracketsSecureViaProviderApiForType() throws Exception { + doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SECURE); + } + + public void testQueryStringInBracketsSystemViaProviderApiForType() throws Exception { + doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SYSTEM); + } + + 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); + } + } + + 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); + + try { + Uri uri = getBaseUriForType(type); + ContentValues[] allValues = new ContentValues[2]; + + // 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 first 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; + + // Verify insertion count. + final int insertCount = getContext().getContentResolver().bulkInsert(uri, allValues); + assertSame("Couldn't insert both values", 2, 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); + } finally { + // Clean up. + deleteStringViaProviderApi(type, FAKE_SETTING_NAME); + deleteStringViaProviderApi(type, FAKE_SETTING_NAME_1); + } + } + + 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(new Runnable() { + @Override + public void run() { + 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(new Runnable() { + @Override + public void run() { + insertStringViaProviderApi(type, name, value, withTableRowUri); + } + }, type, name, value, UserHandle.USER_OWNER); + } + + 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(); + } + } +} |