backup fixes:
- BackupTestAgent calls the DispatchHelper - Make BackupAgent.onRestore take a BackupDataInput, not just a generic ParcelFileDescriptor.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package android.app;
|
||||
|
||||
import android.app.IBackupAgent;
|
||||
import android.backup.BackupDataInput;
|
||||
import android.backup.BackupDataOutput;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
@@ -25,6 +26,8 @@ import android.os.ParcelFileDescriptor;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* This is the central interface between an application and Android's
|
||||
* settings backup mechanism.
|
||||
@@ -32,6 +35,8 @@ import android.util.Log;
|
||||
* @hide pending API solidification
|
||||
*/
|
||||
public abstract class BackupAgent extends ContextWrapper {
|
||||
private static final String TAG = "BackupAgent";
|
||||
|
||||
public BackupAgent() {
|
||||
super(null);
|
||||
}
|
||||
@@ -77,8 +82,8 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
* file. The application should record the final backup state
|
||||
* here after restoring its data from dataFd.
|
||||
*/
|
||||
public abstract void onRestore(ParcelFileDescriptor /* TODO: BackupDataInput */ data,
|
||||
ParcelFileDescriptor newState);
|
||||
public abstract void onRestore(BackupDataInput data, ParcelFileDescriptor newState)
|
||||
throws IOException;
|
||||
|
||||
|
||||
// ----- Core implementation -----
|
||||
@@ -107,13 +112,11 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
ParcelFileDescriptor newState) throws RemoteException {
|
||||
// !!! TODO - real implementation; for now just invoke the callbacks directly
|
||||
Log.v(TAG, "doBackup() invoked");
|
||||
BackupDataOutput output = new BackupDataOutput(BackupAgent.this,
|
||||
data.getFileDescriptor());
|
||||
BackupDataOutput output = new BackupDataOutput(data.getFileDescriptor());
|
||||
try {
|
||||
BackupAgent.this.onBackup(oldState, output, newState);
|
||||
} catch (RuntimeException ex) {
|
||||
Log.d("BackupAgent", "onBackup ("
|
||||
+ BackupAgent.this.getClass().getName() + ") threw", ex);
|
||||
Log.d(TAG, "onBackup (" + BackupAgent.this.getClass().getName() + ") threw", ex);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
@@ -122,7 +125,16 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
ParcelFileDescriptor newState) throws RemoteException {
|
||||
// !!! TODO - real implementation; for now just invoke the callbacks directly
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package android.app;
|
||||
|
||||
import android.backup.BackupDataInput;
|
||||
import android.backup.BackupDataOutput;
|
||||
import android.backup.FileBackupHelper;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
@@ -52,6 +53,6 @@ public class FullBackupAgent extends BackupAgent {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState) {
|
||||
public void onRestore(BackupDataInput data, ParcelFileDescriptor newState) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,11 @@ import java.io.IOException;
|
||||
/** @hide */
|
||||
public class BackupDataOutput {
|
||||
int mBackupWriter;
|
||||
private Context mContext;
|
||||
|
||||
public static final int OP_UPDATE = 1;
|
||||
public static final int OP_DELETE = 2;
|
||||
|
||||
public BackupDataOutput(Context context, FileDescriptor fd) {
|
||||
mContext = context;
|
||||
public BackupDataOutput(FileDescriptor fd) {
|
||||
if (fd == null) throw new NullPointerException();
|
||||
mBackupWriter = ctor(fd);
|
||||
if (mBackupWriter == 0) {
|
||||
|
||||
@@ -16,11 +16,15 @@
|
||||
|
||||
package android.backup;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
||||
/** @hide */
|
||||
public class RestoreHelperDispatcher {
|
||||
private static final String TAG = "RestoreHelperDispatcher";
|
||||
|
||||
HashMap<String,RestoreHelper> mHelpers = new HashMap<String,RestoreHelper>();
|
||||
|
||||
public void addHelper(String keyPrefix, RestoreHelper helper) {
|
||||
@@ -28,8 +32,11 @@ public class RestoreHelperDispatcher {
|
||||
}
|
||||
|
||||
public void dispatch(BackupDataInput input) throws IOException {
|
||||
boolean alreadyComplained = false;
|
||||
|
||||
BackupDataInputStream stream = new BackupDataInputStream(input);
|
||||
while (input.readNextHeader()) {
|
||||
|
||||
String rawKey = input.getKey();
|
||||
int pos = rawKey.indexOf(':');
|
||||
if (pos > 0) {
|
||||
@@ -39,6 +46,16 @@ public class RestoreHelperDispatcher {
|
||||
stream.dataSize = input.getDataSize();
|
||||
stream.key = rawKey.substring(pos+1);
|
||||
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.
|
||||
|
||||
@@ -160,7 +160,7 @@ public class LocalTransport extends IBackupTransport.Stub {
|
||||
File[] blobs = packageDir.listFiles();
|
||||
int err = 0;
|
||||
if (blobs != null && blobs.length > 0) {
|
||||
BackupDataOutput out = new BackupDataOutput(mContext, outFd.getFileDescriptor());
|
||||
BackupDataOutput out = new BackupDataOutput(outFd.getFileDescriptor());
|
||||
try {
|
||||
for (File f : blobs) {
|
||||
FileInputStream in = new FileInputStream(f);
|
||||
|
||||
@@ -144,8 +144,7 @@ public class BackupTestActivity extends ListActivity
|
||||
FileBackupHelper h = new FileBackupHelper(BackupTestActivity.this,
|
||||
"FileBackupHelper");
|
||||
FileOutputStream dataFile = openFileOutput("backup_test", MODE_WORLD_READABLE);
|
||||
BackupDataOutput data = new BackupDataOutput(BackupTestActivity.this,
|
||||
dataFile.getFD());
|
||||
BackupDataOutput data = new BackupDataOutput(dataFile.getFD());
|
||||
h.performBackup(null, data, state, new String[] { "a", "empty" });
|
||||
dataFile.close();
|
||||
state.close();
|
||||
|
||||
@@ -17,28 +17,45 @@
|
||||
package com.android.backuptest;
|
||||
|
||||
import android.app.BackupAgent;
|
||||
import android.backup.BackupDataInput;
|
||||
import android.backup.BackupDataOutput;
|
||||
import android.backup.FileBackupHelper;
|
||||
import android.backup.FileRestoreHelper;
|
||||
import android.backup.RestoreHelperDispatcher;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class BackupTestAgent extends BackupAgent
|
||||
{
|
||||
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
|
||||
public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
|
||||
ParcelFileDescriptor newState) {
|
||||
Log.d(TAG, "onBackup");
|
||||
FileBackupHelper helper = new FileBackupHelper(this);
|
||||
helper.performBackup(oldState, data, newState, new String[] {
|
||||
BackupTestActivity.FILE_NAME
|
||||
});
|
||||
|
||||
(new FileBackupHelper(this, DATA_FILES)).performBackup(oldState, data, newState, FILES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRestore(ParcelFileDescriptor data, ParcelFileDescriptor newState) {
|
||||
public void onRestore(BackupDataInput data, ParcelFileDescriptor newState)
|
||||
throws IOException {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user