diff options
Diffstat (limited to 'packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java')
-rw-r--r-- | packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java | 152 |
1 files changed, 119 insertions, 33 deletions
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java index 45bb2b6..0c4ef7d 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java @@ -55,6 +55,7 @@ import android.util.Log; */ public class SettingsBackupAgent extends BackupAgentHelper { private static final boolean DEBUG = false; + private static final boolean DEBUG_BACKUP = DEBUG || true; private static final String KEY_SYSTEM = "system"; private static final String KEY_SECURE = "secure"; @@ -75,6 +76,9 @@ public class SettingsBackupAgent extends BackupAgentHelper { private static final int STATE_WIFI_CONFIG = 4; private static final int STATE_SIZE = 5; // The number of state items + // Versioning of the 'full backup' format + private static final int FULL_BACKUP_VERSION = 1; + private static String[] sortedSystemKeys = null; private static String[] sortedSecureKeys = null; @@ -109,6 +113,8 @@ public class SettingsBackupAgent extends BackupAgentHelper { private static String mWifiConfigFile; public void onCreate() { + if (DEBUG_BACKUP) Log.d(TAG, "onCreate() invoked"); + mSettingsHelper = new SettingsHelper(this); super.onCreate(); @@ -151,26 +157,32 @@ public class SettingsBackupAgent extends BackupAgentHelper { // representation of the backed-up settings. String root = getFilesDir().getAbsolutePath(); File stage = new File(root, STAGE_FILE); - FileOutputStream filestream = new FileOutputStream(stage); - BufferedOutputStream bufstream = new BufferedOutputStream(filestream); - DataOutputStream out = new DataOutputStream(bufstream); - - out.writeInt(systemSettingsData.length); - out.write(systemSettingsData); - out.writeInt(secureSettingsData.length); - out.write(secureSettingsData); - out.writeInt(locale.length); - out.write(locale); - out.writeInt(wifiSupplicantData.length); - out.write(wifiSupplicantData); - out.writeInt(wifiConfigData.length); - out.write(wifiConfigData); - - out.flush(); // also flushes downstream - - // now we're set to emit the tar stream - FullBackup.backupToTar(getPackageName(), FullBackup.DATA_TREE_TOKEN, null, - root, stage.getAbsolutePath(), data); + try { + FileOutputStream filestream = new FileOutputStream(stage); + BufferedOutputStream bufstream = new BufferedOutputStream(filestream); + DataOutputStream out = new DataOutputStream(bufstream); + + out.writeInt(FULL_BACKUP_VERSION); + + out.writeInt(systemSettingsData.length); + out.write(systemSettingsData); + out.writeInt(secureSettingsData.length); + out.write(secureSettingsData); + out.writeInt(locale.length); + out.write(locale); + out.writeInt(wifiSupplicantData.length); + out.write(wifiSupplicantData); + out.writeInt(wifiConfigData.length); + out.write(wifiConfigData); + + out.flush(); // also flushes downstream + + // now we're set to emit the tar stream + FullBackup.backupToTar(getPackageName(), FullBackup.DATA_TREE_TOKEN, null, + root, stage.getAbsolutePath(), data); + } finally { + stage.delete(); + } } } @@ -199,7 +211,7 @@ public class SettingsBackupAgent extends BackupAgentHelper { } else if (KEY_LOCALE.equals(key)) { byte[] localeData = new byte[size]; data.readEntityData(localeData, 0, size); - mSettingsHelper.setLocaleData(localeData); + mSettingsHelper.setLocaleData(localeData, size); } else if (KEY_WIFI_CONFIG.equals(key)) { restoreFileData(mWifiConfigFile, data); } else { @@ -208,6 +220,70 @@ public class SettingsBackupAgent extends BackupAgentHelper { } } + @Override + public void onRestoreFile(ParcelFileDescriptor data, long size, + int type, String domain, String relpath, long mode, long mtime) + throws IOException { + if (DEBUG_BACKUP) Log.d(TAG, "onRestoreFile() invoked"); + // Our data is actually a blob of flattened settings data identical to that + // produced during incremental backups. Just unpack and apply it all in + // turn. + FileInputStream instream = new FileInputStream(data.getFileDescriptor()); + DataInputStream in = new DataInputStream(instream); + + int version = in.readInt(); + if (DEBUG_BACKUP) Log.d(TAG, "Flattened data version " + version); + if (version == FULL_BACKUP_VERSION) { + // system settings data first + int nBytes = in.readInt(); + if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of settings data"); + byte[] buffer = new byte[nBytes]; + in.read(buffer, 0, nBytes); + restoreSettings(buffer, nBytes, Settings.System.CONTENT_URI); + + // secure settings + nBytes = in.readInt(); + if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of secure settings data"); + if (nBytes > buffer.length) buffer = new byte[nBytes]; + in.read(buffer, 0, nBytes); + restoreSettings(buffer, nBytes, Settings.Secure.CONTENT_URI); + + // locale + nBytes = in.readInt(); + if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of locale data"); + if (nBytes > buffer.length) buffer = new byte[nBytes]; + in.read(buffer, 0, nBytes); + mSettingsHelper.setLocaleData(buffer, nBytes); + + // wifi supplicant + nBytes = in.readInt(); + if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of wifi supplicant data"); + if (nBytes > buffer.length) buffer = new byte[nBytes]; + in.read(buffer, 0, nBytes); + int retainedWifiState = enableWifi(false); + restoreWifiSupplicant(FILE_WIFI_SUPPLICANT, buffer, nBytes); + FileUtils.setPermissions(FILE_WIFI_SUPPLICANT, + FileUtils.S_IRUSR | FileUtils.S_IWUSR | + FileUtils.S_IRGRP | FileUtils.S_IWGRP, + Process.myUid(), Process.WIFI_UID); + // retain the previous WIFI state. + enableWifi(retainedWifiState == WifiManager.WIFI_STATE_ENABLED || + retainedWifiState == WifiManager.WIFI_STATE_ENABLING); + + // wifi config + nBytes = in.readInt(); + if (DEBUG_BACKUP) Log.d(TAG, nBytes + " bytes of wifi config data"); + if (nBytes > buffer.length) buffer = new byte[nBytes]; + in.read(buffer, 0, nBytes); + restoreFileData(mWifiConfigFile, buffer, nBytes); + + if (DEBUG_BACKUP) Log.d(TAG, "Full restore complete."); + } else { + data.close(); + throw new IOException("Invalid file schema"); + } + } + private long[] readOldChecksums(ParcelFileDescriptor oldState) throws IOException { long[] stateChecksums = new long[STATE_SIZE]; @@ -287,6 +363,17 @@ public class SettingsBackupAgent extends BackupAgentHelper { } private void restoreSettings(BackupDataInput data, Uri contentUri) { + byte[] settings = new byte[data.getDataSize()]; + try { + data.readEntityData(settings, 0, settings.length); + } catch (IOException ioe) { + Log.e(TAG, "Couldn't read entity data"); + return; + } + restoreSettings(settings, settings.length, contentUri); + } + + private void restoreSettings(byte[] settings, int bytes, Uri contentUri) { if (DEBUG) Log.i(TAG, "restoreSettings: " + contentUri); String[] whitelist = null; if (contentUri.equals(Settings.Secure.CONTENT_URI)) { @@ -296,15 +383,8 @@ public class SettingsBackupAgent extends BackupAgentHelper { } ContentValues cv = new ContentValues(2); - byte[] settings = new byte[data.getDataSize()]; - try { - data.readEntityData(settings, 0, settings.length); - } catch (IOException ioe) { - Log.e(TAG, "Couldn't read entity data"); - return; - } int pos = 0; - while (pos < settings.length) { + while (pos < bytes) { int length = readInt(settings, pos); pos += 4; String settingName = length > 0? new String(settings, pos, length) : null; @@ -451,13 +531,16 @@ public class SettingsBackupAgent extends BackupAgentHelper { private void restoreFileData(String filename, BackupDataInput data) { byte[] bytes = new byte[data.getDataSize()]; if (bytes.length <= 0) return; + restoreFileData(filename, bytes, bytes.length); + } + + private void restoreFileData(String filename, byte[] bytes, int size) { try { - data.readEntityData(bytes, 0, bytes.length); File file = new File(filename); if (file.exists()) file.delete(); OutputStream os = new BufferedOutputStream(new FileOutputStream(filename, true)); - os.write(bytes); + os.write(bytes, 0, size); os.close(); } catch (IOException ioe) { Log.w(TAG, "Couldn't restore " + filename); @@ -506,15 +589,18 @@ public class SettingsBackupAgent extends BackupAgentHelper { private void restoreWifiSupplicant(String filename, BackupDataInput data) { byte[] bytes = new byte[data.getDataSize()]; if (bytes.length <= 0) return; + restoreWifiSupplicant(filename, bytes, bytes.length); + } + + private void restoreWifiSupplicant(String filename, byte[] bytes, int size) { try { - data.readEntityData(bytes, 0, bytes.length); File supplicantFile = new File(FILE_WIFI_SUPPLICANT); if (supplicantFile.exists()) supplicantFile.delete(); copyWifiSupplicantTemplate(); OutputStream os = new BufferedOutputStream(new FileOutputStream(filename, true)); os.write("\n".getBytes()); - os.write(bytes); + os.write(bytes, 0, size); os.close(); } catch (IOException ioe) { Log.w(TAG, "Couldn't restore " + filename); |