summaryrefslogtreecommitdiffstats
path: root/packages/SettingsProvider/src
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SettingsProvider/src')
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java105
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java11
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java7
3 files changed, 100 insertions, 23 deletions
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index b6bc8a5..2b36904 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -16,12 +16,16 @@
package com.android.providers.settings;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.EOFException;
import java.util.Arrays;
import java.util.HashMap;
+import java.util.zip.CRC32;
import android.backup.BackupDataInput;
import android.backup.BackupDataOutput;
@@ -34,7 +38,9 @@ import android.database.Cursor;
import android.media.AudioManager;
import android.net.Uri;
import android.net.wifi.WifiManager;
+import android.os.FileUtils;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
@@ -52,6 +58,13 @@ public class SettingsBackupAgent extends BackupHelperAgent {
private static final String KEY_SYNC = "sync_providers";
private static final String KEY_LOCALE = "locale";
+ private static final int STATE_SYSTEM = 0;
+ private static final int STATE_SECURE = 1;
+ private static final int STATE_SYNC = 2;
+ private static final int STATE_LOCALE = 3;
+ private static final int STATE_WIFI = 4;
+ private static final int STATE_SIZE = 5; // The number of state items
+
private static String[] sortedSystemKeys = null;
private static String[] sortedSecureKeys = null;
@@ -87,20 +100,22 @@ public class SettingsBackupAgent extends BackupHelperAgent {
byte[] secureSettingsData = getSecureSettings();
byte[] syncProviders = mSettingsHelper.getSyncProviders();
byte[] locale = mSettingsHelper.getLocaleData();
-
- data.writeEntityHeader(KEY_SYSTEM, systemSettingsData.length);
- data.writeEntityData(systemSettingsData, systemSettingsData.length);
-
- data.writeEntityHeader(KEY_SECURE, secureSettingsData.length);
- data.writeEntityData(secureSettingsData, secureSettingsData.length);
-
- data.writeEntityHeader(KEY_SYNC, syncProviders.length);
- data.writeEntityData(syncProviders, syncProviders.length);
-
- data.writeEntityHeader(KEY_LOCALE, locale.length);
- data.writeEntityData(locale, locale.length);
-
- backupFile(FILE_WIFI_SUPPLICANT, data);
+ byte[] wifiData = getFileData(FILE_WIFI_SUPPLICANT);
+
+ long[] stateChecksums = readOldChecksums(oldState);
+
+ stateChecksums[STATE_SYSTEM] =
+ writeIfChanged(stateChecksums[STATE_SYSTEM], KEY_SYSTEM, systemSettingsData, data);
+ stateChecksums[STATE_SECURE] =
+ writeIfChanged(stateChecksums[STATE_SECURE], KEY_SECURE, secureSettingsData, data);
+ stateChecksums[STATE_SYNC] =
+ writeIfChanged(stateChecksums[STATE_SYNC], KEY_SYNC, syncProviders, data);
+ stateChecksums[STATE_LOCALE] =
+ writeIfChanged(stateChecksums[STATE_LOCALE], KEY_LOCALE, locale, data);
+ stateChecksums[STATE_WIFI] =
+ writeIfChanged(stateChecksums[STATE_WIFI], FILE_WIFI_SUPPLICANT, wifiData, data);
+
+ writeNewChecksums(stateChecksums, newState);
}
@Override
@@ -115,11 +130,15 @@ public class SettingsBackupAgent extends BackupHelperAgent {
final int size = data.getDataSize();
if (KEY_SYSTEM.equals(key)) {
restoreSettings(data, Settings.System.CONTENT_URI);
+ mSettingsHelper.applyAudioSettings();
} else if (KEY_SECURE.equals(key)) {
restoreSettings(data, Settings.Secure.CONTENT_URI);
-// TODO: Re-enable WIFI restore when we figure out a solution for the permissions
-// } else if (FILE_WIFI_SUPPLICANT.equals(key)) {
-// restoreFile(FILE_WIFI_SUPPLICANT, data);
+ } else if (FILE_WIFI_SUPPLICANT.equals(key)) {
+ restoreFile(FILE_WIFI_SUPPLICANT, data);
+ FileUtils.setPermissions(FILE_WIFI_SUPPLICANT,
+ FileUtils.S_IRUSR | FileUtils.S_IWUSR |
+ FileUtils.S_IRGRP | FileUtils.S_IWGRP,
+ Process.myUid(), Process.WIFI_UID);
} else if (KEY_SYNC.equals(key)) {
mSettingsHelper.setSyncProviders(data);
} else if (KEY_LOCALE.equals(key)) {
@@ -132,6 +151,49 @@ public class SettingsBackupAgent extends BackupHelperAgent {
}
}
+ private long[] readOldChecksums(ParcelFileDescriptor oldState) throws IOException {
+ long[] stateChecksums = new long[STATE_SIZE];
+
+ DataInputStream dataInput = new DataInputStream(
+ new FileInputStream(oldState.getFileDescriptor()));
+ for (int i = 0; i < STATE_SIZE; i++) {
+ try {
+ stateChecksums[i] = dataInput.readLong();
+ } catch (EOFException eof) {
+ break;
+ }
+ }
+ dataInput.close();
+ return stateChecksums;
+ }
+
+ private void writeNewChecksums(long[] checksums, ParcelFileDescriptor newState)
+ throws IOException {
+ DataOutputStream dataOutput = new DataOutputStream(
+ new FileOutputStream(newState.getFileDescriptor()));
+ for (int i = 0; i < STATE_SIZE; i++) {
+ dataOutput.writeLong(checksums[i]);
+ }
+ dataOutput.close();
+ }
+
+ private long writeIfChanged(long oldChecksum, String key, byte[] data,
+ BackupDataOutput output) {
+ CRC32 checkSummer = new CRC32();
+ checkSummer.update(data);
+ long newChecksum = checkSummer.getValue();
+ if (oldChecksum == newChecksum) {
+ return oldChecksum;
+ }
+ try {
+ output.writeEntityHeader(key, data.length);
+ output.writeEntityData(data, data.length);
+ } catch (IOException ioe) {
+ // Bail
+ }
+ return newChecksum;
+ }
+
private byte[] getSystemSettings() {
Cursor sortedCursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION,
null, null, Settings.NameValueTable.NAME);
@@ -248,7 +310,7 @@ public class SettingsBackupAgent extends BackupHelperAgent {
return result;
}
- private void backupFile(String filename, BackupDataOutput data) {
+ private byte[] getFileData(String filename) {
try {
File file = new File(filename);
if (file.exists()) {
@@ -260,14 +322,13 @@ public class SettingsBackupAgent extends BackupHelperAgent {
got = fis.read(bytes, offset, bytes.length - offset);
if (got > 0) offset += got;
} while (offset < bytes.length && got > 0);
- data.writeEntityHeader(filename, bytes.length);
- data.writeEntityData(bytes, bytes.length);
+ return bytes;
} else {
- data.writeEntityHeader(filename, 0);
- data.writeEntityData(EMPTY_DATA, 0);
+ return EMPTY_DATA;
}
} catch (IOException ioe) {
Log.w(TAG, "Couldn't backup " + filename);
+ return EMPTY_DATA;
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
index 2c5775a..ca739e6 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsHelper.java
@@ -167,6 +167,9 @@ public class SettingsHelper {
// Check if locale was set by the user:
Configuration conf = mContext.getResources().getConfiguration();
Locale loc = conf.locale;
+ // TODO: The following is not working as intended because the network is forcing a locale
+ // change after registering. Need to find some other way to detect if the user manually
+ // changed the locale
if (conf.userSetLocale) return; // Don't change if user set it in the SetupWizard
final String[] availableLocales = mContext.getAssets().getLocales();
@@ -193,6 +196,14 @@ public class SettingsHelper {
} catch (RemoteException e) {
// Intentionally left blank
}
+ }
+ /**
+ * Informs the audio service of changes to the settings so that
+ * they can be re-read and applied.
+ */
+ void applyAudioSettings() {
+ AudioManager am = new AudioManager(mContext);
+ am.reloadAudioSettings();
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 2abf8b3..c0de9a5 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -126,11 +126,14 @@ public class SettingsProvider extends ContentProvider {
// a notification and then using the contract class to get their data,
// the system property will be updated and they'll get the new data.
+ boolean backedUpDataChanged = false;
String property = null, table = uri.getPathSegments().get(0);
if (table.equals("system")) {
property = Settings.System.SYS_PROP_SETTING_VERSION;
+ backedUpDataChanged = true;
} else if (table.equals("secure")) {
property = Settings.Secure.SYS_PROP_SETTING_VERSION;
+ backedUpDataChanged = true;
} else if (table.equals("gservices")) {
property = Settings.Gservices.SYS_PROP_SETTING_VERSION;
}
@@ -142,7 +145,9 @@ public class SettingsProvider extends ContentProvider {
}
// Inform the backup manager about a data change
- mBackupManager.dataChanged();
+ if (backedUpDataChanged) {
+ mBackupManager.dataChanged();
+ }
// Now send the notification through the content framework.
String notify = uri.getQueryParameter("notify");