Add support for incremental and full backup directory configuration

This commit is contained in:
Steve Soltys 2017-10-09 20:40:25 -04:00
parent 677b950dea
commit f41d211ddc
5 changed files with 50 additions and 30 deletions

View file

@ -38,8 +38,6 @@ import java.util.Set;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
import static com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfiguration.FULL_BACKUP_DIRECTORY;
/** /**
* @author Steve Soltys * @author Steve Soltys
*/ */
@ -78,7 +76,7 @@ class RestoreBackupActivityController {
while ((zipEntry = inputStream.getNextEntry()) != null) { while ((zipEntry = inputStream.getNextEntry()) != null) {
String zipEntryPath = zipEntry.getName(); String zipEntryPath = zipEntry.getName();
if (zipEntryPath.startsWith(FULL_BACKUP_DIRECTORY)) { if (zipEntryPath.startsWith(ContentProviderBackupConfigurationBuilder.DEFAULT_FULL_BACKUP_DIRECTORY)) {
String fileName = new File(zipEntryPath).getName(); String fileName = new File(zipEntryPath).getName();
results.add(fileName); results.add(fileName);
} }

View file

@ -10,10 +10,6 @@ import java.util.Set;
*/ */
public class ContentProviderBackupConfiguration { public class ContentProviderBackupConfiguration {
public static final String FULL_BACKUP_DIRECTORY = "full/";
public static final String INCREMENTAL_BACKUP_DIRECTORY = "incr/";
private final Context context; private final Context context;
private final Uri uri; private final Uri uri;
@ -22,11 +18,18 @@ public class ContentProviderBackupConfiguration {
private final Set<String> packages; private final Set<String> packages;
ContentProviderBackupConfiguration(Context context, Uri uri, Set<String> packages, long backupSizeQuota) { private final String fullBackupDirectory;
private final String incrementalBackupDirectory;
ContentProviderBackupConfiguration(Context context, Uri uri, Set<String> packages, long backupSizeQuota,
String fullBackupDirectory, String incrementalBackupDirectory) {
this.context = context; this.context = context;
this.uri = uri; this.uri = uri;
this.packages = packages; this.packages = packages;
this.backupSizeQuota = backupSizeQuota; this.backupSizeQuota = backupSizeQuota;
this.fullBackupDirectory = fullBackupDirectory;
this.incrementalBackupDirectory = incrementalBackupDirectory;
} }
public Context getContext() { public Context getContext() {
@ -45,4 +48,11 @@ public class ContentProviderBackupConfiguration {
return packages.size(); return packages.size();
} }
public String getFullBackupDirectory() {
return fullBackupDirectory;
}
public String getIncrementalBackupDirectory() {
return incrementalBackupDirectory;
}
} }

View file

@ -2,6 +2,7 @@ package com.stevesoltys.backup.transport.component.provider;
import android.content.Context; import android.content.Context;
import android.net.Uri; import android.net.Uri;
import com.android.internal.util.Preconditions;
import java.util.Set; import java.util.Set;
@ -10,6 +11,10 @@ import java.util.Set;
*/ */
public class ContentProviderBackupConfigurationBuilder { public class ContentProviderBackupConfigurationBuilder {
public static final String DEFAULT_FULL_BACKUP_DIRECTORY = "full/";
public static final String DEFAULT_INCREMENTAL_BACKUP_DIRECTORY = "incr/";
private Context context; private Context context;
private Uri outputUri; private Uri outputUri;
@ -18,19 +23,19 @@ public class ContentProviderBackupConfigurationBuilder {
private long backupSizeQuota = Long.MAX_VALUE; private long backupSizeQuota = Long.MAX_VALUE;
private String incrementalBackupDirectory = DEFAULT_INCREMENTAL_BACKUP_DIRECTORY;
private String fullBackupDirectory = DEFAULT_FULL_BACKUP_DIRECTORY;
public ContentProviderBackupConfiguration build() { public ContentProviderBackupConfiguration build() {
Preconditions.checkState(context != null, "Context must be set.");
Preconditions.checkState(outputUri != null, "Output URI must be set.");
Preconditions.checkState(packages != null, "Package list must be set.");
Preconditions.checkState(incrementalBackupDirectory != null, "Incremental backup directory must be set.");
Preconditions.checkState(fullBackupDirectory != null, "Full backup directory must be set.");
if(context == null) { return new ContentProviderBackupConfiguration(context, outputUri, packages, backupSizeQuota,
throw new IllegalArgumentException("Context must be set."); fullBackupDirectory, incrementalBackupDirectory);
} else if (outputUri == null) {
throw new IllegalArgumentException("Output URI must be set.");
} else if(packages == null) {
throw new IllegalArgumentException("Package list must be set.");
}
return new ContentProviderBackupConfiguration(context, outputUri, packages, backupSizeQuota);
} }
public ContentProviderBackupConfigurationBuilder setContext(Context context) { public ContentProviderBackupConfigurationBuilder setContext(Context context) {
@ -52,4 +57,14 @@ public class ContentProviderBackupConfigurationBuilder {
this.backupSizeQuota = backupSizeQuota; this.backupSizeQuota = backupSizeQuota;
return this; return this;
} }
public ContentProviderBackupConfigurationBuilder setIncrementalBackupDirectory(String incrementalBackupDirectory) {
this.incrementalBackupDirectory = incrementalBackupDirectory;
return this;
}
public ContentProviderBackupConfigurationBuilder setFullBackupDirectory(String fullBackupDirectory) {
this.fullBackupDirectory = fullBackupDirectory;
return this;
}
} }

View file

@ -18,8 +18,6 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream; import java.util.zip.ZipOutputStream;
import static android.app.backup.BackupTransport.*; import static android.app.backup.BackupTransport.*;
import static com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfiguration.FULL_BACKUP_DIRECTORY;
import static com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfiguration.INCREMENTAL_BACKUP_DIRECTORY;
/** /**
* TODO: Clean this up. Much of it was taken from the LocalTransport implementation. * TODO: Clean this up. Much of it was taken from the LocalTransport implementation.
@ -121,7 +119,7 @@ public class ContentProviderBackupComponent implements BackupComponent {
int dataSize = backupDataInput.getDataSize(); int dataSize = backupDataInput.getDataSize();
if (dataSize >= 0) { if (dataSize >= 0) {
ZipEntry zipEntry = new ZipEntry(INCREMENTAL_BACKUP_DIRECTORY + backupState.getPackageName() + ZipEntry zipEntry = new ZipEntry(configuration.getIncrementalBackupDirectory() + backupState.getPackageName() +
"/" + chunkFileName); "/" + chunkFileName);
outputStream.putNextEntry(zipEntry); outputStream.putNextEntry(zipEntry);
@ -167,7 +165,7 @@ public class ContentProviderBackupComponent implements BackupComponent {
backupState.setBuffer(new byte[INITIAL_BUFFER_SIZE]); backupState.setBuffer(new byte[INITIAL_BUFFER_SIZE]);
backupState.setBytesTransferred(0); backupState.setBytesTransferred(0);
ZipEntry zipEntry = new ZipEntry(FULL_BACKUP_DIRECTORY + backupState.getPackageName()); ZipEntry zipEntry = new ZipEntry(configuration.getFullBackupDirectory() + backupState.getPackageName());
backupState.getOutputStream().putNextEntry(zipEntry); backupState.getOutputStream().putNextEntry(zipEntry);
} catch (Exception ex) { } catch (Exception ex) {

View file

@ -24,8 +24,6 @@ import java.util.zip.ZipInputStream;
import static android.app.backup.BackupTransport.*; import static android.app.backup.BackupTransport.*;
import static android.app.backup.RestoreDescription.TYPE_FULL_STREAM; import static android.app.backup.RestoreDescription.TYPE_FULL_STREAM;
import static android.app.backup.RestoreDescription.TYPE_KEY_VALUE; import static android.app.backup.RestoreDescription.TYPE_KEY_VALUE;
import static com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfiguration.FULL_BACKUP_DIRECTORY;
import static com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfiguration.INCREMENTAL_BACKUP_DIRECTORY;
/** /**
* @author Steve Soltys * @author Steve Soltys
@ -66,11 +64,11 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
String name = packages[packageIndex].packageName; String name = packages[packageIndex].packageName;
try { try {
if (containsPackageFile(INCREMENTAL_BACKUP_DIRECTORY + name)) { if (containsPackageFile(configuration.getIncrementalBackupDirectory() + name)) {
restoreState.setRestoreType(TYPE_KEY_VALUE); restoreState.setRestoreType(TYPE_KEY_VALUE);
return new RestoreDescription(name, restoreState.getRestoreType()); return new RestoreDescription(name, restoreState.getRestoreType());
} else if (containsPackageFile(FULL_BACKUP_DIRECTORY + name)) { } else if (containsPackageFile(configuration.getFullBackupDirectory() + name)) {
restoreState.setRestoreType(TYPE_FULL_STREAM); restoreState.setRestoreType(TYPE_FULL_STREAM);
return new RestoreDescription(name, restoreState.getRestoreType()); return new RestoreDescription(name, restoreState.getRestoreType());
} }
@ -139,7 +137,8 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
ParcelFileDescriptor inputFileDescriptor = buildInputFileDescriptor(); ParcelFileDescriptor inputFileDescriptor = buildInputFileDescriptor();
ZipInputStream inputStream = buildInputStream(inputFileDescriptor); ZipInputStream inputStream = buildInputStream(inputFileDescriptor);
Optional<ZipEntry> zipEntryOptional = seekToEntry(inputStream, INCREMENTAL_BACKUP_DIRECTORY + packageName); Optional<ZipEntry> zipEntryOptional = seekToEntry(inputStream,
configuration.getIncrementalBackupDirectory() + packageName);
while (zipEntryOptional.isPresent()) { while (zipEntryOptional.isPresent()) {
String fileName = new File(zipEntryOptional.get().getName()).getName(); String fileName = new File(zipEntryOptional.get().getName()).getName();
String blobKey = new String(Base64.decode(fileName, Base64.DEFAULT)); String blobKey = new String(Base64.decode(fileName, Base64.DEFAULT));
@ -149,7 +148,7 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
backupDataOutput.writeEntityData(backupData, backupData.length); backupDataOutput.writeEntityData(backupData, backupData.length);
inputStream.closeEntry(); inputStream.closeEntry();
zipEntryOptional = seekToEntry(inputStream, INCREMENTAL_BACKUP_DIRECTORY + packageName); zipEntryOptional = seekToEntry(inputStream, configuration.getIncrementalBackupDirectory() + packageName);
} }
IoUtils.closeQuietly(inputFileDescriptor.getFileDescriptor()); IoUtils.closeQuietly(inputFileDescriptor.getFileDescriptor());
@ -174,7 +173,7 @@ public class ContentProviderRestoreComponent implements RestoreComponent {
inputStream = buildInputStream(inputFileDescriptor); inputStream = buildInputStream(inputFileDescriptor);
restoreState.setInputStream(inputStream); restoreState.setInputStream(inputStream);
if (!seekToEntry(inputStream, FULL_BACKUP_DIRECTORY + name).isPresent()) { if (!seekToEntry(inputStream, configuration.getFullBackupDirectory() + name).isPresent()) {
IoUtils.closeQuietly(inputFileDescriptor.getFileDescriptor()); IoUtils.closeQuietly(inputFileDescriptor.getFileDescriptor());
return TRANSPORT_PACKAGE_REJECTED; return TRANSPORT_PACKAGE_REJECTED;
} }