backup fixes:

- BackupTestAgent calls the DispatchHelper
- Make BackupAgent.onRestore take a BackupDataInput, not just a
  generic ParcelFileDescriptor.
This commit is contained in:
Joe Onorato
2009-06-17 17:55:20 -07:00
parent 6ce1983a2b
commit 83248c432f
7 changed files with 63 additions and 19 deletions

View File

@@ -17,6 +17,7 @@
package android.app; package android.app;
import android.app.IBackupAgent; import android.app.IBackupAgent;
import android.backup.BackupDataInput;
import android.backup.BackupDataOutput; import android.backup.BackupDataOutput;
import android.content.Context; import android.content.Context;
import android.content.ContextWrapper; import android.content.ContextWrapper;
@@ -25,6 +26,8 @@ import android.os.ParcelFileDescriptor;
import android.os.RemoteException; import android.os.RemoteException;
import android.util.Log; import android.util.Log;
import java.io.IOException;
/** /**
* This is the central interface between an application and Android's * This is the central interface between an application and Android's
* settings backup mechanism. * settings backup mechanism.
@@ -32,6 +35,8 @@ import android.util.Log;
* @hide pending API solidification * @hide pending API solidification
*/ */
public abstract class BackupAgent extends ContextWrapper { public abstract class BackupAgent extends ContextWrapper {
private static final String TAG = "BackupAgent";
public BackupAgent() { public BackupAgent() {
super(null); super(null);
} }
@@ -77,8 +82,8 @@ public abstract class BackupAgent extends ContextWrapper {
* file. The application should record the final backup state * file. The application should record the final backup state
* here after restoring its data from dataFd. * here after restoring its data from dataFd.
*/ */
public abstract void onRestore(ParcelFileDescriptor /* TODO: BackupDataInput */ data, public abstract void onRestore(BackupDataInput data, ParcelFileDescriptor newState)
ParcelFileDescriptor newState); throws IOException;
// ----- Core implementation ----- // ----- Core implementation -----
@@ -107,13 +112,11 @@ public abstract class BackupAgent extends ContextWrapper {
ParcelFileDescriptor newState) throws RemoteException { ParcelFileDescriptor newState) throws RemoteException {
// !!! TODO - real implementation; for now just invoke the callbacks directly // !!! TODO - real implementation; for now just invoke the callbacks directly
Log.v(TAG, "doBackup() invoked"); Log.v(TAG, "doBackup() invoked");
BackupDataOutput output = new BackupDataOutput(BackupAgent.this, BackupDataOutput output = new BackupDataOutput(data.getFileDescriptor());
data.getFileDescriptor());
try { try {
BackupAgent.this.onBackup(oldState, output, newState); BackupAgent.this.onBackup(oldState, output, newState);
} catch (RuntimeException ex) { } catch (RuntimeException ex) {
Log.d("BackupAgent", "onBackup (" Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex);
+ BackupAgent.this.getClass().getName() + ") threw", ex);
throw ex; throw ex;
} }
} }
@@ -122,7 +125,16 @@ public abstract class BackupAgent extends ContextWrapper {
ParcelFileDescriptor newState) throws RemoteException { ParcelFileDescriptor newState) throws RemoteException {
// !!! TODO - real implementation; for now just invoke the callbacks directly // !!! TODO - real implementation; for now just invoke the callbacks directly
Log.v(TAG, "doRestore() invoked"); Log.v(TAG, "doRestore() invoked");
BackupAgent.this.onRestore(data, newState); BackupDataInput input = new BackupDataInput(data.getFileDescriptor());
try {
BackupAgent.this.onRestore(input, newState);
} catch (IOException ex) {
Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex);
throw new RuntimeException(ex);
} catch (RuntimeException ex) {
Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex);
throw ex;
}
} }
} }
} }

View File

@@ -1,5 +1,6 @@
package android.app; package android.app;
import android.backup.BackupDataInput;
import android.backup.BackupDataOutput; import android.backup.BackupDataOutput;
import android.backup.FileBackupHelper; import android.backup.FileBackupHelper;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
@@ -52,6 +53,6 @@ public class FullBackupAgent extends BackupAgent {
} }
@Override @Override
public void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState) { public void onRestore(BackupDataInput data, ParcelFileDescriptor newState) {
} }
} }

View File

@@ -24,13 +24,11 @@ import java.io.IOException;
/** @hide */ /** @hide */
public class BackupDataOutput { public class BackupDataOutput {
int mBackupWriter; int mBackupWriter;
private Context mContext;
public static final int OP_UPDATE = 1; public static final int OP_UPDATE = 1;
public static final int OP_DELETE = 2; public static final int OP_DELETE = 2;
public BackupDataOutput(Context context, FileDescriptor fd) { public BackupDataOutput(FileDescriptor fd) {
mContext = context;
if (fd == null) throw new NullPointerException(); if (fd == null) throw new NullPointerException();
mBackupWriter = ctor(fd); mBackupWriter = ctor(fd);
if (mBackupWriter == 0) { if (mBackupWriter == 0) {

View File

@@ -16,11 +16,15 @@
package android.backup; package android.backup;
import android.util.Log;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
/** @hide */ /** @hide */
public class RestoreHelperDispatcher { public class RestoreHelperDispatcher {
private static final String TAG = "RestoreHelperDispatcher";
HashMap<String,RestoreHelper> mHelpers = new HashMap<String,RestoreHelper>(); HashMap<String,RestoreHelper> mHelpers = new HashMap<String,RestoreHelper>();
public void addHelper(String keyPrefix, RestoreHelper helper) { public void addHelper(String keyPrefix, RestoreHelper helper) {
@@ -28,8 +32,11 @@ public class RestoreHelperDispatcher {
} }
public void dispatch(BackupDataInput input) throws IOException { public void dispatch(BackupDataInput input) throws IOException {
boolean alreadyComplained = false;
BackupDataInputStream stream = new BackupDataInputStream(input); BackupDataInputStream stream = new BackupDataInputStream(input);
while (input.readNextHeader()) { while (input.readNextHeader()) {
String rawKey = input.getKey(); String rawKey = input.getKey();
int pos = rawKey.indexOf(':'); int pos = rawKey.indexOf(':');
if (pos > 0) { if (pos > 0) {
@@ -39,6 +46,16 @@ public class RestoreHelperDispatcher {
stream.dataSize = input.getDataSize(); stream.dataSize = input.getDataSize();
stream.key = rawKey.substring(pos+1); stream.key = rawKey.substring(pos+1);
helper.restoreEntity(stream); helper.restoreEntity(stream);
} else {
if (!alreadyComplained) {
Log.w(TAG, "Couldn't find helper for: '" + rawKey + "'");
alreadyComplained = true;
}
}
} else {
if (!alreadyComplained) {
Log.w(TAG, "Entity with no prefix: '" + rawKey + "'");
alreadyComplained = true;
} }
} }
input.skipEntityData(); // In case they didn't consume the data. input.skipEntityData(); // In case they didn't consume the data.

View File

@@ -160,7 +160,7 @@ public class LocalTransport extends IBackupTransport.Stub {
File[] blobs = packageDir.listFiles(); File[] blobs = packageDir.listFiles();
int err = 0; int err = 0;
if (blobs != null && blobs.length > 0) { if (blobs != null && blobs.length > 0) {
BackupDataOutput out = new BackupDataOutput(mContext, outFd.getFileDescriptor()); BackupDataOutput out = new BackupDataOutput(outFd.getFileDescriptor());
try { try {
for (File f : blobs) { for (File f : blobs) {
FileInputStream in = new FileInputStream(f); FileInputStream in = new FileInputStream(f);

View File

@@ -144,8 +144,7 @@ public class BackupTestActivity extends ListActivity
FileBackupHelper h = new FileBackupHelper(BackupTestActivity.this, FileBackupHelper h = new FileBackupHelper(BackupTestActivity.this,
"FileBackupHelper"); "FileBackupHelper");
FileOutputStream dataFile = openFileOutput("backup_test", MODE_WORLD_READABLE); FileOutputStream dataFile = openFileOutput("backup_test", MODE_WORLD_READABLE);
BackupDataOutput data = new BackupDataOutput(BackupTestActivity.this, BackupDataOutput data = new BackupDataOutput(dataFile.getFD());
dataFile.getFD());
h.performBackup(null, data, state, new String[] { "a", "empty" }); h.performBackup(null, data, state, new String[] { "a", "empty" });
dataFile.close(); dataFile.close();
state.close(); state.close();

View File

@@ -17,28 +17,45 @@
package com.android.backuptest; package com.android.backuptest;
import android.app.BackupAgent; import android.app.BackupAgent;
import android.backup.BackupDataInput;
import android.backup.BackupDataOutput; import android.backup.BackupDataOutput;
import android.backup.FileBackupHelper; import android.backup.FileBackupHelper;
import android.backup.FileRestoreHelper;
import android.backup.RestoreHelperDispatcher;
import android.os.ParcelFileDescriptor; import android.os.ParcelFileDescriptor;
import android.util.Log; import android.util.Log;
import java.io.IOException;
public class BackupTestAgent extends BackupAgent public class BackupTestAgent extends BackupAgent
{ {
static final String TAG = "BackupTestAgent"; static final String TAG = "BackupTestAgent";
static final String SHARED_PREFS = "shared_prefs";
static final String DATA_FILES = "data_files";
static final String[] FILES = new String[] {
BackupTestActivity.FILE_NAME
};
@Override @Override
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
ParcelFileDescriptor newState) { ParcelFileDescriptor newState) {
Log.d(TAG, "onBackup"); Log.d(TAG, "onBackup");
FileBackupHelper helper = new FileBackupHelper(this);
helper.performBackup(oldState, data, newState, new String[] { (new FileBackupHelper(this, DATA_FILES)).performBackup(oldState, data, newState, FILES);
BackupTestActivity.FILE_NAME
});
} }
@Override @Override
public void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState) { public void onRestore(BackupDataInput data, ParcelFileDescriptor newState)
throws IOException {
Log.d(TAG, "onRestore"); Log.d(TAG, "onRestore");
RestoreHelperDispatcher dispatch = new RestoreHelperDispatcher();
// dispatch.addHelper(SHARED_PREFS, new SharedPrefsRestoreHelper(this));
dispatch.addHelper(DATA_FILES, new FileRestoreHelper(this));
dispatch.dispatch(data);
} }
} }