diff options
Diffstat (limited to 'core/java/android/backup')
| -rw-r--r-- | core/java/android/backup/BackupDataOutput.java | 7 | ||||
| -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.java | 56 | ||||
| -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.java | 83 | ||||
| -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.java | 41 | ||||
| -rw-r--r-- | core/java/android/backup/SharedPreferencesBackupHelper.java | 40 |
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); + } } } |
