Add support for incremental and full backup directory configuration
This commit is contained in:
parent
677b950dea
commit
f41d211ddc
5 changed files with 50 additions and 30 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue