diff --git a/app/src/main/java/com/stevesoltys/backup/service/backup/BackupJobService.java b/app/src/main/java/com/stevesoltys/backup/service/backup/BackupJobService.java index 3d73f9be..cd0d2d78 100644 --- a/app/src/main/java/com/stevesoltys/backup/service/backup/BackupJobService.java +++ b/app/src/main/java/com/stevesoltys/backup/service/backup/BackupJobService.java @@ -9,12 +9,10 @@ import android.os.RemoteException; import android.util.Log; import com.stevesoltys.backup.service.PackageService; -import com.stevesoltys.backup.transport.ConfigurableBackupTransport; import com.stevesoltys.backup.transport.ConfigurableBackupTransportService; import static android.app.backup.BackupManager.FLAG_NON_INCREMENTAL_BACKUP; import static android.os.ServiceManager.getService; -import static com.stevesoltys.backup.transport.ConfigurableBackupTransportService.getBackupTransport; public class BackupJobService extends JobService { @@ -34,8 +32,6 @@ public class BackupJobService extends JobService { try { String[] packages = packageService.getEligiblePackages(); // TODO use an observer to know when backups fail - ConfigurableBackupTransport backupTransport = getBackupTransport(getApplication()); - backupTransport.prepareBackup(packages.length); int result = backupManager.requestBackup(packages, null, null, FLAG_NON_INCREMENTAL_BACKUP); if (result == BackupManager.SUCCESS) { Log.i(TAG, "Backup succeeded "); diff --git a/app/src/main/java/com/stevesoltys/backup/service/backup/BackupObserver.java b/app/src/main/java/com/stevesoltys/backup/service/backup/BackupObserver.java index 8bcbfefa..a319b377 100644 --- a/app/src/main/java/com/stevesoltys/backup/service/backup/BackupObserver.java +++ b/app/src/main/java/com/stevesoltys/backup/service/backup/BackupObserver.java @@ -12,6 +12,8 @@ import com.stevesoltys.backup.session.backup.BackupResult; import com.stevesoltys.backup.session.backup.BackupSession; import com.stevesoltys.backup.session.backup.BackupSessionObserver; +import static com.stevesoltys.backup.transport.ConfigurableBackupTransportService.getBackupTransport; + /** * @author Steve Soltys */ @@ -59,6 +61,9 @@ class BackupObserver implements BackupSessionObserver { @Override public void backupSessionCompleted(BackupSession backupSession, BackupResult backupResult) { + + if (backupResult == BackupResult.SUCCESS) getBackupTransport(context).backupFinished(); + context.runOnUiThread(() -> { if (backupResult == BackupResult.SUCCESS) { Toast.makeText(context, R.string.backup_success, Toast.LENGTH_LONG).show(); diff --git a/app/src/main/java/com/stevesoltys/backup/service/backup/BackupService.java b/app/src/main/java/com/stevesoltys/backup/service/backup/BackupService.java index 779bcdd1..132b082f 100644 --- a/app/src/main/java/com/stevesoltys/backup/service/backup/BackupService.java +++ b/app/src/main/java/com/stevesoltys/backup/service/backup/BackupService.java @@ -11,12 +11,9 @@ import com.stevesoltys.backup.activity.PopupWindowUtil; import com.stevesoltys.backup.activity.backup.BackupPopupWindowListener; import com.stevesoltys.backup.service.TransportService; import com.stevesoltys.backup.session.backup.BackupSession; -import com.stevesoltys.backup.transport.ConfigurableBackupTransport; import java.util.Set; -import static com.stevesoltys.backup.transport.ConfigurableBackupTransportService.getBackupTransport; - /** * @author Steve Soltys */ @@ -34,8 +31,6 @@ public class BackupService { PopupWindow popupWindow = PopupWindowUtil.showLoadingPopupWindow(parent); BackupObserver backupObserver = new BackupObserver(parent, popupWindow); - ConfigurableBackupTransport backupTransport = getBackupTransport(parent.getApplication()); - backupTransport.prepareBackup(selectedPackages.size()); BackupSession backupSession = transportService.backup(backupObserver, selectedPackages); View popupWindowButton = popupWindow.getContentView().findViewById(R.id.popup_cancel_button); diff --git a/app/src/main/java/com/stevesoltys/backup/session/backup/BackupMonitor.java b/app/src/main/java/com/stevesoltys/backup/session/backup/BackupMonitor.java new file mode 100644 index 00000000..a8d264f0 --- /dev/null +++ b/app/src/main/java/com/stevesoltys/backup/session/backup/BackupMonitor.java @@ -0,0 +1,20 @@ +package com.stevesoltys.backup.session.backup; + +import android.app.backup.IBackupManagerMonitor; +import android.os.Bundle; +import android.util.Log; + +import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_CATEGORY; +import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_ID; +import static android.app.backup.BackupManagerMonitor.EXTRA_LOG_EVENT_PACKAGE_NAME; + +class BackupMonitor extends IBackupManagerMonitor.Stub { + + @Override + public void onEvent(Bundle bundle) { + Log.d("BackupMonitor", "ID: " + bundle.getInt(EXTRA_LOG_EVENT_ID)); + Log.d("BackupMonitor", "CATEGORY: " + bundle.getInt(EXTRA_LOG_EVENT_CATEGORY, -1)); + Log.d("BackupMonitor", "PACKAGE: " + bundle.getString(EXTRA_LOG_EVENT_PACKAGE_NAME, "?")); + } + +} diff --git a/app/src/main/java/com/stevesoltys/backup/session/backup/BackupSession.java b/app/src/main/java/com/stevesoltys/backup/session/backup/BackupSession.java index dfd95173..96cd2953 100644 --- a/app/src/main/java/com/stevesoltys/backup/session/backup/BackupSession.java +++ b/app/src/main/java/com/stevesoltys/backup/session/backup/BackupSession.java @@ -30,7 +30,7 @@ public class BackupSession extends IBackupObserver.Stub { public void start() throws RemoteException { String [] selectedPackageArray = packages.toArray(new String[0]); - backupManager.requestBackup(selectedPackageArray, this, null, FLAG_NON_INCREMENTAL_BACKUP); + backupManager.requestBackup(selectedPackageArray, this, new BackupMonitor(), FLAG_NON_INCREMENTAL_BACKUP); } public void stop(BackupResult result) throws RemoteException { diff --git a/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransport.java b/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransport.java index 811fb97c..b709bb13 100644 --- a/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransport.java +++ b/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransport.java @@ -36,10 +36,6 @@ public class ConfigurableBackupTransport extends BackupTransport { restoreComponent = new ContentProviderRestoreComponent(context); } - public void prepareBackup(int numberOfPackages) { - backupComponent.prepareBackup(numberOfPackages); - } - public void prepareRestore(String password, Uri fileUri) { restoreComponent.prepareRestore(password, fileUri); } @@ -63,20 +59,7 @@ public class ConfigurableBackupTransport extends BackupTransport { @Override public boolean isAppEligibleForBackup(PackageInfo targetPackage, boolean isFullBackup) { - // TODO re-include key-value (incremental) - // affected apps: - // * com.android.documentsui - // * android - // * com.android.nfc - // * com.android.calendar - // * com.android.providers.settings - // * com.android.cellbroadcastreceiver - // * com.android.calllogbackup - // * com.android.providers.blockednumber - // * com.android.providers.userdictionary - if (isFullBackup) return true; - Log.i(TAG, "Excluding key-value backup of " + targetPackage.packageName); - return false; + return true; } @Override @@ -99,15 +82,17 @@ public class ConfigurableBackupTransport extends BackupTransport { return backupComponent.currentDestinationString(); } + /* Methods related to Backup */ + @Override public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor inFd, int flags) { - // TODO handle flags - return performBackup(packageInfo, inFd); + return backupComponent.performIncrementalBackup(packageInfo, inFd, flags); } @Override public int performBackup(PackageInfo targetPackage, ParcelFileDescriptor fileDescriptor) { - return backupComponent.performIncrementalBackup(targetPackage, fileDescriptor); + Log.w(TAG, "Warning: Legacy performBackup() method called."); + return performBackup(targetPackage, fileDescriptor, 0); } @Override @@ -156,6 +141,12 @@ public class ConfigurableBackupTransport extends BackupTransport { return backupComponent.clearBackupData(packageInfo); } + public void backupFinished() { + backupComponent.backupFinished(); + } + + /* Methods related to Restore */ + @Override public long getCurrentRestoreSet() { return restoreComponent.getCurrentRestoreSet(); diff --git a/app/src/main/java/com/stevesoltys/backup/transport/component/BackupComponent.java b/app/src/main/java/com/stevesoltys/backup/transport/component/BackupComponent.java index f3c7cd42..92715d61 100644 --- a/app/src/main/java/com/stevesoltys/backup/transport/component/BackupComponent.java +++ b/app/src/main/java/com/stevesoltys/backup/transport/component/BackupComponent.java @@ -8,8 +8,6 @@ import android.os.ParcelFileDescriptor; */ public interface BackupComponent { - void prepareBackup(int numberOfPackages); - String currentDestinationString(); String dataManagementLabel(); @@ -20,7 +18,7 @@ public interface BackupComponent { int finishBackup(); - int performIncrementalBackup(PackageInfo targetPackage, ParcelFileDescriptor data); + int performIncrementalBackup(PackageInfo targetPackage, ParcelFileDescriptor data, int flags); int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor fileDescriptor); @@ -35,4 +33,6 @@ public interface BackupComponent { long requestBackupTime(); long requestFullBackupTime(); + + void backupFinished(); } diff --git a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupComponent.java b/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupComponent.java index 2f6a677c..bab06921 100644 --- a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupComponent.java +++ b/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupComponent.java @@ -31,7 +31,10 @@ import javax.crypto.SecretKey; import libcore.io.IoUtils; +import static android.app.backup.BackupTransport.FLAG_INCREMENTAL; +import static android.app.backup.BackupTransport.FLAG_NON_INCREMENTAL; import static android.app.backup.BackupTransport.TRANSPORT_ERROR; +import static android.app.backup.BackupTransport.TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED; import static android.app.backup.BackupTransport.TRANSPORT_OK; import static android.app.backup.BackupTransport.TRANSPORT_PACKAGE_REJECTED; import static android.app.backup.BackupTransport.TRANSPORT_QUOTA_EXCEEDED; @@ -49,7 +52,7 @@ import static java.util.Objects.requireNonNull; */ public class ContentProviderBackupComponent implements BackupComponent { - private static final String TAG = ContentProviderBackupComponent.class.getName(); + private static final String TAG = ContentProviderBackupComponent.class.getSimpleName(); private static final String DOCUMENT_SUFFIX = "yyyy-MM-dd_HH_mm_ss"; @@ -61,8 +64,6 @@ public class ContentProviderBackupComponent implements BackupComponent { private final Context context; - private int numberOfPackages = 0; - private ContentProviderBackupState backupState; public ContentProviderBackupComponent(Context context) { @@ -93,11 +94,6 @@ public class ContentProviderBackupComponent implements BackupComponent { return TRANSPORT_OK; } - @Override - public void prepareBackup(int numberOfPackages) { - this.numberOfPackages = numberOfPackages; - } - @Override public String currentDestinationString() { return DESTINATION_DESCRIPTION; @@ -133,7 +129,6 @@ public class ContentProviderBackupComponent implements BackupComponent { try { initializeBackupState(); - backupState.setPackageIndex(backupState.getPackageIndex() + 1); backupState.setPackageName(targetPackage.packageName); backupState.setInputFileDescriptor(fileDescriptor); @@ -156,12 +151,24 @@ public class ContentProviderBackupComponent implements BackupComponent { } @Override - public int performIncrementalBackup(PackageInfo packageInfo, ParcelFileDescriptor data) { + public int performIncrementalBackup(PackageInfo packageInfo, ParcelFileDescriptor data, int flags) { + boolean isIncremental = (flags & FLAG_INCREMENTAL) != 0; + if (isIncremental) { + Log.w(TAG, "Can not handle incremental backup. Requesting non-incremental for " + packageInfo.packageName); + return TRANSPORT_NON_INCREMENTAL_BACKUP_REQUIRED; + } + + boolean isNonIncremental = (flags & FLAG_NON_INCREMENTAL) != 0; + if (isNonIncremental) { + Log.i(TAG, "Performing non-incremental backup for " + packageInfo.packageName); + } else { + Log.i(TAG, "Performing backup for " + packageInfo.packageName); + } + BackupDataInput backupDataInput = new BackupDataInput(data.getFileDescriptor()); try { initializeBackupState(); - backupState.setPackageIndex(backupState.getPackageIndex() + 1); backupState.setPackageName(packageInfo.packageName); return transferIncrementalBackupData(backupDataInput); @@ -261,6 +268,11 @@ public class ContentProviderBackupComponent implements BackupComponent { return TRANSPORT_OK; } + @Override + public void backupFinished() { + clearBackupState(true); + } + private void initializeBackupState() throws Exception { if (backupState == null) { backupState = new ContentProviderBackupState(); @@ -333,8 +345,8 @@ public class ContentProviderBackupComponent implements BackupComponent { outputStream.closeEntry(); } - - if (backupState.getPackageIndex() == numberOfPackages || closeFile) { + if (closeFile) { + Log.d(TAG, "Closing backup file..."); if (outputStream != null) { outputStream.finish(); outputStream.close(); diff --git a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupState.java b/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupState.java index 799874b4..0adc8d17 100644 --- a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupState.java +++ b/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupState.java @@ -2,12 +2,13 @@ package com.stevesoltys.backup.transport.component.provider; import android.os.ParcelFileDescriptor; -import javax.crypto.Cipher; -import javax.crypto.SecretKey; import java.io.InputStream; import java.security.SecureRandom; import java.util.zip.ZipOutputStream; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; + /** * @author Steve Soltys */ @@ -29,13 +30,11 @@ class ContentProviderBackupState { private String packageName; - private int packageIndex; - private byte[] salt; private SecretKey secretKey; - public ContentProviderBackupState() { + ContentProviderBackupState() { salt = new byte[16]; SECURE_RANDOM.nextBytes(salt); } @@ -88,14 +87,6 @@ class ContentProviderBackupState { this.outputStream = outputStream; } - int getPackageIndex() { - return packageIndex; - } - - void setPackageIndex(int packageIndex) { - this.packageIndex = packageIndex; - } - String getPackageName() { return packageName; } @@ -108,11 +99,11 @@ class ContentProviderBackupState { return salt; } - public SecretKey getSecretKey() { + SecretKey getSecretKey() { return secretKey; } - public void setSecretKey(SecretKey secretKey) { + void setSecretKey(SecretKey secretKey) { this.secretKey = secretKey; } }