summaryrefslogtreecommitdiffstats
path: root/core/java/android/backup
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/backup')
-rw-r--r--core/java/android/backup/BackupDataOutput.java7
-rw-r--r--core/java/android/backup/BackupHelper.java (renamed from core/java/android/backup/RestoreHelper.java)18
-rw-r--r--core/java/android/backup/BackupHelperAgent.java56
-rw-r--r--core/java/android/backup/BackupHelperDispatcher.java (renamed from core/java/android/backup/RestoreHelperDispatcher.java)40
-rw-r--r--core/java/android/backup/FileBackupHelper.java83
-rw-r--r--core/java/android/backup/FileBackupHelperBase.java (renamed from core/java/android/backup/RestoreHelperBase.java)54
-rw-r--r--core/java/android/backup/FileRestoreHelper.java41
-rw-r--r--core/java/android/backup/SharedPreferencesBackupHelper.java40
8 files changed, 196 insertions, 143 deletions
diff --git a/core/java/android/backup/BackupDataOutput.java b/core/java/android/backup/BackupDataOutput.java
index 05e667e..d29c5ba 100644
--- a/core/java/android/backup/BackupDataOutput.java
+++ b/core/java/android/backup/BackupDataOutput.java
@@ -55,6 +55,10 @@ public class BackupDataOutput {
}
}
+ public void setKeyPrefix(String keyPrefix) {
+ setKeyPrefix_native(mBackupWriter, keyPrefix);
+ }
+
protected void finalize() throws Throwable {
try {
dtor(mBackupWriter);
@@ -62,11 +66,12 @@ public class BackupDataOutput {
super.finalize();
}
}
-
+
private native static int ctor(FileDescriptor fd);
private native static void dtor(int mBackupWriter);
private native static int writeEntityHeader_native(int mBackupWriter, String key, int dataSize);
private native static int writeEntityData_native(int mBackupWriter, byte[] data, int size);
+ private native static void setKeyPrefix_native(int mBackupWriter, String keyPrefix);
}
diff --git a/core/java/android/backup/RestoreHelper.java b/core/java/android/backup/BackupHelper.java
index e47869c..3983e28 100644
--- a/core/java/android/backup/RestoreHelper.java
+++ b/core/java/android/backup/BackupHelper.java
@@ -21,14 +21,26 @@ import android.os.ParcelFileDescriptor;
import java.io.InputStream;
/** @hide */
-public interface RestoreHelper {
+public interface BackupHelper {
/**
- * Called by RestoreHelperDispatcher to dispatch one entity of data.
+ * Based on oldState, determine which of the files from the application's data directory
+ * need to be backed up, write them to the data stream, and fill in newState with the
+ * state as it exists now.
+ */
+ public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState);
+
+ /**
+ * Called by BackupHelperDispatcher to dispatch one entity of data.
* <p class=note>
* Do not close the <code>data</code> stream. Do not read more than
* <code>dataSize</code> bytes from <code>data</code>.
*/
public void restoreEntity(BackupDataInputStream data);
- public void writeSnapshot(ParcelFileDescriptor fd);
+
+ /**
+ *
+ */
+ public void writeRestoreSnapshot(ParcelFileDescriptor fd);
}
diff --git a/core/java/android/backup/BackupHelperAgent.java b/core/java/android/backup/BackupHelperAgent.java
new file mode 100644
index 0000000..f7eb1b8
--- /dev/null
+++ b/core/java/android/backup/BackupHelperAgent.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2007 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 android.backup;
+
+import android.app.BackupAgent;
+import android.backup.BackupHelper;
+import android.backup.BackupHelperDispatcher;
+import android.backup.BackupDataInput;
+import android.backup.BackupDataOutput;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import java.io.IOException;
+
+/** @hide */
+public class BackupHelperAgent extends BackupAgent {
+ static final String TAG = "BackupHelperAgent";
+
+ BackupHelperDispatcher mDispatcher = new BackupHelperDispatcher();
+
+ @Override
+ public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) {
+ mDispatcher.performBackup(oldState, data, newState);
+ }
+
+ @Override
+ public void onRestore(BackupDataInput data, ParcelFileDescriptor newState)
+ throws IOException {
+ mDispatcher.performRestore(data, newState);
+ }
+
+ public BackupHelperDispatcher getDispatcher() {
+ return mDispatcher;
+ }
+
+ public void addHelper(String keyPrefix, BackupHelper helper) {
+ mDispatcher.addHelper(keyPrefix, helper);
+ }
+}
+
+
diff --git a/core/java/android/backup/RestoreHelperDispatcher.java b/core/java/android/backup/BackupHelperDispatcher.java
index 4861775..e9a8f71 100644
--- a/core/java/android/backup/RestoreHelperDispatcher.java
+++ b/core/java/android/backup/BackupHelperDispatcher.java
@@ -20,20 +20,34 @@ import android.os.ParcelFileDescriptor;
import android.util.Log;
import java.io.IOException;
-import java.util.HashMap;
+import java.util.TreeMap;
import java.util.Map;
/** @hide */
-public class RestoreHelperDispatcher {
- private static final String TAG = "RestoreHelperDispatcher";
+public class BackupHelperDispatcher {
+ private static final String TAG = "BackupHelperDispatcher";
- HashMap<String,RestoreHelper> mHelpers = new HashMap<String,RestoreHelper>();
+ TreeMap<String,BackupHelper> mHelpers = new TreeMap<String,BackupHelper>();
+
+ public BackupHelperDispatcher() {
+ }
- public void addHelper(String keyPrefix, RestoreHelper helper) {
+ public void addHelper(String keyPrefix, BackupHelper helper) {
mHelpers.put(keyPrefix, helper);
}
- public void dispatch(BackupDataInput input, ParcelFileDescriptor newState) throws IOException {
+ /** TODO: Make this save and restore the key prefix. */
+ public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) {
+ // Write out the state files -- mHelpers is a TreeMap, so the order is well defined.
+ for (Map.Entry<String,BackupHelper> entry: mHelpers.entrySet()) {
+ data.setKeyPrefix(entry.getKey());
+ entry.getValue().performBackup(oldState, data, newState);
+ }
+ }
+
+ public void performRestore(BackupDataInput input, ParcelFileDescriptor newState)
+ throws IOException {
boolean alreadyComplained = false;
BackupDataInputStream stream = new BackupDataInputStream(input);
@@ -43,7 +57,7 @@ public class RestoreHelperDispatcher {
int pos = rawKey.indexOf(':');
if (pos > 0) {
String prefix = rawKey.substring(0, pos);
- RestoreHelper helper = mHelpers.get(prefix);
+ BackupHelper helper = mHelpers.get(prefix);
if (helper != null) {
stream.dataSize = input.getDataSize();
stream.key = rawKey.substring(pos+1);
@@ -63,15 +77,9 @@ public class RestoreHelperDispatcher {
input.skipEntityData(); // In case they didn't consume the data.
}
- if (mHelpers.size() > 1) {
- throw new RuntimeException("RestoreHelperDispatcher won't get your your"
- + " data in the right order yet.");
- }
-
- // Write out the state files
- for (RestoreHelper helper: mHelpers.values()) {
- // TODO: Write a header for the state
- helper.writeSnapshot(newState);
+ // Write out the state files -- mHelpers is a TreeMap, so the order is well defined.
+ for (BackupHelper helper: mHelpers.values()) {
+ helper.writeRestoreSnapshot(newState);
}
}
}
diff --git a/core/java/android/backup/FileBackupHelper.java b/core/java/android/backup/FileBackupHelper.java
index ed840bb..4058497 100644
--- a/core/java/android/backup/FileBackupHelper.java
+++ b/core/java/android/backup/FileBackupHelper.java
@@ -24,19 +24,19 @@ import java.io.File;
import java.io.FileDescriptor;
/** @hide */
-public class FileBackupHelper {
+public class FileBackupHelper extends FileBackupHelperBase implements BackupHelper {
private static final String TAG = "FileBackupHelper";
Context mContext;
- String mKeyPrefix;
+ File mFilesDir;
+ String[] mFiles;
- public FileBackupHelper(Context context) {
- mContext = context;
- }
+ public FileBackupHelper(Context context, String... files) {
+ super(context);
- public FileBackupHelper(Context context, String keyPrefix) {
mContext = context;
- mKeyPrefix = keyPrefix;
+ mFilesDir = context.getFilesDir();
+ mFiles = files;
}
/**
@@ -45,8 +45,9 @@ public class FileBackupHelper {
* state as it exists now.
*/
public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
- ParcelFileDescriptor newState, String[] files) {
+ ParcelFileDescriptor newState) {
// file names
+ String[] files = mFiles;
File base = mContext.getFilesDir();
final int N = files.length;
String[] fullPaths = new String[N];
@@ -54,66 +55,18 @@ public class FileBackupHelper {
fullPaths[i] = (new File(base, files[i])).getAbsolutePath();
}
- // keys
- String[] keys = makeKeys(mKeyPrefix, files);
-
// go
- performBackup_checked(oldState, data, newState, fullPaths, keys);
+ performBackup_checked(oldState, data, newState, fullPaths, files);
}
- /**
- * If keyPrefix is not null, prepend it to each of the strings in <code>original</code>;
- * otherwise, return original.
- */
- static String[] makeKeys(String keyPrefix, String[] original) {
- if (keyPrefix != null) {
- String[] keys;
- final int N = original.length;
- keys = new String[N];
- for (int i=0; i<N; i++) {
- keys[i] = keyPrefix + ':' + original[i];
- }
- return keys;
- } else {
- return original;
- }
- }
-
- /**
- * Check the parameters so the native code doens't have to throw all the exceptions
- * since it's easier to do that from java.
- */
- static void performBackup_checked(ParcelFileDescriptor oldState, BackupDataOutput data,
- ParcelFileDescriptor newState, String[] files, String[] keys) {
- if (files.length == 0) {
- return;
- }
- // files must be all absolute paths
- for (String f: files) {
- if (f.charAt(0) != '/') {
- throw new RuntimeException("files must have all absolute paths: " + f);
- }
- }
- // the length of files and keys must be the same
- if (files.length != keys.length) {
- throw new RuntimeException("files.length=" + files.length
- + " keys.length=" + keys.length);
- }
- // oldStateFd can be null
- FileDescriptor oldStateFd = oldState != null ? oldState.getFileDescriptor() : null;
- FileDescriptor newStateFd = newState.getFileDescriptor();
- if (newStateFd == null) {
- throw new NullPointerException();
- }
-
- int err = performBackup_native(oldStateFd, data.mBackupWriter, newStateFd, files, keys);
-
- if (err != 0) {
- // TODO: more here
- throw new RuntimeException("Backup failed 0x" + Integer.toHexString(err));
+ public void restoreEntity(BackupDataInputStream data) {
+ // TODO: turn this off before ship
+ Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size());
+ String key = data.getKey();
+ if (isKeyInList(key, mFiles)) {
+ File f = new File(mFilesDir, key);
+ writeFile(f, data);
}
}
-
- native private static int performBackup_native(FileDescriptor oldState,
- int data, FileDescriptor newState, String[] files, String[] keys);
}
+
diff --git a/core/java/android/backup/RestoreHelperBase.java b/core/java/android/backup/FileBackupHelperBase.java
index 93a8fef..03ae476 100644
--- a/core/java/android/backup/RestoreHelperBase.java
+++ b/core/java/android/backup/FileBackupHelperBase.java
@@ -25,14 +25,14 @@ import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
-class RestoreHelperBase {
+class FileBackupHelperBase {
private static final String TAG = "RestoreHelperBase";
int mPtr;
Context mContext;
boolean mExceptionLogged;
- RestoreHelperBase(Context context) {
+ FileBackupHelperBase(Context context) {
mPtr = ctor();
mContext = context;
}
@@ -45,6 +45,41 @@ class RestoreHelperBase {
}
}
+ /**
+ * Check the parameters so the native code doens't have to throw all the exceptions
+ * since it's easier to do that from java.
+ */
+ static void performBackup_checked(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState, String[] files, String[] keys) {
+ if (files.length == 0) {
+ return;
+ }
+ // files must be all absolute paths
+ for (String f: files) {
+ if (f.charAt(0) != '/') {
+ throw new RuntimeException("files must have all absolute paths: " + f);
+ }
+ }
+ // the length of files and keys must be the same
+ if (files.length != keys.length) {
+ throw new RuntimeException("files.length=" + files.length
+ + " keys.length=" + keys.length);
+ }
+ // oldStateFd can be null
+ FileDescriptor oldStateFd = oldState != null ? oldState.getFileDescriptor() : null;
+ FileDescriptor newStateFd = newState.getFileDescriptor();
+ if (newStateFd == null) {
+ throw new NullPointerException();
+ }
+
+ int err = performBackup_native(oldStateFd, data.mBackupWriter, newStateFd, files, keys);
+
+ if (err != 0) {
+ // TODO: more here
+ throw new RuntimeException("Backup failed 0x" + Integer.toHexString(err));
+ }
+ }
+
void writeFile(File f, InputStream in) {
if (!(in instanceof BackupDataInputStream)) {
throw new IllegalStateException("input stream must be a BackupDataInputStream");
@@ -68,13 +103,26 @@ class RestoreHelperBase {
}
}
- public void writeSnapshot(ParcelFileDescriptor fd) {
+ public void writeRestoreSnapshot(ParcelFileDescriptor fd) {
int result = writeSnapshot_native(mPtr, fd.getFileDescriptor());
// TODO: Do something with the error.
}
+ boolean isKeyInList(String key, String[] list) {
+ for (String s: list) {
+ if (s.equals(key)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private static native int ctor();
private static native void dtor(int ptr);
+
+ native private static int performBackup_native(FileDescriptor oldState,
+ int data, FileDescriptor newState, String[] files, String[] keys);
+
private static native int writeFile_native(int ptr, String filename, int backupReader);
private static native int writeSnapshot_native(int ptr, FileDescriptor fd);
}
diff --git a/core/java/android/backup/FileRestoreHelper.java b/core/java/android/backup/FileRestoreHelper.java
deleted file mode 100644
index b7e3625..0000000
--- a/core/java/android/backup/FileRestoreHelper.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2009 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 android.backup;
-
-import android.content.Context;
-import android.util.Log;
-
-import java.io.File;
-
-/** @hide */
-public class FileRestoreHelper extends RestoreHelperBase implements RestoreHelper {
- private static final String TAG = "FileRestoreHelper";
-
- File mFilesDir;
-
- public FileRestoreHelper(Context context) {
- super(context);
- mFilesDir = context.getFilesDir();
- }
-
- public void restoreEntity(BackupDataInputStream data) {
- Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size()); // TODO: turn this off before ship
- File f = new File(mFilesDir, data.getKey());
- writeFile(f, data);
- }
-}
-
diff --git a/core/java/android/backup/SharedPreferencesBackupHelper.java b/core/java/android/backup/SharedPreferencesBackupHelper.java
index cad79df..f492629 100644
--- a/core/java/android/backup/SharedPreferencesBackupHelper.java
+++ b/core/java/android/backup/SharedPreferencesBackupHelper.java
@@ -18,39 +18,51 @@ package android.backup;
import android.content.Context;
import android.os.ParcelFileDescriptor;
+import android.util.Log;
+import java.io.File;
import java.io.FileDescriptor;
/** @hide */
-public class SharedPreferencesBackupHelper {
+public class SharedPreferencesBackupHelper extends FileBackupHelperBase implements BackupHelper {
+ private static final String TAG = "SharedPreferencesBackupHelper";
+
private Context mContext;
- private String mKeyPrefix;
+ private String[] mPrefGroups;
- public SharedPreferencesBackupHelper(Context context) {
- mContext = context;
- }
+ public SharedPreferencesBackupHelper(Context context, String[] prefGroups) {
+ super(context);
- public SharedPreferencesBackupHelper(Context context, String keyPrefix) {
mContext = context;
- mKeyPrefix = keyPrefix;
+ mPrefGroups = prefGroups;
}
-
- public void performBackup(ParcelFileDescriptor oldSnapshot, ParcelFileDescriptor newSnapshot,
- BackupDataOutput data, String[] prefGroups) {
+
+ public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
+ ParcelFileDescriptor newState) {
Context context = mContext;
// make filenames for the prefGroups
+ String[] prefGroups = mPrefGroups;
final int N = prefGroups.length;
String[] files = new String[N];
for (int i=0; i<N; i++) {
files[i] = context.getSharedPrefsFile(prefGroups[i]).getAbsolutePath();
}
- // make keys if necessary
- String[] keys = FileBackupHelper.makeKeys(mKeyPrefix, prefGroups);
-
// go
- FileBackupHelper.performBackup_checked(oldSnapshot, data, newSnapshot, files, prefGroups);
+ performBackup_checked(oldState, data, newState, files, prefGroups);
+ }
+
+ public void restoreEntity(BackupDataInputStream data) {
+ Context context = mContext;
+
+ // TODO: turn this off before ship
+ Log.d(TAG, "got entity '" + data.getKey() + "' size=" + data.size());
+ String key = data.getKey();
+ if (isKeyInList(key, mPrefGroups)) {
+ File f = context.getSharedPrefsFile(key).getAbsoluteFile();
+ writeFile(f, data);
+ }
}
}