summaryrefslogtreecommitdiffstats
path: root/packages/SettingsProvider
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SettingsProvider')
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java12
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java124
2 files changed, 110 insertions, 26 deletions
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index eac83d8..7f826ef 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -793,7 +793,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
}
// Figure out the white list and redirects to the global table.
- String[] whitelist = null;
+ final String[] whitelist;
if (contentUri.equals(Settings.Secure.CONTENT_URI)) {
whitelist = Settings.Secure.SETTINGS_TO_BACKUP;
} else if (contentUri.equals(Settings.System.CONTENT_URI)) {
@@ -809,6 +809,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
Map<String, String> cachedEntries = new HashMap<String, String>();
ContentValues contentValues = new ContentValues(2);
SettingsHelper settingsHelper = mSettingsHelper;
+ ContentResolver cr = getContentResolver();
final int whiteListSize = whitelist.length;
for (int i = 0; i < whiteListSize; i++) {
@@ -841,14 +842,7 @@ public class SettingsBackupAgent extends BackupAgentHelper {
final Uri destination = (movedToGlobal != null && movedToGlobal.contains(key))
? Settings.Global.CONTENT_URI
: contentUri;
-
- // The helper doesn't care what namespace the keys are in
- if (settingsHelper.restoreValue(key, value)) {
- contentValues.clear();
- contentValues.put(Settings.NameValueTable.NAME, key);
- contentValues.put(Settings.NameValueTable.VALUE, value);
- getContentResolver().insert(destination, contentValues);
- }
+ settingsHelper.restoreValue(this, cr, contentValues, destination, key, value);
if (DEBUG) {
Log.d(TAG, "Restored setting: " + destination + " : "+ key + "=" + value);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 4144c80..1cad610 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -19,7 +19,10 @@ package com.android.providers.settings;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
import android.app.backup.IBackupManager;
+import android.content.ContentResolver;
+import android.content.ContentValues;
import android.content.Context;
+import android.content.Intent;
import android.content.res.Configuration;
import android.location.LocationManager;
import android.media.AudioManager;
@@ -28,10 +31,12 @@ import android.net.Uri;
import android.os.IPowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.ArraySet;
import java.util.Locale;
@@ -41,6 +46,48 @@ public class SettingsHelper {
private AudioManager mAudioManager;
private TelephonyManager mTelephonyManager;
+ /**
+ * A few settings elements are special in that a restore of those values needs to
+ * be post-processed by relevant parts of the OS. A restore of any settings element
+ * mentioned in this table will therefore cause the system to send a broadcast with
+ * the {@link Intent#ACTION_SETTING_RESTORED} action, with extras naming the
+ * affected setting and supplying its pre-restore value for comparison.
+ *
+ * @see Intent#ACTION_SETTING_RESTORED
+ * @see System#SETTINGS_TO_BACKUP
+ * @see Secure#SETTINGS_TO_BACKUP
+ * @see Global#SETTINGS_TO_BACKUP
+ *
+ * {@hide}
+ */
+ private static final ArraySet<String> sBroadcastOnRestore;
+ static {
+ sBroadcastOnRestore = new ArraySet<String>(1);
+ sBroadcastOnRestore.add(Settings.Secure.ENABLED_NOTIFICATION_LISTENERS);
+ }
+
+ private interface SettingsLookup {
+ public String lookup(ContentResolver resolver, String name, int userHandle);
+ }
+
+ private static SettingsLookup sSystemLookup = new SettingsLookup() {
+ public String lookup(ContentResolver resolver, String name, int userHandle) {
+ return Settings.System.getStringForUser(resolver, name, userHandle);
+ }
+ };
+
+ private static SettingsLookup sSecureLookup = new SettingsLookup() {
+ public String lookup(ContentResolver resolver, String name, int userHandle) {
+ return Settings.Secure.getStringForUser(resolver, name, userHandle);
+ }
+ };
+
+ private static SettingsLookup sGlobalLookup = new SettingsLookup() {
+ public String lookup(ContentResolver resolver, String name, int userHandle) {
+ return Settings.Global.getStringForUser(resolver, name, userHandle);
+ }
+ };
+
public SettingsHelper(Context context) {
mContext = context;
mAudioManager = (AudioManager) context
@@ -58,24 +105,67 @@ public class SettingsHelper {
* some cases the data will be written by the call to the appropriate API,
* and in some cases the property value needs to be modified before setting.
*/
- public boolean restoreValue(String name, String value) {
- if (Settings.System.SCREEN_BRIGHTNESS.equals(name)) {
- setBrightness(Integer.parseInt(value));
- } else if (Settings.System.SOUND_EFFECTS_ENABLED.equals(name)) {
- setSoundEffects(Integer.parseInt(value) == 1);
- } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
- setGpsLocation(value);
- return false;
- } else if (Settings.Secure.BACKUP_AUTO_RESTORE.equals(name)) {
- setAutoRestore(Integer.parseInt(value) == 1);
- } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) {
- return false;
- } else if (Settings.System.RINGTONE.equals(name)
- || Settings.System.NOTIFICATION_SOUND.equals(name)) {
- setRingtone(name, value);
- return false;
+ public void restoreValue(Context context, ContentResolver cr, ContentValues contentValues,
+ Uri destination, String name, String value) {
+ // Will we need a post-restore broadcast for this element?
+ String oldValue = null;
+ boolean sendBroadcast = false;
+ final SettingsLookup table;
+
+ if (destination.equals(Settings.Secure.CONTENT_URI)) {
+ table = sSecureLookup;
+ } else if (destination.equals(Settings.System.CONTENT_URI)) {
+ table = sSystemLookup;
+ } else { /* must be GLOBAL; this was preflighted by the caller */
+ table = sGlobalLookup;
+ }
+
+ if (sBroadcastOnRestore.contains(name)) {
+ oldValue = table.lookup(cr, name, UserHandle.USER_OWNER);
+ sendBroadcast = true;
+ }
+
+ try {
+ if (Settings.System.SCREEN_BRIGHTNESS.equals(name)) {
+ setBrightness(Integer.parseInt(value));
+ // fall through to the ordinary write to settings
+ } else if (Settings.System.SOUND_EFFECTS_ENABLED.equals(name)) {
+ setSoundEffects(Integer.parseInt(value) == 1);
+ // fall through to the ordinary write to settings
+ } else if (Settings.Secure.LOCATION_PROVIDERS_ALLOWED.equals(name)) {
+ setGpsLocation(value);
+ return;
+ } else if (Settings.Secure.BACKUP_AUTO_RESTORE.equals(name)) {
+ setAutoRestore(Integer.parseInt(value) == 1);
+ } else if (isAlreadyConfiguredCriticalAccessibilitySetting(name)) {
+ return;
+ } else if (Settings.System.RINGTONE.equals(name)
+ || Settings.System.NOTIFICATION_SOUND.equals(name)) {
+ setRingtone(name, value);
+ return;
+ }
+
+ // Default case: write the restored value to settings
+ contentValues.clear();
+ contentValues.put(Settings.NameValueTable.NAME, name);
+ contentValues.put(Settings.NameValueTable.VALUE, value);
+ cr.insert(destination, contentValues);
+ } catch (Exception e) {
+ // If we fail to apply the setting, by definition nothing happened
+ sendBroadcast = false;
+ } finally {
+ // If this was an element of interest, send the "we just restored it"
+ // broadcast with the historical value now that the new value has
+ // been committed and observers kicked off.
+ if (sendBroadcast) {
+ Intent intent = new Intent(Intent.ACTION_SETTING_RESTORED)
+ .setPackage("android").addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY)
+ .putExtra(Intent.EXTRA_SETTING_NAME, name)
+ .putExtra(Intent.EXTRA_SETTING_NEW_VALUE, value)
+ .putExtra(Intent.EXTRA_SETTING_PREVIOUS_VALUE, oldValue);
+ context.sendBroadcastAsUser(intent, UserHandle.OWNER, null);
+ }
}
- return true;
}
public String onBackupValue(String name, String value) {