Merge "Pass excluded keys to the backup agent in onRestore"

This commit is contained in:
Ruslan Tkhakokhov
2019-12-11 16:23:34 +00:00
committed by Android (Google) Code Review
3 changed files with 61 additions and 5 deletions

View File

@@ -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

View File

@@ -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);

View File

@@ -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,