/** * Copyright (c) 2015, The CyanogenMod 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 cyanogenmod.providers; import android.content.ContentResolver; import android.content.IContentProvider; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.RemoteException; import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.util.AndroidException; import android.util.Log; import java.util.HashMap; /** * CMSettings contains CM specific preferences in System, Secure, and Global. */ public final class CMSettings { private static final String TAG = "CMSettings"; private static final boolean LOCAL_LOGV = false; public static final String AUTHORITY = "cmsettings"; public static class CMSettingNotFoundException extends AndroidException { public CMSettingNotFoundException(String msg) { super(msg); } } // region Call Methods /** * @hide - User handle argument extra to the fast-path call()-based requests */ public static final String CALL_METHOD_USER_KEY = "_user"; /** * @hide - Private call() method on SettingsProvider to read from 'system' table. */ public static final String CALL_METHOD_GET_SYSTEM = "GET_system"; /** * @hide - Private call() method on SettingsProvider to read from 'secure' table. */ public static final String CALL_METHOD_GET_SECURE = "GET_secure"; /** * @hide - Private call() method on SettingsProvider to read from 'global' table. */ public static final String CALL_METHOD_GET_GLOBAL = "GET_global"; /** * @hide - Private call() method to write to 'system' table */ public static final String CALL_METHOD_PUT_SYSTEM = "PUT_system"; /** * @hide - Private call() method to write to 'secure' table */ public static final String CALL_METHOD_PUT_SECURE = "PUT_secure"; /** * @hide - Private call() method to write to 'global' table */ public static final String CALL_METHOD_PUT_GLOBAL= "PUT_global"; /** * @hide - Private call() method on CMSettingsProvider to migrate CM settings */ public static final String CALL_METHOD_MIGRATE_SETTINGS = "migrate_settings"; /** * @hide - Private call() method on CMSettingsProvider to migrate CM settings for a user */ public static final String CALL_METHOD_MIGRATE_SETTINGS_FOR_USER = "migrate_settings_for_user"; // endregion // Thread-safe. private static class NameValueCache { private final String mVersionSystemProperty; private final Uri mUri; private static final String[] SELECT_VALUE = new String[] { Settings.NameValueTable.VALUE }; private static final String NAME_EQ_PLACEHOLDER = "name=?"; // Must synchronize on 'this' to access mValues and mValuesVersion. private final HashMap mValues = new HashMap(); private long mValuesVersion = 0; // Initially null; set lazily and held forever. Synchronized on 'this'. private IContentProvider mContentProvider = null; // The method we'll call (or null, to not use) on the provider // for the fast path of retrieving settings. private final String mCallGetCommand; private final String mCallSetCommand; public NameValueCache(String versionSystemProperty, Uri uri, String getCommand, String setCommand) { mVersionSystemProperty = versionSystemProperty; mUri = uri; mCallGetCommand = getCommand; mCallSetCommand = setCommand; } private IContentProvider lazyGetProvider(ContentResolver cr) { IContentProvider cp; synchronized (this) { cp = mContentProvider; if (cp == null) { cp = mContentProvider = cr.acquireProvider(mUri.getAuthority()); } } return cp; } /** * Puts a string name/value pair into the content provider for the specified user. * @param cr The content resolver to use. * @param name The name of the key to put into the content provider. * @param value The value to put into the content provider. * @param userId The user id to use for the content provider. * @return Whether the put was successful. */ public boolean putStringForUser(ContentResolver cr, String name, String value, final int userId) { try { Bundle arg = new Bundle(); arg.putString(Settings.NameValueTable.VALUE, value); arg.putInt(CALL_METHOD_USER_KEY, userId); IContentProvider cp = lazyGetProvider(cr); cp.call(cr.getPackageName(), mCallSetCommand, name, arg); } catch (RemoteException e) { Log.w(TAG, "Can't set key " + name + " in " + mUri, e); return false; } return true; } /** * Gets a string value with the specified name from the name/value cache if possible. If * not, it will use the content resolver and perform a query. * @param cr Content resolver to use if name/value cache does not contain the name or if * the cache version is older than the current version. * @param name The name of the key to search for. * @param userId The user id of the cache to look in. * @return The string value of the specified key. */ public String getStringForUser(ContentResolver cr, String name, final int userId) { final boolean isSelf = (userId == UserHandle.myUserId()); if (isSelf) { if (LOCAL_LOGV) Log.d(TAG, "get setting for self"); long newValuesVersion = SystemProperties.getLong(mVersionSystemProperty, 0); // Our own user's settings data uses a client-side cache synchronized (this) { if (mValuesVersion != newValuesVersion) { if (LOCAL_LOGV || false) { Log.v(TAG, "invalidate [" + mUri.getLastPathSegment() + "]: current " + newValuesVersion + " != cached " + mValuesVersion); } mValues.clear(); mValuesVersion = newValuesVersion; } if (mValues.containsKey(name)) { return mValues.get(name); // Could be null, that's OK -- negative caching } } } else { if (LOCAL_LOGV) Log.v(TAG, "get setting for user " + userId + " by user " + UserHandle.myUserId() + " so skipping cache"); } IContentProvider cp = lazyGetProvider(cr); // Try the fast path first, not using query(). If this // fails (alternate Settings provider that doesn't support // this interface?) then we fall back to the query/table // interface. if (mCallGetCommand != null) { try { Bundle args = null; if (!isSelf) { args = new Bundle(); args.putInt(CALL_METHOD_USER_KEY, userId); } Bundle b = cp.call(cr.getPackageName(), mCallGetCommand, name, args); if (b != null) { String value = b.getPairValue(); // Don't update our cache for reads of other users' data if (isSelf) { synchronized (this) { mValues.put(name, value); } } else { if (LOCAL_LOGV) Log.i(TAG, "call-query of user " + userId + " by " + UserHandle.myUserId() + " so not updating cache"); } return value; } // If the response Bundle is null, we fall through // to the query interface below. } catch (RemoteException e) { // Not supported by the remote side? Fall through // to query(). } } Cursor c = null; try { c = cp.query(cr.getPackageName(), mUri, SELECT_VALUE, NAME_EQ_PLACEHOLDER, new String[]{name}, null, null); if (c == null) { Log.w(TAG, "Can't get key " + name + " from " + mUri); return null; } String value = c.moveToNext() ? c.getString(0) : null; synchronized (this) { mValues.put(name, value); } if (LOCAL_LOGV) { Log.v(TAG, "cache miss [" + mUri.getLastPathSegment() + "]: " + name + " = " + (value == null ? "(null)" : value)); } return value; } catch (RemoteException e) { Log.w(TAG, "Can't get key " + name + " from " + mUri, e); return null; // Return null, but don't cache it. } finally { if (c != null) c.close(); } } } /** * System settings, containing miscellaneous CM system preferences. This table holds simple * name/value pairs. There are convenience functions for accessing individual settings entries. */ public static final class System extends Settings.NameValueTable { public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/system"); public static final String SYS_PROP_CM_SETTING_VERSION = "sys.cm_settings_system_version"; private static final NameValueCache sNameValueCache = new NameValueCache( SYS_PROP_CM_SETTING_VERSION, CONTENT_URI, CALL_METHOD_GET_SYSTEM, CALL_METHOD_PUT_SYSTEM); // region Methods /** * Construct the content URI for a particular name/value pair, useful for monitoring changes * with a ContentObserver. * @param name to look up in the table * @return the corresponding content URI */ public static Uri getUriFor(String name) { return Settings.NameValueTable.getUriFor(CONTENT_URI, name); } /** * Look up a name in the database. * @param resolver to access the database with * @param name to look up in the table * @return the corresponding value, or null if not present */ public static String getString(ContentResolver resolver, String name) { return getStringForUser(resolver, name, UserHandle.myUserId()); } /** @hide */ public static String getStringForUser(ContentResolver resolver, String name, int userId) { return sNameValueCache.getStringForUser(resolver, name, userId); } /** * Store a name/value pair into the database. * @param resolver to access the database with * @param name to store * @param value to associate with the name * @return true if the value was set, false on database errors */ public static boolean putString(ContentResolver resolver, String name, String value) { return putStringForUser(resolver, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putStringForUser(ContentResolver resolver, String name, String value, int userId) { return sNameValueCache.putStringForUser(resolver, name, value, userId); } /** * Convenience function for retrieving a single settings value * as an integer. Note that internally setting values are always * stored as strings; this function converts the string to an integer * for you. The default value will be returned if the setting is * not defined or not an integer. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * @param def Value to return if the setting is not defined. * * @return The setting's current value, or 'def' if it is not defined * or not a valid integer. */ public static int getInt(ContentResolver cr, String name, int def) { return getIntForUser(cr, name, def, UserHandle.myUserId()); } /** @hide */ public static int getIntForUser(ContentResolver cr, String name, int def, int userId) { String v = getStringForUser(cr, name, userId); try { return v != null ? Integer.parseInt(v) : def; } catch (NumberFormatException e) { return def; } } /** * Convenience function for retrieving a single settings value * as an integer. Note that internally setting values are always * stored as strings; this function converts the string to an integer * for you. *

* This version does not take a default value. If the setting has not * been set, or the string value is not a number, * it throws {@link CMSettingNotFoundException}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * * @throws CMSettingNotFoundException Thrown if a setting by the given * name can't be found or the setting value is not an integer. * * @return The setting's current value. */ public static int getInt(ContentResolver cr, String name) throws CMSettingNotFoundException { return getIntForUser(cr, name, UserHandle.myUserId()); } /** @hide */ public static int getIntForUser(ContentResolver cr, String name, int userId) throws CMSettingNotFoundException { String v = getStringForUser(cr, name, userId); try { return Integer.parseInt(v); } catch (NumberFormatException e) { throw new CMSettingNotFoundException(name); } } /** * Convenience function for updating a single settings value as an * integer. This will either create a new entry in the table if the * given name does not exist, or modify the value of the existing row * with that name. Note that internally setting values are always * stored as strings, so this function converts the given value to a * string before storing it. * * @param cr The ContentResolver to access. * @param name The name of the setting to modify. * @param value The new value for the setting. * @return true if the value was set, false on database errors */ public static boolean putInt(ContentResolver cr, String name, int value) { return putIntForUser(cr, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putIntForUser(ContentResolver cr, String name, int value, int userId) { return putStringForUser(cr, name, Integer.toString(value), userId); } /** * Convenience function for retrieving a single settings value * as a {@code long}. Note that internally setting values are always * stored as strings; this function converts the string to a {@code long} * for you. The default value will be returned if the setting is * not defined or not a {@code long}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * @param def Value to return if the setting is not defined. * * @return The setting's current value, or 'def' if it is not defined * or not a valid {@code long}. */ public static long getLong(ContentResolver cr, String name, long def) { return getLongForUser(cr, name, def, UserHandle.myUserId()); } /** @hide */ public static long getLongForUser(ContentResolver cr, String name, long def, int userId) { String valString = getStringForUser(cr, name, userId); long value; try { value = valString != null ? Long.parseLong(valString) : def; } catch (NumberFormatException e) { value = def; } return value; } /** * Convenience function for retrieving a single settings value * as a {@code long}. Note that internally setting values are always * stored as strings; this function converts the string to a {@code long} * for you. *

* This version does not take a default value. If the setting has not * been set, or the string value is not a number, * it throws {@link CMSettingNotFoundException}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * * @return The setting's current value. * @throws CMSettingNotFoundException Thrown if a setting by the given * name can't be found or the setting value is not an integer. */ public static long getLong(ContentResolver cr, String name) throws CMSettingNotFoundException { return getLongForUser(cr, name, UserHandle.myUserId()); } /** @hide */ public static long getLongForUser(ContentResolver cr, String name, int userId) throws CMSettingNotFoundException { String valString = getStringForUser(cr, name, userId); try { return Long.parseLong(valString); } catch (NumberFormatException e) { throw new CMSettingNotFoundException(name); } } /** * Convenience function for updating a single settings value as a long * integer. This will either create a new entry in the table if the * given name does not exist, or modify the value of the existing row * with that name. Note that internally setting values are always * stored as strings, so this function converts the given value to a * string before storing it. * * @param cr The ContentResolver to access. * @param name The name of the setting to modify. * @param value The new value for the setting. * @return true if the value was set, false on database errors */ public static boolean putLong(ContentResolver cr, String name, long value) { return putLongForUser(cr, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putLongForUser(ContentResolver cr, String name, long value, int userId) { return putStringForUser(cr, name, Long.toString(value), userId); } /** * Convenience function for retrieving a single settings value * as a floating point number. Note that internally setting values are * always stored as strings; this function converts the string to an * float for you. The default value will be returned if the setting * is not defined or not a valid float. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * @param def Value to return if the setting is not defined. * * @return The setting's current value, or 'def' if it is not defined * or not a valid float. */ public static float getFloat(ContentResolver cr, String name, float def) { return getFloatForUser(cr, name, def, UserHandle.myUserId()); } /** @hide */ public static float getFloatForUser(ContentResolver cr, String name, float def, int userId) { String v = getStringForUser(cr, name, userId); try { return v != null ? Float.parseFloat(v) : def; } catch (NumberFormatException e) { return def; } } /** * Convenience function for retrieving a single system settings value * as a float. Note that internally setting values are always * stored as strings; this function converts the string to a float * for you. *

* This version does not take a default value. If the setting has not * been set, or the string value is not a number, * it throws {@link CMSettingNotFoundException}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * * @throws CMSettingNotFoundException Thrown if a setting by the given * name can't be found or the setting value is not a float. * * @return The setting's current value. */ public static float getFloat(ContentResolver cr, String name) throws CMSettingNotFoundException { return getFloatForUser(cr, name, UserHandle.myUserId()); } /** @hide */ public static float getFloatForUser(ContentResolver cr, String name, int userId) throws CMSettingNotFoundException { String v = getStringForUser(cr, name, userId); if (v == null) { throw new CMSettingNotFoundException(name); } try { return Float.parseFloat(v); } catch (NumberFormatException e) { throw new CMSettingNotFoundException(name); } } /** * Convenience function for updating a single settings value as a * floating point number. This will either create a new entry in the * table if the given name does not exist, or modify the value of the * existing row with that name. Note that internally setting values * are always stored as strings, so this function converts the given * value to a string before storing it. * * @param cr The ContentResolver to access. * @param name The name of the setting to modify. * @param value The new value for the setting. * @return true if the value was set, false on database errors */ public static boolean putFloat(ContentResolver cr, String name, float value) { return putFloatForUser(cr, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putFloatForUser(ContentResolver cr, String name, float value, int userId) { return putStringForUser(cr, name, Float.toString(value), userId); } // endregion // region System Settings /** * Quick Settings Quick Pulldown * 0 = off, 1 = right, 2 = left * @hide */ public static final String QS_QUICK_PULLDOWN = "qs_quick_pulldown"; /** * Whether to attach a queue to media notifications. * 0 = 0ff, 1 = on * @hide */ public static final String NOTIFICATION_PLAY_QUEUE = "notification_play_queue"; /** * Whether the HighTouchSensitivity is activated or not. * 0 = off, 1 = on * @hide */ public static final String HIGH_TOUCH_SENSITIVITY_ENABLE = "high_touch_sensitivity_enable"; /** * Show the pending notification counts as overlays on the status bar * @hide */ public static final String SYSTEM_PROFILES_ENABLED = "system_profiles_enabled"; /** * Whether to hide the clock, show it in the right or left * position or show it in the center * 0: don't show the clock * 1: show the clock in the right position (LTR) * 2: show the clock in the center * 3: show the clock in the left position (LTR) * default: 1 * @hide */ public static final String STATUS_BAR_CLOCK = "status_bar_clock"; /** * Display style of AM/PM next to clock in status bar * 0: Normal display (Eclair stock) * 1: Small display (Froyo stock) * 2: No display (Gingerbread/ICS stock) * default: 2 * @hide */ public static final String STATUS_BAR_AM_PM = "status_bar_am_pm"; /** * Display style of the status bar battery information * 0: Display the battery an icon in portrait mode * 2: Display the battery as a circle * 4: Hide the battery status information * 5: Display the battery an icon in landscape mode * 6: Display the battery as plain text * default: 0 * @hide */ public static final String STATUS_BAR_BATTERY_STYLE = "status_bar_battery_style"; /** * Status bar battery % * 0: Hide the battery percentage * 1: Display the battery percentage inside the icon * 2: Display the battery percentage next to the icon * @hide */ public static final String STATUS_BAR_SHOW_BATTERY_PERCENT = "status_bar_show_battery_percent"; // endregion /** * Whether the phone ringtone should be played in an increasing manner * @hide */ public static final String INCREASING_RING = "increasing_ring"; /** * Start volume fraction for increasing ring volume * @hide */ public static final String INCREASING_RING_START_VOLUME = "increasing_ring_start_vol"; /** * Ramp up time (seconds) for increasing ring * @hide */ public static final String INCREASING_RING_RAMP_UP_TIME = "increasing_ring_ramp_up_time"; /** * Volume Adjust Sounds Enable, This is the noise made when using volume hard buttons * Defaults to 1 - sounds enabled * @hide */ public static final String VOLUME_ADJUST_SOUNDS_ENABLED = "volume_adjust_sounds_enabled"; /** * Navigation controls to Use * @hide */ public static final String NAV_BUTTONS = "nav_buttons"; /** * Volume key controls ringtone or media sound stream * @hide */ public static final String VOLUME_KEYS_CONTROL_RING_STREAM = "volume_keys_control_ring_stream"; } /** * Secure settings, containing miscellaneous CM secure preferences. This * table holds simple name/value pairs. There are convenience * functions for accessing individual settings entries. */ public static final class Secure extends Settings.NameValueTable { public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/secure"); public static final String SYS_PROP_CM_SETTING_VERSION = "sys.cm_settings_secure_version"; private static final NameValueCache sNameValueCache = new NameValueCache( SYS_PROP_CM_SETTING_VERSION, CONTENT_URI, CALL_METHOD_GET_SECURE, CALL_METHOD_PUT_SECURE); // region Methods /** * Construct the content URI for a particular name/value pair, useful for monitoring changes * with a ContentObserver. * @param name to look up in the table * @return the corresponding content URI */ public static Uri getUriFor(String name) { return Settings.NameValueTable.getUriFor(CONTENT_URI, name); } /** * Look up a name in the database. * @param resolver to access the database with * @param name to look up in the table * @return the corresponding value, or null if not present */ public static String getString(ContentResolver resolver, String name) { return getStringForUser(resolver, name, UserHandle.myUserId()); } /** @hide */ public static String getStringForUser(ContentResolver resolver, String name, int userId) { return sNameValueCache.getStringForUser(resolver, name, userId); } /** * Store a name/value pair into the database. * @param resolver to access the database with * @param name to store * @param value to associate with the name * @return true if the value was set, false on database errors */ public static boolean putString(ContentResolver resolver, String name, String value) { return putStringForUser(resolver, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putStringForUser(ContentResolver resolver, String name, String value, int userId) { return sNameValueCache.putStringForUser(resolver, name, value, userId); } /** * Convenience function for retrieving a single settings value * as an integer. Note that internally setting values are always * stored as strings; this function converts the string to an integer * for you. The default value will be returned if the setting is * not defined or not an integer. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * @param def Value to return if the setting is not defined. * * @return The setting's current value, or 'def' if it is not defined * or not a valid integer. */ public static int getInt(ContentResolver cr, String name, int def) { return getIntForUser(cr, name, def, UserHandle.myUserId()); } /** @hide */ public static int getIntForUser(ContentResolver cr, String name, int def, int userId) { String v = getStringForUser(cr, name, userId); try { return v != null ? Integer.parseInt(v) : def; } catch (NumberFormatException e) { return def; } } /** * Convenience function for retrieving a single settings value * as an integer. Note that internally setting values are always * stored as strings; this function converts the string to an integer * for you. *

* This version does not take a default value. If the setting has not * been set, or the string value is not a number, * it throws {@link CMSettingNotFoundException}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * * @throws CMSettingNotFoundException Thrown if a setting by the given * name can't be found or the setting value is not an integer. * * @return The setting's current value. */ public static int getInt(ContentResolver cr, String name) throws CMSettingNotFoundException { return getIntForUser(cr, name, UserHandle.myUserId()); } /** @hide */ public static int getIntForUser(ContentResolver cr, String name, int userId) throws CMSettingNotFoundException { String v = getStringForUser(cr, name, userId); try { return Integer.parseInt(v); } catch (NumberFormatException e) { throw new CMSettingNotFoundException(name); } } /** * Convenience function for updating a single settings value as an * integer. This will either create a new entry in the table if the * given name does not exist, or modify the value of the existing row * with that name. Note that internally setting values are always * stored as strings, so this function converts the given value to a * string before storing it. * * @param cr The ContentResolver to access. * @param name The name of the setting to modify. * @param value The new value for the setting. * @return true if the value was set, false on database errors */ public static boolean putInt(ContentResolver cr, String name, int value) { return putIntForUser(cr, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putIntForUser(ContentResolver cr, String name, int value, int userId) { return putStringForUser(cr, name, Integer.toString(value), userId); } /** * Convenience function for retrieving a single settings value * as a {@code long}. Note that internally setting values are always * stored as strings; this function converts the string to a {@code long} * for you. The default value will be returned if the setting is * not defined or not a {@code long}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * @param def Value to return if the setting is not defined. * * @return The setting's current value, or 'def' if it is not defined * or not a valid {@code long}. */ public static long getLong(ContentResolver cr, String name, long def) { return getLongForUser(cr, name, def, UserHandle.myUserId()); } /** @hide */ public static long getLongForUser(ContentResolver cr, String name, long def, int userId) { String valString = getStringForUser(cr, name, userId); long value; try { value = valString != null ? Long.parseLong(valString) : def; } catch (NumberFormatException e) { value = def; } return value; } /** * Convenience function for retrieving a single settings value * as a {@code long}. Note that internally setting values are always * stored as strings; this function converts the string to a {@code long} * for you. *

* This version does not take a default value. If the setting has not * been set, or the string value is not a number, * it throws {@link CMSettingNotFoundException}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * * @return The setting's current value. * @throws CMSettingNotFoundException Thrown if a setting by the given * name can't be found or the setting value is not an integer. */ public static long getLong(ContentResolver cr, String name) throws CMSettingNotFoundException { return getLongForUser(cr, name, UserHandle.myUserId()); } /** @hide */ public static long getLongForUser(ContentResolver cr, String name, int userId) throws CMSettingNotFoundException { String valString = getStringForUser(cr, name, userId); try { return Long.parseLong(valString); } catch (NumberFormatException e) { throw new CMSettingNotFoundException(name); } } /** * Convenience function for updating a single settings value as a long * integer. This will either create a new entry in the table if the * given name does not exist, or modify the value of the existing row * with that name. Note that internally setting values are always * stored as strings, so this function converts the given value to a * string before storing it. * * @param cr The ContentResolver to access. * @param name The name of the setting to modify. * @param value The new value for the setting. * @return true if the value was set, false on database errors */ public static boolean putLong(ContentResolver cr, String name, long value) { return putLongForUser(cr, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putLongForUser(ContentResolver cr, String name, long value, int userId) { return putStringForUser(cr, name, Long.toString(value), userId); } /** * Convenience function for retrieving a single settings value * as a floating point number. Note that internally setting values are * always stored as strings; this function converts the string to an * float for you. The default value will be returned if the setting * is not defined or not a valid float. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * @param def Value to return if the setting is not defined. * * @return The setting's current value, or 'def' if it is not defined * or not a valid float. */ public static float getFloat(ContentResolver cr, String name, float def) { return getFloatForUser(cr, name, def, UserHandle.myUserId()); } /** @hide */ public static float getFloatForUser(ContentResolver cr, String name, float def, int userId) { String v = getStringForUser(cr, name, userId); try { return v != null ? Float.parseFloat(v) : def; } catch (NumberFormatException e) { return def; } } /** * Convenience function for retrieving a single system settings value * as a float. Note that internally setting values are always * stored as strings; this function converts the string to a float * for you. *

* This version does not take a default value. If the setting has not * been set, or the string value is not a number, * it throws {@link CMSettingNotFoundException}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * * @throws CMSettingNotFoundException Thrown if a setting by the given * name can't be found or the setting value is not a float. * * @return The setting's current value. */ public static float getFloat(ContentResolver cr, String name) throws CMSettingNotFoundException { return getFloatForUser(cr, name, UserHandle.myUserId()); } /** @hide */ public static float getFloatForUser(ContentResolver cr, String name, int userId) throws CMSettingNotFoundException { String v = getStringForUser(cr, name, userId); if (v == null) { throw new CMSettingNotFoundException(name); } try { return Float.parseFloat(v); } catch (NumberFormatException e) { throw new CMSettingNotFoundException(name); } } /** * Convenience function for updating a single settings value as a * floating point number. This will either create a new entry in the * table if the given name does not exist, or modify the value of the * existing row with that name. Note that internally setting values * are always stored as strings, so this function converts the given * value to a string before storing it. * * @param cr The ContentResolver to access. * @param name The name of the setting to modify. * @param value The new value for the setting. * @return true if the value was set, false on database errors */ public static boolean putFloat(ContentResolver cr, String name, float value) { return putFloatForUser(cr, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putFloatForUser(ContentResolver cr, String name, float value, int userId) { return putStringForUser(cr, name, Float.toString(value), userId); } // endregion // region Secure Settings /** * Whether to enable "advanced mode" for the current user. * Boolean setting. 0 = no, 1 = yes. * @hide */ public static final String ADVANCED_MODE = "advanced_mode"; /** * The time in ms to keep the button backlight on after pressing a button. * A value of 0 will keep the buttons on for as long as the screen is on. * @hide */ public static final String BUTTON_BACKLIGHT_TIMEOUT = "button_backlight_timeout"; /** * The button brightness to be used while the screen is on or after a button press, * depending on the value of {@link BUTTON_BACKLIGHT_TIMEOUT}. * Valid value range is between 0 and {@link PowerManager#getMaximumButtonBrightness()} * @hide */ public static final String BUTTON_BRIGHTNESS = "button_brightness"; /** * A '|' delimited list of theme components to apply from the default theme on first boot. * Components can be one or more of the "mods_XXXXXXX" found in * {@link ThemesContract$ThemesColumns}. Leaving this field blank assumes all components * will be applied. * * ex: mods_icons|mods_overlays|mods_homescreen * * @hide */ public static final String DEFAULT_THEME_COMPONENTS = "default_theme_components"; /** * Default theme to use. If empty, use holo. * @hide */ public static final String DEFAULT_THEME_PACKAGE = "default_theme_package"; /** * Developer options - Navigation Bar show switch * @hide */ public static final String DEV_FORCE_SHOW_NAVBAR = "dev_force_show_navbar"; /** * The keyboard brightness to be used while the screen is on. * Valid value range is between 0 and {@link PowerManager#getMaximumKeyboardBrightness()} * @hide */ public static final String KEYBOARD_BRIGHTNESS = "keyboard_brightness"; /** * Default theme config name */ public static final String NAME_THEME_CONFIG = "name_theme_config"; /** * Custom navring actions * @hide */ public static final String[] NAVIGATION_RING_TARGETS = new String[] { "navigation_ring_targets_0", "navigation_ring_targets_1", "navigation_ring_targets_2", }; /** * String to contain power menu actions * @hide */ public static final String POWER_MENU_ACTIONS = "power_menu_actions"; /** * Whether to show the brightness slider in quick settings panel. * @hide */ public static final String QS_SHOW_BRIGHTNESS_SLIDER = "qs_show_brightness_slider"; /** * List of QS tile names * @hide */ public static final String QS_TILES = "sysui_qs_tiles"; /** * Use "main" tiles on the first row of the quick settings panel * 0 = no, 1 = yes * @hide */ public static final String QS_USE_MAIN_TILES = "sysui_qs_main_tiles"; /** * Global stats collection * @hide */ public static final String STATS_COLLECTION = "stats_collection"; /** * Boolean value whether to link ringtone and notification volume * * @hide */ public static final String VOLUME_LINK_NOTIFICATION = "volume_link_notification"; /** * Whether newly installed apps should run with privacy guard by default * @hide */ public static final String PRIVACY_GUARD_DEFAULT = "privacy_guard_default"; /** * The global recents long press activity chosen by the user. * This setting is stored as a flattened component name as * per {@link ComponentName#flattenToString()}. * * @hide */ public static final String RECENTS_LONG_PRESS_ACTIVITY = "recents_long_press_activity"; /** * What happens when the user presses the Home button when the * phone is ringing.
* Values:
* 1 - Nothing happens. (Default behavior)
* 2 - The Home button answer the current call.
* * @hide */ public static final String RING_HOME_BUTTON_BEHAVIOR = "ring_home_button_behavior"; /** * RING_HOME_BUTTON_BEHAVIOR value for "do nothing". * @hide */ public static final int RING_HOME_BUTTON_BEHAVIOR_DO_NOTHING = 0x1; /** * RING_HOME_BUTTON_BEHAVIOR value for "answer". * @hide */ public static final int RING_HOME_BUTTON_BEHAVIOR_ANSWER = 0x2; /** * RING_HOME_BUTTON_BEHAVIOR default value. * @hide */ public static final int RING_HOME_BUTTON_BEHAVIOR_DEFAULT = RING_HOME_BUTTON_BEHAVIOR_DO_NOTHING; /** * When the user has enable the option to have a "bug report" command * in the power menu. * @deprecated Use {@link android.provider.Settings.Global#BUGREPORT_IN_POWER_MENU} instead * @hide */ @Deprecated public static final String BUGREPORT_IN_POWER_MENU = "bugreport_in_power_menu"; // endregion } /** * Global settings, containing miscellaneous CM global preferences. This * table holds simple name/value pairs. There are convenience * functions for accessing individual settings entries. */ public static final class Global extends Settings.NameValueTable { public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/global"); public static final String SYS_PROP_CM_SETTING_VERSION = "sys.cm_settings_global_version"; private static final NameValueCache sNameValueCache = new NameValueCache( SYS_PROP_CM_SETTING_VERSION, CONTENT_URI, CALL_METHOD_GET_GLOBAL, CALL_METHOD_PUT_GLOBAL); // region Methods /** * Construct the content URI for a particular name/value pair, useful for monitoring changes * with a ContentObserver. * @param name to look up in the table * @return the corresponding content URI */ public static Uri getUriFor(String name) { return Settings.NameValueTable.getUriFor(CONTENT_URI, name); } /** * Look up a name in the database. * @param resolver to access the database with * @param name to look up in the table * @return the corresponding value, or null if not present */ public static String getString(ContentResolver resolver, String name) { return getStringForUser(resolver, name, UserHandle.myUserId()); } /** @hide */ public static String getStringForUser(ContentResolver resolver, String name, int userId) { return sNameValueCache.getStringForUser(resolver, name, userId); } /** * Store a name/value pair into the database. * @param resolver to access the database with * @param name to store * @param value to associate with the name * @return true if the value was set, false on database errors */ public static boolean putString(ContentResolver resolver, String name, String value) { return putStringForUser(resolver, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putStringForUser(ContentResolver resolver, String name, String value, int userId) { return sNameValueCache.putStringForUser(resolver, name, value, userId); } /** * Convenience function for retrieving a single settings value * as an integer. Note that internally setting values are always * stored as strings; this function converts the string to an integer * for you. The default value will be returned if the setting is * not defined or not an integer. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * @param def Value to return if the setting is not defined. * * @return The setting's current value, or 'def' if it is not defined * or not a valid integer. */ public static int getInt(ContentResolver cr, String name, int def) { return getIntForUser(cr, name, def, UserHandle.myUserId()); } /** @hide */ public static int getIntForUser(ContentResolver cr, String name, int def, int userId) { String v = getStringForUser(cr, name, userId); try { return v != null ? Integer.parseInt(v) : def; } catch (NumberFormatException e) { return def; } } /** * Convenience function for retrieving a single settings value * as an integer. Note that internally setting values are always * stored as strings; this function converts the string to an integer * for you. *

* This version does not take a default value. If the setting has not * been set, or the string value is not a number, * it throws {@link CMSettingNotFoundException}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * * @throws CMSettingNotFoundException Thrown if a setting by the given * name can't be found or the setting value is not an integer. * * @return The setting's current value. */ public static int getInt(ContentResolver cr, String name) throws CMSettingNotFoundException { return getIntForUser(cr, name, UserHandle.myUserId()); } /** @hide */ public static int getIntForUser(ContentResolver cr, String name, int userId) throws CMSettingNotFoundException { String v = getStringForUser(cr, name, userId); try { return Integer.parseInt(v); } catch (NumberFormatException e) { throw new CMSettingNotFoundException(name); } } /** * Convenience function for updating a single settings value as an * integer. This will either create a new entry in the table if the * given name does not exist, or modify the value of the existing row * with that name. Note that internally setting values are always * stored as strings, so this function converts the given value to a * string before storing it. * * @param cr The ContentResolver to access. * @param name The name of the setting to modify. * @param value The new value for the setting. * @return true if the value was set, false on database errors */ public static boolean putInt(ContentResolver cr, String name, int value) { return putIntForUser(cr, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putIntForUser(ContentResolver cr, String name, int value, int userId) { return putStringForUser(cr, name, Integer.toString(value), userId); } /** * Convenience function for retrieving a single settings value * as a {@code long}. Note that internally setting values are always * stored as strings; this function converts the string to a {@code long} * for you. The default value will be returned if the setting is * not defined or not a {@code long}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * @param def Value to return if the setting is not defined. * * @return The setting's current value, or 'def' if it is not defined * or not a valid {@code long}. */ public static long getLong(ContentResolver cr, String name, long def) { return getLongForUser(cr, name, def, UserHandle.myUserId()); } /** @hide */ public static long getLongForUser(ContentResolver cr, String name, long def, int userId) { String valString = getStringForUser(cr, name, userId); long value; try { value = valString != null ? Long.parseLong(valString) : def; } catch (NumberFormatException e) { value = def; } return value; } /** * Convenience function for retrieving a single settings value * as a {@code long}. Note that internally setting values are always * stored as strings; this function converts the string to a {@code long} * for you. *

* This version does not take a default value. If the setting has not * been set, or the string value is not a number, * it throws {@link CMSettingNotFoundException}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * * @return The setting's current value. * @throws CMSettingNotFoundException Thrown if a setting by the given * name can't be found or the setting value is not an integer. */ public static long getLong(ContentResolver cr, String name) throws CMSettingNotFoundException { return getLongForUser(cr, name, UserHandle.myUserId()); } /** @hide */ public static long getLongForUser(ContentResolver cr, String name, int userId) throws CMSettingNotFoundException { String valString = getStringForUser(cr, name, userId); try { return Long.parseLong(valString); } catch (NumberFormatException e) { throw new CMSettingNotFoundException(name); } } /** * Convenience function for updating a single settings value as a long * integer. This will either create a new entry in the table if the * given name does not exist, or modify the value of the existing row * with that name. Note that internally setting values are always * stored as strings, so this function converts the given value to a * string before storing it. * * @param cr The ContentResolver to access. * @param name The name of the setting to modify. * @param value The new value for the setting. * @return true if the value was set, false on database errors */ public static boolean putLong(ContentResolver cr, String name, long value) { return putLongForUser(cr, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putLongForUser(ContentResolver cr, String name, long value, int userId) { return putStringForUser(cr, name, Long.toString(value), userId); } /** * Convenience function for retrieving a single settings value * as a floating point number. Note that internally setting values are * always stored as strings; this function converts the string to an * float for you. The default value will be returned if the setting * is not defined or not a valid float. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * @param def Value to return if the setting is not defined. * * @return The setting's current value, or 'def' if it is not defined * or not a valid float. */ public static float getFloat(ContentResolver cr, String name, float def) { return getFloatForUser(cr, name, def, UserHandle.myUserId()); } /** @hide */ public static float getFloatForUser(ContentResolver cr, String name, float def, int userId) { String v = getStringForUser(cr, name, userId); try { return v != null ? Float.parseFloat(v) : def; } catch (NumberFormatException e) { return def; } } /** * Convenience function for retrieving a single system settings value * as a float. Note that internally setting values are always * stored as strings; this function converts the string to a float * for you. *

* This version does not take a default value. If the setting has not * been set, or the string value is not a number, * it throws {@link CMSettingNotFoundException}. * * @param cr The ContentResolver to access. * @param name The name of the setting to retrieve. * * @throws CMSettingNotFoundException Thrown if a setting by the given * name can't be found or the setting value is not a float. * * @return The setting's current value. */ public static float getFloat(ContentResolver cr, String name) throws CMSettingNotFoundException { return getFloatForUser(cr, name, UserHandle.myUserId()); } /** @hide */ public static float getFloatForUser(ContentResolver cr, String name, int userId) throws CMSettingNotFoundException { String v = getStringForUser(cr, name, userId); if (v == null) { throw new CMSettingNotFoundException(name); } try { return Float.parseFloat(v); } catch (NumberFormatException e) { throw new CMSettingNotFoundException(name); } } /** * Convenience function for updating a single settings value as a * floating point number. This will either create a new entry in the * table if the given name does not exist, or modify the value of the * existing row with that name. Note that internally setting values * are always stored as strings, so this function converts the given * value to a string before storing it. * * @param cr The ContentResolver to access. * @param name The name of the setting to modify. * @param value The new value for the setting. * @return true if the value was set, false on database errors */ public static boolean putFloat(ContentResolver cr, String name, float value) { return putFloatForUser(cr, name, value, UserHandle.myUserId()); } /** @hide */ public static boolean putFloatForUser(ContentResolver cr, String name, float value, int userId) { return putStringForUser(cr, name, Float.toString(value), userId); } // endregion // region Global Settings // endregion } }