Pass excluded keys to the backup agent in onRestore
Pass the list of the keys excluded from KV restore to the backup agent to make it aware of what data has been removed (in case it has any application-level consequences) as well as the data that should be removed by the agent itself. Bug: 145126096 Test: atest CtsBackupTestCases Change-Id: I34415b149b379fb5bb67b0fbcd70ec9b9858acfe
This commit is contained in:
@@ -84,6 +84,19 @@ oneway interface IBackupAgent {
|
||||
long appVersionCode, in ParcelFileDescriptor newState,
|
||||
int token, IBackupManager callbackBinder);
|
||||
|
||||
/**
|
||||
* Restore an entire data snapshot to the application and pass the list of excluded keys to the
|
||||
* backup agent.
|
||||
*
|
||||
* @param excludedKeys List of keys to be excluded from the restore. It will be passed to the
|
||||
* backup agent to make it aware of what data has been removed (in case it has any
|
||||
* application-level implications) as well as the data that should be removed by the
|
||||
* agent itself.
|
||||
*/
|
||||
void doRestoreWithExcludedKeys(in ParcelFileDescriptor data,
|
||||
long appVersionCode, in ParcelFileDescriptor newState,
|
||||
int token, IBackupManager callbackBinder, in List<String> excludedKeys);
|
||||
|
||||
/**
|
||||
* Perform a "full" backup to the given file descriptor. The output file is presumed
|
||||
* to be a socket or other non-seekable, write-only data sink. When this method is
|
||||
|
||||
@@ -45,7 +45,10 @@ import org.xmlpull.v1.XmlPullParserException;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
@@ -326,6 +329,28 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
onRestore(data, (int) appVersionCode, newState);
|
||||
}
|
||||
|
||||
/**
|
||||
* New version of {@link #onRestore(BackupDataInput, long, android.os.ParcelFileDescriptor)}
|
||||
* that has a list of keys to be excluded from the restore. Key/value pairs for which the key
|
||||
* is present in {@code excludedKeys} have already been excluded from the restore data by the
|
||||
* system. The list is passed to the agent to make it aware of what data has been removed (in
|
||||
* case it has any application-level consequences) as well as the data that should be removed
|
||||
* by the agent itself.
|
||||
*
|
||||
* The default implementation calls {@link #onRestore(BackupDataInput, long,
|
||||
* android.os.ParcelFileDescriptor)}.
|
||||
*
|
||||
* @param excludedKeys A list of keys to be excluded from restore.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void onRestore(BackupDataInput data, long appVersionCode,
|
||||
ParcelFileDescriptor newState,
|
||||
Set<String> excludedKeys)
|
||||
throws IOException {
|
||||
onRestore(data, appVersionCode, newState);
|
||||
}
|
||||
|
||||
/**
|
||||
* The application is having its entire file system contents backed up. {@code data}
|
||||
* points to the backup destination, and the app has the opportunity to choose which
|
||||
@@ -1016,8 +1041,22 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
|
||||
@Override
|
||||
public void doRestore(ParcelFileDescriptor data, long appVersionCode,
|
||||
ParcelFileDescriptor newState,
|
||||
int token, IBackupManager callbackBinder) throws RemoteException {
|
||||
ParcelFileDescriptor newState, int token, IBackupManager callbackBinder)
|
||||
throws RemoteException {
|
||||
doRestoreInternal(data, appVersionCode, newState, token, callbackBinder,
|
||||
/* excludedKeys */ null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doRestoreWithExcludedKeys(ParcelFileDescriptor data, long appVersionCode,
|
||||
ParcelFileDescriptor newState, int token, IBackupManager callbackBinder,
|
||||
List<String> excludedKeys) throws RemoteException {
|
||||
doRestoreInternal(data, appVersionCode, newState, token, callbackBinder, excludedKeys);
|
||||
}
|
||||
|
||||
private void doRestoreInternal(ParcelFileDescriptor data, long appVersionCode,
|
||||
ParcelFileDescriptor newState, int token, IBackupManager callbackBinder,
|
||||
List<String> excludedKeys) throws RemoteException {
|
||||
// Ensure that we're running with the app's normal permission level
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
|
||||
@@ -1029,7 +1068,9 @@ public abstract class BackupAgent extends ContextWrapper {
|
||||
|
||||
BackupDataInput input = new BackupDataInput(data.getFileDescriptor());
|
||||
try {
|
||||
BackupAgent.this.onRestore(input, appVersionCode, newState);
|
||||
BackupAgent.this.onRestore(input, appVersionCode, newState,
|
||||
excludedKeys != null ? new HashSet<>(excludedKeys)
|
||||
: Collections.emptySet());
|
||||
} catch (IOException ex) {
|
||||
Log.d(TAG, "onRestore (" + BackupAgent.this.getClass().getName() + ") threw", ex);
|
||||
throw new RuntimeException(ex);
|
||||
|
||||
@@ -766,8 +766,10 @@ public class PerformUnifiedRestoreTask implements BackupRestoreTask {
|
||||
backupManagerService.prepareOperationTimeout(
|
||||
mEphemeralOpToken, restoreAgentTimeoutMillis, this, OP_TYPE_RESTORE_WAIT);
|
||||
startedAgentRestore = true;
|
||||
mAgent.doRestore(mBackupData, appVersionCode, mNewState,
|
||||
mEphemeralOpToken, backupManagerService.getBackupManagerBinder());
|
||||
mAgent.doRestoreWithExcludedKeys(mBackupData, appVersionCode, mNewState,
|
||||
mEphemeralOpToken, backupManagerService.getBackupManagerBinder(),
|
||||
mExcludedKeys.containsKey(packageName)
|
||||
? new ArrayList<>(mExcludedKeys.get(packageName)) : null);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "Unable to call app for restore: " + packageName, e);
|
||||
EventLog.writeEvent(EventLogTags.RESTORE_AGENT_FAILURE,
|
||||
|
||||
Reference in New Issue
Block a user