From 92ce6c1a5c606a920bee09e6fc1a8f234f42fe3a Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Tue, 11 Jun 2019 20:53:44 -0300 Subject: [PATCH] Refactor transport components to eliminate need to initialize and reset transport --- .../activity/MainActivityController.java | 62 ++------------ .../activity/backup/CreateBackupActivity.java | 6 +- .../CreateBackupActivityController.java | 17 ++-- .../RestoreBackupActivityController.java | 15 +++- .../backup/service/TransportService.java | 21 +---- .../service/backup/BackupJobService.java | 25 +----- .../backup/service/backup/BackupObserver.java | 18 +--- .../backup/service/backup/BackupService.java | 30 ++----- .../service/restore/RestoreObserver.java | 11 +-- .../service/restore/RestoreService.java | 23 ++--- .../ConfigurableBackupTransport.java | 41 +++++---- .../ConfigurableBackupTransportService.java | 7 +- .../transport/component/BackupComponent.java | 2 + .../transport/component/RestoreComponent.java | 3 + .../ContentProviderBackupComponent.java | 85 +++++++++++++++---- .../ContentProviderBackupConfiguration.java | 66 -------------- ...entProviderBackupConfigurationBuilder.java | 77 ----------------- .../ContentProviderRestoreComponent.java | 43 +++++++--- .../component/stub/StubBackupComponent.java | 76 ----------------- .../component/stub/StubRestoreComponent.java | 53 ------------ 20 files changed, 175 insertions(+), 506 deletions(-) delete mode 100644 app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupConfiguration.java delete mode 100644 app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupConfigurationBuilder.java delete mode 100644 app/src/main/java/com/stevesoltys/backup/transport/component/stub/StubBackupComponent.java delete mode 100644 app/src/main/java/com/stevesoltys/backup/transport/component/stub/StubRestoreComponent.java diff --git a/app/src/main/java/com/stevesoltys/backup/activity/MainActivityController.java b/app/src/main/java/com/stevesoltys/backup/activity/MainActivityController.java index f569d376..d9e13fff 100644 --- a/app/src/main/java/com/stevesoltys/backup/activity/MainActivityController.java +++ b/app/src/main/java/com/stevesoltys/backup/activity/MainActivityController.java @@ -8,7 +8,6 @@ import android.content.ComponentName; import android.content.ContentResolver; import android.content.Intent; import android.net.Uri; -import android.util.Log; import android.widget.Toast; import com.stevesoltys.backup.activity.backup.CreateBackupActivity; @@ -16,11 +15,6 @@ import com.stevesoltys.backup.activity.restore.RestoreBackupActivity; import com.stevesoltys.backup.service.backup.BackupJobService; import com.stevesoltys.backup.transport.ConfigurableBackupTransportService; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; - import static android.app.job.JobInfo.NETWORK_TYPE_UNMETERED; import static android.content.Intent.ACTION_OPEN_DOCUMENT; import static android.content.Intent.ACTION_OPEN_DOCUMENT_TREE; @@ -28,9 +22,6 @@ import static android.content.Intent.CATEGORY_OPENABLE; import static android.content.Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION; import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION; import static android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION; -import static android.provider.DocumentsContract.buildDocumentUriUsingTree; -import static android.provider.DocumentsContract.createDocument; -import static android.provider.DocumentsContract.getTreeDocumentId; import static com.stevesoltys.backup.Backup.JOB_ID_BACKGROUND_BACKUP; import static com.stevesoltys.backup.activity.MainActivity.OPEN_DOCUMENT_TREE_BACKUP_REQUEST_CODE; import static com.stevesoltys.backup.activity.MainActivity.OPEN_DOCUMENT_TREE_REQUEST_CODE; @@ -47,27 +38,16 @@ import static java.util.concurrent.TimeUnit.DAYS; */ public class MainActivityController { - private static final String TAG = MainActivityController.class.getName(); - - private static final String DOCUMENT_MIME_TYPE = "application/octet-stream"; - private static final String DOCUMENT_SUFFIX = "yyyy-MM-dd_HH_mm_ss"; + public static final String DOCUMENT_MIME_TYPE = "application/octet-stream"; void onBackupButtonClicked(Activity parent) { Uri folderUri = getBackupFolderUri(parent); if (folderUri == null) { showChooseFolderActivity(parent, true); } else { - try { - // ensure that backup service is started - parent.startService(new Intent(parent, ConfigurableBackupTransportService.class)); - - Uri fileUri = createBackupFile(parent.getContentResolver(), folderUri); - showCreateBackupActivity(parent, fileUri); - - } catch (IOException e) { - Log.w(TAG, "Error creating backup file: ", e); - showChooseFolderActivity(parent, true); - } + // ensure that backup service is started + parent.startService(new Intent(parent, ConfigurableBackupTransportService.class)); + showCreateBackupActivity(parent); } } @@ -148,22 +128,11 @@ public class MainActivityController { if (!continueToBackup) return; - try { - // create a new backup file in folder - Uri fileUri = createBackupFile(contentResolver, folderUri); - - showCreateBackupActivity(parent, fileUri); - - } catch (IOException e) { - Log.e(TAG, "Error creating backup file: ", e); - // TODO show better error message once more infrastructure is in place - Toast.makeText(parent, "Error creating backup file", Toast.LENGTH_SHORT).show(); - } + showCreateBackupActivity(parent); } - private void showCreateBackupActivity(Activity parent, Uri fileUri) { + private void showCreateBackupActivity(Activity parent) { Intent intent = new Intent(parent, CreateBackupActivity.class); - intent.setData(fileUri); parent.startActivity(intent); } @@ -178,23 +147,4 @@ public class MainActivityController { parent.startActivity(intent); } - public static Uri createBackupFile(ContentResolver contentResolver, Uri folderUri) throws IOException { - Uri documentUri = buildDocumentUriUsingTree(folderUri, getTreeDocumentId(folderUri)); - try { - Uri fileUri = createDocument(contentResolver, documentUri, DOCUMENT_MIME_TYPE, getBackupFileName()); - if (fileUri == null) throw new IOException(); - return fileUri; - - } catch (SecurityException e) { - // happens when folder was deleted and thus Uri permission don't exist anymore - throw new IOException(e); - } - } - - private static String getBackupFileName() { - SimpleDateFormat dateFormat = new SimpleDateFormat(DOCUMENT_SUFFIX, Locale.US); - String date = dateFormat.format(new Date()); - return "backup-" + date; - } - } diff --git a/app/src/main/java/com/stevesoltys/backup/activity/backup/CreateBackupActivity.java b/app/src/main/java/com/stevesoltys/backup/activity/backup/CreateBackupActivity.java index 7ac6e255..cdfc0549 100644 --- a/app/src/main/java/com/stevesoltys/backup/activity/backup/CreateBackupActivity.java +++ b/app/src/main/java/com/stevesoltys/backup/activity/backup/CreateBackupActivity.java @@ -1,6 +1,5 @@ package com.stevesoltys.backup.activity.backup; -import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.view.Menu; @@ -16,14 +15,12 @@ public class CreateBackupActivity extends PackageListActivity implements View.On private CreateBackupActivityController controller; - private Uri contentUri; - @Override public void onClick(View view) { int viewId = view.getId(); if (viewId == R.id.create_confirm_button) { - controller.onCreateBackupButtonClicked(selectedPackageList, contentUri, this); + controller.onCreateBackupButtonClicked(selectedPackageList, this); } } @@ -36,7 +33,6 @@ public class CreateBackupActivity extends PackageListActivity implements View.On packageListView = findViewById(R.id.create_package_list); selectedPackageList = new HashSet<>(); - contentUri = getIntent().getData(); controller = new CreateBackupActivityController(); AsyncTask.execute(() -> controller.populatePackageList(packageListView, CreateBackupActivity.this)); diff --git a/app/src/main/java/com/stevesoltys/backup/activity/backup/CreateBackupActivityController.java b/app/src/main/java/com/stevesoltys/backup/activity/backup/CreateBackupActivityController.java index 67d2c156..74cbf4bb 100644 --- a/app/src/main/java/com/stevesoltys/backup/activity/backup/CreateBackupActivityController.java +++ b/app/src/main/java/com/stevesoltys/backup/activity/backup/CreateBackupActivityController.java @@ -2,7 +2,6 @@ package com.stevesoltys.backup.activity.backup; import android.app.Activity; import android.app.AlertDialog; -import android.net.Uri; import android.os.RemoteException; import android.text.InputType; import android.util.Log; @@ -75,16 +74,16 @@ class CreateBackupActivityController { }); } - void onCreateBackupButtonClicked(Set selectedPackages, Uri contentUri, Activity parent) { + void onCreateBackupButtonClicked(Set selectedPackages, Activity parent) { String password = SettingsManager.getBackupPassword(parent); if (password == null) { - showEnterPasswordAlert(selectedPackages, contentUri, parent); + showEnterPasswordAlert(selectedPackages, parent); } else { - backupService.backupPackageData(selectedPackages, contentUri, parent, password); + backupService.backupPackageData(selectedPackages, parent); } } - private void showEnterPasswordAlert(Set selectedPackages, Uri contentUri, Activity parent) { + private void showEnterPasswordAlert(Set selectedPackages, Activity parent) { final EditText passwordTextView = new EditText(parent); passwordTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); @@ -97,9 +96,9 @@ class CreateBackupActivityController { if (passwordTextView.getText().length() == 0) { Toast.makeText(parent, "Please enter a password", Toast.LENGTH_SHORT).show(); dialog.cancel(); - showEnterPasswordAlert(selectedPackages, contentUri, parent); + showEnterPasswordAlert(selectedPackages, parent); } else { - showConfirmPasswordAlert(selectedPackages, contentUri, parent, + showConfirmPasswordAlert(selectedPackages, parent, passwordTextView.getText().toString()); } }) @@ -108,7 +107,7 @@ class CreateBackupActivityController { .show(); } - private void showConfirmPasswordAlert(Set selectedPackages, Uri contentUri, Activity parent, + private void showConfirmPasswordAlert(Set selectedPackages, Activity parent, String originalPassword) { final EditText passwordTextView = new EditText(parent); passwordTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); @@ -122,7 +121,7 @@ class CreateBackupActivityController { if (originalPassword.equals(password)) { SettingsManager.setBackupPassword(parent, password); - backupService.backupPackageData(selectedPackages, contentUri, parent, password); + backupService.backupPackageData(selectedPackages, parent); } else { new AlertDialog.Builder(parent) diff --git a/app/src/main/java/com/stevesoltys/backup/activity/restore/RestoreBackupActivityController.java b/app/src/main/java/com/stevesoltys/backup/activity/restore/RestoreBackupActivityController.java index 6370d7e7..ed3ed757 100644 --- a/app/src/main/java/com/stevesoltys/backup/activity/restore/RestoreBackupActivityController.java +++ b/app/src/main/java/com/stevesoltys/backup/activity/restore/RestoreBackupActivityController.java @@ -7,12 +7,15 @@ import android.os.ParcelFileDescriptor; import android.text.InputType; import android.util.Log; import android.view.View; -import android.widget.*; +import android.widget.ArrayAdapter; +import android.widget.EditText; +import android.widget.ListView; +import android.widget.PopupWindow; +import android.widget.TextView; + import com.stevesoltys.backup.R; import com.stevesoltys.backup.activity.PopupWindowUtil; import com.stevesoltys.backup.service.restore.RestoreService; -import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfigurationBuilder; -import libcore.io.IoUtils; import java.io.File; import java.io.FileInputStream; @@ -24,6 +27,10 @@ import java.util.concurrent.atomic.AtomicReference; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import libcore.io.IoUtils; + +import static com.stevesoltys.backup.transport.ConfigurableBackupTransport.DEFAULT_FULL_BACKUP_DIRECTORY; + /** * @author Steve Soltys */ @@ -76,7 +83,7 @@ class RestoreBackupActivityController { while ((zipEntry = inputStream.getNextEntry()) != null) { String zipEntryPath = zipEntry.getName(); - if (zipEntryPath.startsWith(ContentProviderBackupConfigurationBuilder.DEFAULT_FULL_BACKUP_DIRECTORY)) { + if (zipEntryPath.startsWith(DEFAULT_FULL_BACKUP_DIRECTORY)) { String fileName = new File(zipEntryPath).getName(); results.add(fileName); } diff --git a/app/src/main/java/com/stevesoltys/backup/service/TransportService.java b/app/src/main/java/com/stevesoltys/backup/service/TransportService.java index 934005b2..9dcbca4a 100644 --- a/app/src/main/java/com/stevesoltys/backup/service/TransportService.java +++ b/app/src/main/java/com/stevesoltys/backup/service/TransportService.java @@ -3,17 +3,11 @@ package com.stevesoltys.backup.service; import android.app.backup.IBackupManager; import android.os.RemoteException; import android.os.ServiceManager; + import com.stevesoltys.backup.session.backup.BackupSession; import com.stevesoltys.backup.session.backup.BackupSessionObserver; import com.stevesoltys.backup.session.restore.RestoreSession; import com.stevesoltys.backup.session.restore.RestoreSessionObserver; -import com.stevesoltys.backup.transport.ConfigurableBackupTransport; -import com.stevesoltys.backup.transport.ConfigurableBackupTransportService; -import com.stevesoltys.backup.transport.component.BackupComponent; -import com.stevesoltys.backup.transport.component.RestoreComponent; -import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupComponent; -import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfiguration; -import com.stevesoltys.backup.transport.component.provider.ContentProviderRestoreComponent; import java.util.Set; @@ -30,19 +24,6 @@ public class TransportService { backupManager = IBackupManager.Stub.asInterface(ServiceManager.getService("backup")); } - public boolean initializeBackupTransport(ContentProviderBackupConfiguration configuration) { - ConfigurableBackupTransport backupTransport = ConfigurableBackupTransportService.getBackupTransport(); - - if (backupTransport.isActive()) { - return false; - } - - BackupComponent backupComponent = new ContentProviderBackupComponent(configuration); - RestoreComponent restoreComponent = new ContentProviderRestoreComponent(configuration); - backupTransport.initialize(backupComponent, restoreComponent); - return true; - } - public BackupSession backup(BackupSessionObserver observer, Set packages) throws RemoteException { if (!BACKUP_TRANSPORT.equals(backupManager.getCurrentTransport())) { 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 1bcc3998..67260600 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 @@ -5,27 +5,20 @@ import android.app.backup.IBackupManager; import android.app.job.JobParameters; import android.app.job.JobService; import android.content.Intent; -import android.net.Uri; import android.os.RemoteException; import android.util.Log; import com.google.android.collect.Sets; import com.stevesoltys.backup.service.PackageService; -import com.stevesoltys.backup.service.TransportService; +import com.stevesoltys.backup.transport.ConfigurableBackupTransport; import com.stevesoltys.backup.transport.ConfigurableBackupTransportService; -import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfiguration; -import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfigurationBuilder; -import java.io.IOException; -import java.util.HashSet; import java.util.LinkedList; import java.util.Set; import static android.app.backup.BackupManager.FLAG_NON_INCREMENTAL_BACKUP; import static android.os.ServiceManager.getService; -import static com.stevesoltys.backup.activity.MainActivityController.createBackupFile; -import static com.stevesoltys.backup.settings.SettingsManager.getBackupFolderUri; -import static com.stevesoltys.backup.settings.SettingsManager.getBackupPassword; +import static com.stevesoltys.backup.transport.ConfigurableBackupTransportService.getBackupTransport; public class BackupJobService extends JobService { @@ -37,7 +30,6 @@ public class BackupJobService extends JobService { ); private final IBackupManager backupManager; - private final TransportService transportService = new TransportService(); public BackupJobService() { backupManager = IBackupManager.Stub.asInterface(getService("backup")); @@ -50,17 +42,10 @@ public class BackupJobService extends JobService { try { LinkedList packages = new LinkedList<>(new PackageService().getEligiblePackages()); packages.removeAll(IGNORED_PACKAGES); - Uri fileUri = createBackupFile(getContentResolver(), getBackupFolderUri(this)); - ContentProviderBackupConfiguration backupConfiguration = new ContentProviderBackupConfigurationBuilder() - .setContext(this) - .setPackages(new HashSet<>(packages)) - .setOutputUri(fileUri) - .setPassword(getBackupPassword(this)) - .build(); - transportService.initializeBackupTransport(backupConfiguration); - // TODO use an observer to know when backups fail String[] packageArray = packages.toArray(new String[packages.size()]); + ConfigurableBackupTransport backupTransport = getBackupTransport(getApplication()); + backupTransport.prepareBackup(packageArray.length); int result = backupManager.requestBackup(packageArray, null, null, FLAG_NON_INCREMENTAL_BACKUP); if (result == BackupManager.SUCCESS) { Log.i(TAG, "Backup succeeded "); @@ -69,8 +54,6 @@ public class BackupJobService extends JobService { } // TODO show notification on backup error - } catch (IOException e) { - Log.e(TAG, "Error creating backup file: ", e); } catch (RemoteException e) { Log.e(TAG, "Error during backup: ", e); } finally { 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 abd2d075..8bcbfefa 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 @@ -6,14 +6,11 @@ import android.widget.PopupWindow; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; + import com.stevesoltys.backup.R; import com.stevesoltys.backup.session.backup.BackupResult; import com.stevesoltys.backup.session.backup.BackupSession; import com.stevesoltys.backup.session.backup.BackupSessionObserver; -import com.stevesoltys.backup.transport.ConfigurableBackupTransport; -import com.stevesoltys.backup.transport.ConfigurableBackupTransportService; - -import java.net.URI; /** * @author Steve Soltys @@ -24,12 +21,9 @@ class BackupObserver implements BackupSessionObserver { private final PopupWindow popupWindow; - private final URI contentUri; - - BackupObserver(Activity context, PopupWindow popupWindow, URI contentUri) { + BackupObserver(Activity context, PopupWindow popupWindow) { this.context = context; this.popupWindow = popupWindow; - this.contentUri = contentUri; } @Override @@ -65,14 +59,6 @@ class BackupObserver implements BackupSessionObserver { @Override public void backupSessionCompleted(BackupSession backupSession, BackupResult backupResult) { - ConfigurableBackupTransport backupTransport = ConfigurableBackupTransportService.getBackupTransport(); - - if (!backupTransport.isActive()) { - return; - } - - backupTransport.reset(); - 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 3795170c..84be267f 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 @@ -1,23 +1,22 @@ package com.stevesoltys.backup.service.backup; import android.app.Activity; -import android.net.Uri; import android.util.Log; import android.view.View; import android.widget.PopupWindow; import android.widget.TextView; -import android.widget.Toast; + import com.stevesoltys.backup.R; 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.component.provider.ContentProviderBackupConfiguration; -import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfigurationBuilder; +import com.stevesoltys.backup.transport.ConfigurableBackupTransport; -import java.net.URI; import java.util.Set; +import static com.stevesoltys.backup.transport.ConfigurableBackupTransportService.getBackupTransport; + /** * @author Steve Soltys */ @@ -27,27 +26,14 @@ public class BackupService { private final TransportService transportService = new TransportService(); - public void backupPackageData(Set selectedPackages, Uri contentUri, Activity parent, - String selectedPassword) { + public void backupPackageData(Set selectedPackages, Activity parent) { try { selectedPackages.add("@pm@"); - ContentProviderBackupConfiguration backupConfiguration = new ContentProviderBackupConfigurationBuilder() - .setContext(parent) - .setOutputUri(contentUri) - .setPackages(selectedPackages) - .setPassword(selectedPassword) - .build(); - - boolean success = transportService.initializeBackupTransport(backupConfiguration); - - if (!success) { - Toast.makeText(parent, R.string.backup_in_progress, Toast.LENGTH_LONG).show(); - return; - } - PopupWindow popupWindow = PopupWindowUtil.showLoadingPopupWindow(parent); - BackupObserver backupObserver = new BackupObserver(parent, popupWindow, new URI(contentUri.getPath())); + 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/service/restore/RestoreObserver.java b/app/src/main/java/com/stevesoltys/backup/service/restore/RestoreObserver.java index 69caa690..d7132af5 100644 --- a/app/src/main/java/com/stevesoltys/backup/service/restore/RestoreObserver.java +++ b/app/src/main/java/com/stevesoltys/backup/service/restore/RestoreObserver.java @@ -5,11 +5,10 @@ import android.widget.PopupWindow; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; + import com.stevesoltys.backup.R; import com.stevesoltys.backup.session.restore.RestoreResult; import com.stevesoltys.backup.session.restore.RestoreSessionObserver; -import com.stevesoltys.backup.transport.ConfigurableBackupTransport; -import com.stevesoltys.backup.transport.ConfigurableBackupTransportService; /** * @author Steve Soltys @@ -56,14 +55,6 @@ class RestoreObserver implements RestoreSessionObserver { @Override public void restoreSessionCompleted(RestoreResult restoreResult) { - ConfigurableBackupTransport backupTransport = ConfigurableBackupTransportService.getBackupTransport(); - - if (!backupTransport.isActive()) { - return; - } - - backupTransport.reset(); - context.runOnUiThread(() -> { if (restoreResult == RestoreResult.SUCCESS) { Toast.makeText(context, R.string.restore_success, Toast.LENGTH_LONG).show(); diff --git a/app/src/main/java/com/stevesoltys/backup/service/restore/RestoreService.java b/app/src/main/java/com/stevesoltys/backup/service/restore/RestoreService.java index 06e15c0b..6441397a 100644 --- a/app/src/main/java/com/stevesoltys/backup/service/restore/RestoreService.java +++ b/app/src/main/java/com/stevesoltys/backup/service/restore/RestoreService.java @@ -6,17 +6,18 @@ import android.os.RemoteException; import android.util.Log; import android.view.View; import android.widget.PopupWindow; -import android.widget.Toast; + import com.stevesoltys.backup.R; import com.stevesoltys.backup.activity.PopupWindowUtil; import com.stevesoltys.backup.activity.restore.RestorePopupWindowListener; import com.stevesoltys.backup.service.TransportService; import com.stevesoltys.backup.session.restore.RestoreSession; -import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfiguration; -import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfigurationBuilder; +import com.stevesoltys.backup.transport.ConfigurableBackupTransport; import java.util.Set; +import static com.stevesoltys.backup.transport.ConfigurableBackupTransportService.getBackupTransport; + /** * @author Steve Soltys */ @@ -27,21 +28,9 @@ public class RestoreService { private final TransportService transportService = new TransportService(); public void restorePackages(Set selectedPackages, Uri contentUri, Activity parent, String password) { + ConfigurableBackupTransport backupTransport = getBackupTransport(parent.getApplication()); + backupTransport.prepareRestore(password, contentUri); try { - ContentProviderBackupConfiguration backupConfiguration = new ContentProviderBackupConfigurationBuilder(). - setContext(parent) - .setOutputUri(contentUri) - .setPackages(selectedPackages) - .setPassword(password) - .build(); - - boolean success = transportService.initializeBackupTransport(backupConfiguration); - - if (!success) { - Toast.makeText(parent, R.string.restore_in_progress, Toast.LENGTH_LONG).show(); - return; - } - PopupWindow popupWindow = PopupWindowUtil.showLoadingPopupWindow(parent); RestoreObserver restoreObserver = new RestoreObserver(parent, popupWindow, selectedPackages.size()); RestoreSession restoreSession = transportService.restore(restoreObserver, selectedPackages); 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 6cddb1a8..505b0670 100644 --- a/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransport.java +++ b/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransport.java @@ -3,14 +3,15 @@ package com.stevesoltys.backup.transport; import android.app.backup.BackupTransport; import android.app.backup.RestoreDescription; import android.app.backup.RestoreSet; +import android.content.Context; import android.content.pm.PackageInfo; +import android.net.Uri; import android.os.ParcelFileDescriptor; -import com.android.internal.util.Preconditions; import com.stevesoltys.backup.transport.component.BackupComponent; import com.stevesoltys.backup.transport.component.RestoreComponent; -import com.stevesoltys.backup.transport.component.stub.StubBackupComponent; -import com.stevesoltys.backup.transport.component.stub.StubRestoreComponent; +import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupComponent; +import com.stevesoltys.backup.transport.component.provider.ContentProviderRestoreComponent; /** * @author Steve Soltys @@ -20,31 +21,27 @@ public class ConfigurableBackupTransport extends BackupTransport { private static final String TRANSPORT_DIRECTORY_NAME = "com.stevesoltys.backup.transport.ConfigurableBackupTransport"; - private BackupComponent backupComponent; + public static final String DEFAULT_FULL_BACKUP_DIRECTORY = "full/"; - private RestoreComponent restoreComponent; + public static final String DEFAULT_INCREMENTAL_BACKUP_DIRECTORY = "incr/"; - ConfigurableBackupTransport() { - backupComponent = new StubBackupComponent(); - restoreComponent = new StubRestoreComponent(); + public static final long DEFAULT_BACKUP_QUOTA = Long.MAX_VALUE; + + private final BackupComponent backupComponent; + + private final RestoreComponent restoreComponent; + + ConfigurableBackupTransport(Context context) { + backupComponent = new ContentProviderBackupComponent(context); + restoreComponent = new ContentProviderRestoreComponent(context); } - public void initialize(BackupComponent backupComponent, RestoreComponent restoreComponent) { - Preconditions.checkNotNull(backupComponent); - Preconditions.checkNotNull(restoreComponent); - Preconditions.checkState(!isActive()); - - this.restoreComponent = restoreComponent; - this.backupComponent = backupComponent; + public void prepareBackup(int numberOfPackages) { + backupComponent.prepareBackup(numberOfPackages); } - public void reset() { - backupComponent = new StubBackupComponent(); - restoreComponent = new StubRestoreComponent(); - } - - public boolean isActive() { - return !(backupComponent instanceof StubBackupComponent || restoreComponent instanceof StubRestoreComponent); + public void prepareRestore(String password, Uri fileUri) { + restoreComponent.prepareRestore(password, fileUri); } @Override diff --git a/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransportService.java b/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransportService.java index 89d74e1c..da896889 100644 --- a/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransportService.java +++ b/app/src/main/java/com/stevesoltys/backup/transport/ConfigurableBackupTransportService.java @@ -1,6 +1,7 @@ package com.stevesoltys.backup.transport; import android.app.Service; +import android.content.Context; import android.content.Intent; import android.os.IBinder; import android.util.Log; @@ -14,10 +15,10 @@ public class ConfigurableBackupTransportService extends Service { private static ConfigurableBackupTransport backupTransport = null; - public static ConfigurableBackupTransport getBackupTransport() { + public static ConfigurableBackupTransport getBackupTransport(Context context) { if (backupTransport == null) { - backupTransport = new ConfigurableBackupTransport(); + backupTransport = new ConfigurableBackupTransport(context); } return backupTransport; @@ -31,7 +32,7 @@ public class ConfigurableBackupTransportService extends Service { @Override public IBinder onBind(Intent intent) { - return getBackupTransport().getBinder(); + return getBackupTransport(getApplicationContext()).getBinder(); } @Override 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 1fafbe63..f3c7cd42 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,6 +8,8 @@ import android.os.ParcelFileDescriptor; */ public interface BackupComponent { + void prepareBackup(int numberOfPackages); + String currentDestinationString(); String dataManagementLabel(); diff --git a/app/src/main/java/com/stevesoltys/backup/transport/component/RestoreComponent.java b/app/src/main/java/com/stevesoltys/backup/transport/component/RestoreComponent.java index 2873cf1b..08f866a0 100644 --- a/app/src/main/java/com/stevesoltys/backup/transport/component/RestoreComponent.java +++ b/app/src/main/java/com/stevesoltys/backup/transport/component/RestoreComponent.java @@ -3,6 +3,7 @@ package com.stevesoltys.backup.transport.component; import android.app.backup.RestoreDescription; import android.app.backup.RestoreSet; import android.content.pm.PackageInfo; +import android.net.Uri; import android.os.ParcelFileDescriptor; /** @@ -10,6 +11,8 @@ import android.os.ParcelFileDescriptor; */ public interface RestoreComponent { + void prepareRestore(String password, Uri fileUri); + int startRestore(long token, PackageInfo[] packages); RestoreDescription nextRestorePackage(); 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 1100c59e..e964ec61 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 @@ -1,28 +1,47 @@ package com.stevesoltys.backup.transport.component.provider; import android.app.backup.BackupDataInput; -import android.content.ContentResolver; +import android.content.Context; import android.content.pm.PackageInfo; +import android.net.Uri; import android.os.ParcelFileDescriptor; import android.util.Base64; import android.util.Log; + import com.stevesoltys.backup.security.CipherUtil; import com.stevesoltys.backup.security.KeyGenerator; +import com.stevesoltys.backup.settings.SettingsManager; import com.stevesoltys.backup.transport.component.BackupComponent; -import libcore.io.IoUtils; + import org.apache.commons.io.IOUtils; -import javax.crypto.Cipher; -import javax.crypto.SecretKey; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.text.SimpleDateFormat; import java.util.Arrays; +import java.util.Date; +import java.util.Locale; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; -import static android.app.backup.BackupTransport.*; +import javax.crypto.Cipher; +import javax.crypto.SecretKey; + +import libcore.io.IoUtils; + +import static android.app.backup.BackupTransport.TRANSPORT_ERROR; +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; +import static android.provider.DocumentsContract.buildDocumentUriUsingTree; +import static android.provider.DocumentsContract.createDocument; +import static android.provider.DocumentsContract.getTreeDocumentId; +import static com.stevesoltys.backup.activity.MainActivityController.DOCUMENT_MIME_TYPE; +import static com.stevesoltys.backup.transport.ConfigurableBackupTransport.DEFAULT_BACKUP_QUOTA; +import static com.stevesoltys.backup.transport.ConfigurableBackupTransport.DEFAULT_FULL_BACKUP_DIRECTORY; +import static com.stevesoltys.backup.transport.ConfigurableBackupTransport.DEFAULT_INCREMENTAL_BACKUP_DIRECTORY; import static java.util.Objects.requireNonNull; /** @@ -32,18 +51,22 @@ public class ContentProviderBackupComponent implements BackupComponent { private static final String TAG = ContentProviderBackupComponent.class.getName(); + private static final String DOCUMENT_SUFFIX = "yyyy-MM-dd_HH_mm_ss"; + private static final String DESTINATION_DESCRIPTION = "Backing up to zip file"; private static final String TRANSPORT_DATA_MANAGEMENT_LABEL = ""; private static final int INITIAL_BUFFER_SIZE = 512; - private final ContentProviderBackupConfiguration configuration; + private final Context context; + + private int numberOfPackages = 0; private ContentProviderBackupState backupState; - public ContentProviderBackupComponent(ContentProviderBackupConfiguration configuration) { - this.configuration = configuration; + public ContentProviderBackupComponent(Context context) { + this.context = context; } @Override @@ -58,7 +81,7 @@ public class ContentProviderBackupComponent implements BackupComponent { if (size <= 0) { result = TRANSPORT_PACKAGE_REJECTED; - } else if (size > configuration.getBackupSizeQuota()) { + } else if (size > DEFAULT_BACKUP_QUOTA) { result = TRANSPORT_QUOTA_EXCEEDED; } @@ -70,6 +93,11 @@ public class ContentProviderBackupComponent implements BackupComponent { return TRANSPORT_OK; } + @Override + public void prepareBackup(int numberOfPackages) { + this.numberOfPackages = numberOfPackages; + } + @Override public String currentDestinationString() { return DESTINATION_DESCRIPTION; @@ -87,7 +115,7 @@ public class ContentProviderBackupComponent implements BackupComponent { @Override public long getBackupQuota(String packageName, boolean fullBackup) { - return configuration.getBackupSizeQuota(); + return DEFAULT_BACKUP_QUOTA; } @Override @@ -115,7 +143,7 @@ public class ContentProviderBackupComponent implements BackupComponent { Cipher cipher = CipherUtil.startEncrypt(backupState.getSecretKey(), backupState.getSalt()); backupState.setCipher(cipher); - ZipEntry zipEntry = new ZipEntry(configuration.getFullBackupDirectory() + backupState.getPackageName()); + ZipEntry zipEntry = new ZipEntry(DEFAULT_FULL_BACKUP_DIRECTORY + backupState.getPackageName()); backupState.getOutputStream().putNextEntry(zipEntry); } catch (Exception ex) { @@ -164,7 +192,7 @@ public class ContentProviderBackupComponent implements BackupComponent { long bytesTransferred = backupState.getBytesTransferred() + numBytes; - if (bytesTransferred > configuration.getBackupSizeQuota()) { + if (bytesTransferred > DEFAULT_BACKUP_QUOTA) { return TRANSPORT_QUOTA_EXCEEDED; } @@ -199,7 +227,7 @@ public class ContentProviderBackupComponent implements BackupComponent { int dataSize = backupDataInput.getDataSize(); if (dataSize >= 0) { - ZipEntry zipEntry = new ZipEntry(configuration.getIncrementalBackupDirectory() + + ZipEntry zipEntry = new ZipEntry(DEFAULT_INCREMENTAL_BACKUP_DIRECTORY + backupState.getPackageName() + "/" + chunkFileName); outputStream.putNextEntry(zipEntry); @@ -246,14 +274,18 @@ public class ContentProviderBackupComponent implements BackupComponent { backupState.getOutputStream().write(backupState.getSalt()); backupState.getOutputStream().closeEntry(); - String password = requireNonNull(configuration.getPassword()); + String password = requireNonNull(SettingsManager.getBackupPassword(context)); backupState.setSecretKey(KeyGenerator.generate(password, backupState.getSalt())); } } private void initializeOutputStream() throws IOException { - ContentResolver contentResolver = configuration.getContext().getContentResolver(); - ParcelFileDescriptor outputFileDescriptor = contentResolver.openFileDescriptor(configuration.getUri(), "w"); + Uri folderUri = SettingsManager.getBackupFolderUri(context); + // TODO notify about failure with notification + Uri fileUri = createBackupFile(folderUri); + + ParcelFileDescriptor outputFileDescriptor = context.getContentResolver().openFileDescriptor(fileUri, "w"); + if (outputFileDescriptor == null) throw new IOException(); backupState.setOutputFileDescriptor(outputFileDescriptor); FileOutputStream fileOutputStream = new FileOutputStream(outputFileDescriptor.getFileDescriptor()); @@ -261,6 +293,25 @@ public class ContentProviderBackupComponent implements BackupComponent { backupState.setOutputStream(zipOutputStream); } + private Uri createBackupFile(Uri folderUri) throws IOException { + Uri documentUri = buildDocumentUriUsingTree(folderUri, getTreeDocumentId(folderUri)); + try { + Uri fileUri = createDocument(context.getContentResolver(), documentUri, DOCUMENT_MIME_TYPE, getBackupFileName()); + if (fileUri == null) throw new IOException(); + return fileUri; + + } catch (SecurityException e) { + // happens when folder was deleted and thus Uri permission don't exist anymore + throw new IOException(e); + } + } + + private String getBackupFileName() { + SimpleDateFormat dateFormat = new SimpleDateFormat(DOCUMENT_SUFFIX, Locale.US); + String date = dateFormat.format(new Date()); + return "backup-" + date; + } + private int clearBackupState(boolean closeFile) { if (backupState == null) { @@ -283,7 +334,7 @@ public class ContentProviderBackupComponent implements BackupComponent { outputStream.closeEntry(); } - if (backupState.getPackageIndex() == configuration.getPackageCount() || closeFile) { + if (backupState.getPackageIndex() == numberOfPackages || closeFile) { if (outputStream != null) { outputStream.finish(); outputStream.close(); diff --git a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupConfiguration.java b/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupConfiguration.java deleted file mode 100644 index bf90d5e5..00000000 --- a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupConfiguration.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.stevesoltys.backup.transport.component.provider; - -import android.content.Context; -import android.net.Uri; - -import java.util.Set; - -/** - * @author Steve Soltys - */ -public class ContentProviderBackupConfiguration { - - private final Context context; - - private final Uri uri; - - private final String password; - - private final long backupSizeQuota; - - private final Set packages; - - private final String fullBackupDirectory; - - private final String incrementalBackupDirectory; - - ContentProviderBackupConfiguration(Context context, Uri uri, Set packages, String password, - long backupSizeQuota, String fullBackupDirectory, - String incrementalBackupDirectory) { - this.context = context; - this.uri = uri; - this.packages = packages; - this.password = password; - this.backupSizeQuota = backupSizeQuota; - this.fullBackupDirectory = fullBackupDirectory; - this.incrementalBackupDirectory = incrementalBackupDirectory; - } - - public long getBackupSizeQuota() { - return backupSizeQuota; - } - - public Context getContext() { - return context; - } - - public String getFullBackupDirectory() { - return fullBackupDirectory; - } - - public String getIncrementalBackupDirectory() { - return incrementalBackupDirectory; - } - - public int getPackageCount() { - return packages.size(); - } - - public String getPassword() { - return password; - } - - public Uri getUri() { - return uri; - } -} diff --git a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupConfigurationBuilder.java b/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupConfigurationBuilder.java deleted file mode 100644 index 0f63b8c5..00000000 --- a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderBackupConfigurationBuilder.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.stevesoltys.backup.transport.component.provider; - -import android.content.Context; -import android.net.Uri; -import com.android.internal.util.Preconditions; - -import java.util.Set; - -/** - * @author Steve Soltys - */ -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 Uri outputUri; - - private Set packages; - - private String password; - - private long backupSizeQuota = Long.MAX_VALUE; - - private String incrementalBackupDirectory = DEFAULT_INCREMENTAL_BACKUP_DIRECTORY; - - private String fullBackupDirectory = DEFAULT_FULL_BACKUP_DIRECTORY; - - 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."); - - return new ContentProviderBackupConfiguration(context, outputUri, packages, password, backupSizeQuota, - fullBackupDirectory, incrementalBackupDirectory); - } - - public ContentProviderBackupConfigurationBuilder setBackupSizeQuota(long backupSizeQuota) { - this.backupSizeQuota = backupSizeQuota; - return this; - } - - public ContentProviderBackupConfigurationBuilder setContext(Context context) { - this.context = context; - return this; - } - - public ContentProviderBackupConfigurationBuilder setFullBackupDirectory(String fullBackupDirectory) { - this.fullBackupDirectory = fullBackupDirectory; - return this; - } - - public ContentProviderBackupConfigurationBuilder setIncrementalBackupDirectory(String incrementalBackupDirectory) { - this.incrementalBackupDirectory = incrementalBackupDirectory; - return this; - } - - public ContentProviderBackupConfigurationBuilder setOutputUri(Uri outputUri) { - this.outputUri = outputUri; - return this; - } - - public ContentProviderBackupConfigurationBuilder setPackages(Set packages) { - this.packages = packages; - return this; - } - - public ContentProviderBackupConfigurationBuilder setPassword(String password) { - this.password = password; - return this; - } -} diff --git a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderRestoreComponent.java b/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderRestoreComponent.java index 47aeeb55..05f1abcd 100644 --- a/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderRestoreComponent.java +++ b/app/src/main/java/com/stevesoltys/backup/transport/component/provider/ContentProviderRestoreComponent.java @@ -1,10 +1,13 @@ package com.stevesoltys.backup.transport.component.provider; +import android.annotation.Nullable; import android.app.backup.BackupDataOutput; import android.app.backup.RestoreDescription; import android.app.backup.RestoreSet; import android.content.ContentResolver; +import android.content.Context; import android.content.pm.PackageInfo; +import android.net.Uri; import android.os.ParcelFileDescriptor; import android.util.Base64; import android.util.Log; @@ -38,6 +41,9 @@ import static android.app.backup.BackupTransport.TRANSPORT_OK; import static android.app.backup.BackupTransport.TRANSPORT_PACKAGE_REJECTED; import static android.app.backup.RestoreDescription.TYPE_FULL_STREAM; import static android.app.backup.RestoreDescription.TYPE_KEY_VALUE; +import static com.stevesoltys.backup.transport.ConfigurableBackupTransport.DEFAULT_FULL_BACKUP_DIRECTORY; +import static com.stevesoltys.backup.transport.ConfigurableBackupTransport.DEFAULT_INCREMENTAL_BACKUP_DIRECTORY; +import static java.util.Objects.requireNonNull; /** * @author Steve Soltys @@ -50,12 +56,23 @@ public class ContentProviderRestoreComponent implements RestoreComponent { private static final int DEFAULT_BUFFER_SIZE = 2048; - private ContentProviderBackupConfiguration configuration; + @Nullable + private String password; + @Nullable + private Uri fileUri; private ContentProviderRestoreState restoreState; - public ContentProviderRestoreComponent(ContentProviderBackupConfiguration configuration) { - this.configuration = configuration; + private final Context context; + + public ContentProviderRestoreComponent(Context context) { + this.context = context; + } + + @Override + public void prepareRestore(String password, Uri fileUri) { + this.password = password; + this.fileUri = fileUri; } @Override @@ -64,14 +81,16 @@ public class ContentProviderRestoreComponent implements RestoreComponent { restoreState.setPackages(packages); restoreState.setPackageIndex(-1); - if (configuration.getPassword() != null && !configuration.getPassword().isEmpty()) { + String password = requireNonNull(this.password); + + if (!password.isEmpty()) { try { ParcelFileDescriptor inputFileDescriptor = buildInputFileDescriptor(); ZipInputStream inputStream = buildInputStream(inputFileDescriptor); seekToEntry(inputStream, ContentProviderBackupConstants.SALT_FILE_PATH); restoreState.setSalt(Streams.readFullyNoClose(inputStream)); - restoreState.setSecretKey(KeyGenerator.generate(configuration.getPassword(), restoreState.getSalt())); + restoreState.setSecretKey(KeyGenerator.generate(password, restoreState.getSalt())); IoUtils.closeQuietly(inputFileDescriptor); IoUtils.closeQuietly(inputStream); @@ -116,11 +135,11 @@ public class ContentProviderRestoreComponent implements RestoreComponent { restoreState.setPackageIndex(packageIndex); String name = packages[packageIndex].packageName; - if (containsPackageFile(configuration.getIncrementalBackupDirectory() + name)) { + if (containsPackageFile(DEFAULT_INCREMENTAL_BACKUP_DIRECTORY + name)) { restoreState.setRestoreType(TYPE_KEY_VALUE); return new RestoreDescription(name, restoreState.getRestoreType()); - } else if (containsPackageFile(configuration.getFullBackupDirectory() + name)) { + } else if (containsPackageFile(DEFAULT_FULL_BACKUP_DIRECTORY + name)) { restoreState.setRestoreType(TYPE_FULL_STREAM); return new RestoreDescription(name, restoreState.getRestoreType()); } @@ -159,7 +178,7 @@ public class ContentProviderRestoreComponent implements RestoreComponent { BackupDataOutput backupDataOutput = new BackupDataOutput(outputFileDescriptor.getFileDescriptor()); Optional zipEntryOptional = seekToEntry(inputStream, - configuration.getIncrementalBackupDirectory() + packageName); + DEFAULT_INCREMENTAL_BACKUP_DIRECTORY + packageName); while (zipEntryOptional.isPresent()) { String fileName = new File(zipEntryOptional.get().getName()).getName(); @@ -170,7 +189,7 @@ public class ContentProviderRestoreComponent implements RestoreComponent { backupDataOutput.writeEntityData(backupData, backupData.length); inputStream.closeEntry(); - zipEntryOptional = seekToEntry(inputStream, configuration.getIncrementalBackupDirectory() + packageName); + zipEntryOptional = seekToEntry(inputStream, DEFAULT_INCREMENTAL_BACKUP_DIRECTORY + packageName); } IoUtils.closeQuietly(inputFileDescriptor); @@ -207,7 +226,7 @@ public class ContentProviderRestoreComponent implements RestoreComponent { ZipInputStream inputStream = buildInputStream(inputFileDescriptor); restoreState.setInputStream(inputStream); - if (!seekToEntry(inputStream, configuration.getFullBackupDirectory() + name).isPresent()) { + if (!seekToEntry(inputStream, DEFAULT_FULL_BACKUP_DIRECTORY + name).isPresent()) { IoUtils.closeQuietly(inputFileDescriptor); IoUtils.closeQuietly(outputFileDescriptor); return TRANSPORT_PACKAGE_REJECTED; @@ -317,8 +336,8 @@ public class ContentProviderRestoreComponent implements RestoreComponent { } private ParcelFileDescriptor buildInputFileDescriptor() throws FileNotFoundException { - ContentResolver contentResolver = configuration.getContext().getContentResolver(); - return contentResolver.openFileDescriptor(configuration.getUri(), "r"); + ContentResolver contentResolver = context.getContentResolver(); + return contentResolver.openFileDescriptor(requireNonNull(fileUri), "r"); } private ZipInputStream buildInputStream(ParcelFileDescriptor inputFileDescriptor) { diff --git a/app/src/main/java/com/stevesoltys/backup/transport/component/stub/StubBackupComponent.java b/app/src/main/java/com/stevesoltys/backup/transport/component/stub/StubBackupComponent.java deleted file mode 100644 index 5c335a80..00000000 --- a/app/src/main/java/com/stevesoltys/backup/transport/component/stub/StubBackupComponent.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.stevesoltys.backup.transport.component.stub; - -import android.content.pm.PackageInfo; -import android.os.ParcelFileDescriptor; -import com.stevesoltys.backup.transport.component.BackupComponent; - -/** - * @author Steve Soltys - */ -public class StubBackupComponent implements BackupComponent { - - @Override - public void cancelFullBackup() { - - } - - @Override - public int checkFullBackupSize(long size) { - return 0; - } - - @Override - public int clearBackupData(PackageInfo packageInfo) { - return 0; - } - - @Override - public String currentDestinationString() { - return null; - } - - @Override - public String dataManagementLabel() { - return null; - } - - @Override - public int finishBackup() { - return 0; - } - - @Override - public long getBackupQuota(String packageName, boolean fullBackup) { - return 0; - } - - @Override - public int initializeDevice() { - return 0; - } - - @Override - public int performFullBackup(PackageInfo targetPackage, ParcelFileDescriptor fileDescriptor) { - return 0; - } - - @Override - public int performIncrementalBackup(PackageInfo targetPackage, ParcelFileDescriptor data) { - return 0; - } - - @Override - public long requestBackupTime() { - return 0; - } - - @Override - public long requestFullBackupTime() { - return 0; - } - - @Override - public int sendBackupData(int numBytes) { - return 0; - } -} diff --git a/app/src/main/java/com/stevesoltys/backup/transport/component/stub/StubRestoreComponent.java b/app/src/main/java/com/stevesoltys/backup/transport/component/stub/StubRestoreComponent.java deleted file mode 100644 index 56d6cfd3..00000000 --- a/app/src/main/java/com/stevesoltys/backup/transport/component/stub/StubRestoreComponent.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.stevesoltys.backup.transport.component.stub; - -import android.content.pm.PackageInfo; -import android.os.ParcelFileDescriptor; -import com.stevesoltys.backup.transport.component.RestoreComponent; -import android.app.backup.RestoreDescription; -import android.app.backup.RestoreSet; - -/** - * @author Steve Soltys - */ -public class StubRestoreComponent implements RestoreComponent { - - @Override - public int startRestore(long token, PackageInfo[] packages) { - return 0; - } - - @Override - public RestoreDescription nextRestorePackage() { - return null; - } - - @Override - public int getRestoreData(ParcelFileDescriptor outputFileDescriptor) { - return 0; - } - - @Override - public int getNextFullRestoreDataChunk(ParcelFileDescriptor socket) { - return 0; - } - - @Override - public int abortFullRestore() { - return 0; - } - - @Override - public long getCurrentRestoreSet() { - return 0; - } - - @Override - public void finishRestore() { - - } - - @Override - public RestoreSet[] getAvailableRestoreSets() { - return new RestoreSet[0]; - } -}