Add loading popup when fetching packages for backup or restore

This commit is contained in:
Steve Soltys 2019-02-21 22:41:54 -05:00
parent 9b979b3693
commit 023750be6e
5 changed files with 90 additions and 47 deletions

View file

@ -2,6 +2,7 @@ package com.stevesoltys.backup.activity.backup;
import android.app.Activity; import android.app.Activity;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -49,7 +50,7 @@ public class CreateBackupActivity extends Activity implements View.OnClickListen
contentUri = getIntent().getData(); contentUri = getIntent().getData();
controller = new CreateBackupActivityController(); controller = new CreateBackupActivityController();
controller.populatePackageList(packageListView, this); AsyncTask.execute(() -> controller.populatePackageList(packageListView, CreateBackupActivity.this));
} }
@Override @Override

View file

@ -14,6 +14,7 @@ import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.*; import android.widget.*;
import com.google.android.collect.Sets;
import com.stevesoltys.backup.R; import com.stevesoltys.backup.R;
import com.stevesoltys.backup.session.BackupManagerController; import com.stevesoltys.backup.session.BackupManagerController;
import com.stevesoltys.backup.session.backup.BackupSession; import com.stevesoltys.backup.session.backup.BackupSession;
@ -26,10 +27,10 @@ import com.stevesoltys.backup.transport.component.provider.ContentProviderBackup
import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfigurationBuilder; import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfigurationBuilder;
import com.stevesoltys.backup.transport.component.provider.ContentProviderRestoreComponent; import com.stevesoltys.backup.transport.component.provider.ContentProviderRestoreComponent;
import java.util.Collections;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
/** /**
* @author Steve Soltys * @author Steve Soltys
@ -38,7 +39,9 @@ class CreateBackupActivityController {
private static final String TAG = CreateBackupActivityController.class.getName(); private static final String TAG = CreateBackupActivityController.class.getName();
private static final Set<String> IGNORED_PACKAGES = Collections.singleton("com.android.providers.downloads.ui"); private static final Set<String> IGNORED_PACKAGES = Sets.newArraySet(
"com.android.providers.downloads.ui", "com.android.providers.media"
);
private final BackupManagerController backupManager; private final BackupManagerController backupManager;
@ -47,6 +50,17 @@ class CreateBackupActivityController {
} }
void populatePackageList(ListView packageListView, CreateBackupActivity parent) { void populatePackageList(ListView packageListView, CreateBackupActivity parent) {
AtomicReference<PopupWindow> popupWindow = new AtomicReference<>();
parent.runOnUiThread(() -> {
popupWindow.set(showLoadingPopupWindow(parent));
TextView textView = popupWindow.get().getContentView().findViewById(R.id.popup_text_view);
textView.setText(R.string.loading_packages);
View popupWindowButton = popupWindow.get().getContentView().findViewById(R.id.popup_cancel_button);
popupWindowButton.setOnClickListener(view -> parent.finish());
});
List<String> eligiblePackageList = new LinkedList<>(); List<String> eligiblePackageList = new LinkedList<>();
try { try {
@ -57,10 +71,29 @@ class CreateBackupActivityController {
Log.e(TAG, "Error while obtaining package list: ", e); Log.e(TAG, "Error while obtaining package list: ", e);
} }
parent.runOnUiThread(() -> {
if (popupWindow.get() != null) {
popupWindow.get().dismiss();
}
packageListView.setOnItemClickListener(parent); packageListView.setOnItemClickListener(parent);
packageListView.setAdapter(new ArrayAdapter<>(parent, R.layout.checked_list_item, eligiblePackageList)); packageListView.setAdapter(new ArrayAdapter<>(parent, R.layout.checked_list_item, eligiblePackageList));
packageListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); packageListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
});
}
private PopupWindow showLoadingPopupWindow(Activity parent) {
LayoutInflater inflater = (LayoutInflater) parent.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup popupViewGroup = parent.findViewById(R.id.popup_layout);
View popupView = inflater.inflate(R.layout.progress_popup_window, popupViewGroup);
PopupWindow popupWindow = new PopupWindow(popupView, 750, 350, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
popupWindow.setElevation(10);
popupWindow.setFocusable(false);
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
popupWindow.setOutsideTouchable(false);
return popupWindow;
} }
void showEnterPasswordAlert(Set<String> selectedPackages, Uri contentUri, Activity parent) { void showEnterPasswordAlert(Set<String> selectedPackages, Uri contentUri, Activity parent) {
@ -68,8 +101,8 @@ class CreateBackupActivityController {
passwordTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); passwordTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
new AlertDialog.Builder(parent) new AlertDialog.Builder(parent)
.setMessage("Please enter a password.\n" + .setTitle("Enter a password")
"You'll need this to restore your backup, so write it down!") .setMessage("You'll need this to restore your backup, so write it down!")
.setView(passwordTextView) .setView(passwordTextView)
.setPositiveButton("Set password", (dialog, button) -> .setPositiveButton("Set password", (dialog, button) ->
@ -86,7 +119,7 @@ class CreateBackupActivityController {
passwordTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); passwordTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
new AlertDialog.Builder(parent) new AlertDialog.Builder(parent)
.setMessage("Please confirm your password.") .setTitle("Confirm password")
.setView(passwordTextView) .setView(passwordTextView)
.setPositiveButton("Confirm", (dialog, button) -> { .setPositiveButton("Confirm", (dialog, button) -> {
@ -128,7 +161,7 @@ class CreateBackupActivityController {
return; return;
} }
PopupWindow popupWindow = buildStatusPopupWindow(parent); PopupWindow popupWindow = showLoadingPopupWindow(parent);
BackupObserver backupObserver = new BackupObserver(parent, popupWindow); BackupObserver backupObserver = new BackupObserver(parent, popupWindow);
BackupSession backupSession = backupManager.backup(backupObserver, selectedPackages); BackupSession backupSession = backupManager.backup(backupObserver, selectedPackages);
@ -155,17 +188,4 @@ class CreateBackupActivityController {
backupTransport.initialize(backupComponent, restoreComponent); backupTransport.initialize(backupComponent, restoreComponent);
return true; return true;
} }
private PopupWindow buildStatusPopupWindow(Activity parent) {
LayoutInflater inflater = (LayoutInflater) parent.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup popupViewGroup = parent.findViewById(R.id.popup_layout);
View popupView = inflater.inflate(R.layout.progress_popup_window, popupViewGroup);
PopupWindow popupWindow = new PopupWindow(popupView, 750, 350, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
popupWindow.setElevation(10);
popupWindow.setFocusable(false);
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
return popupWindow;
}
} }

View file

@ -2,6 +2,7 @@ package com.stevesoltys.backup.activity.restore;
import android.app.Activity; import android.app.Activity;
import android.net.Uri; import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -49,7 +50,7 @@ public class RestoreBackupActivity extends Activity implements View.OnClickListe
contentUri = getIntent().getData(); contentUri = getIntent().getData();
controller = new RestoreBackupActivityController(); controller = new RestoreBackupActivityController();
controller.populatePackageList(packageListView, contentUri, this); AsyncTask.execute(() -> controller.populatePackageList(packageListView, contentUri, this));
} }
@Override @Override

View file

@ -22,9 +22,9 @@ import com.stevesoltys.backup.transport.ConfigurableBackupTransport;
import com.stevesoltys.backup.transport.ConfigurableBackupTransportService; import com.stevesoltys.backup.transport.ConfigurableBackupTransportService;
import com.stevesoltys.backup.transport.component.BackupComponent; import com.stevesoltys.backup.transport.component.BackupComponent;
import com.stevesoltys.backup.transport.component.RestoreComponent; 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.ContentProviderBackupConfiguration;
import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfigurationBuilder; import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupConfigurationBuilder;
import com.stevesoltys.backup.transport.component.provider.ContentProviderBackupComponent;
import com.stevesoltys.backup.transport.component.provider.ContentProviderRestoreComponent; import com.stevesoltys.backup.transport.component.provider.ContentProviderRestoreComponent;
import libcore.io.IoUtils; import libcore.io.IoUtils;
@ -34,6 +34,7 @@ import java.io.IOException;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream; import java.util.zip.ZipInputStream;
@ -51,7 +52,19 @@ class RestoreBackupActivityController {
} }
void populatePackageList(ListView packageListView, Uri contentUri, RestoreBackupActivity parent) { void populatePackageList(ListView packageListView, Uri contentUri, RestoreBackupActivity parent) {
AtomicReference<PopupWindow> popupWindow = new AtomicReference<>();
parent.runOnUiThread(() -> {
popupWindow.set(showLoadingPopupWindow(parent));
TextView textView = popupWindow.get().getContentView().findViewById(R.id.popup_text_view);
textView.setText(R.string.loading_backup);
View popupWindowButton = popupWindow.get().getContentView().findViewById(R.id.popup_cancel_button);
popupWindowButton.setOnClickListener(view -> parent.finish());
});
List<String> eligiblePackageList = new LinkedList<>(); List<String> eligiblePackageList = new LinkedList<>();
try { try {
eligiblePackageList.addAll(getEligiblePackages(contentUri, parent)); eligiblePackageList.addAll(getEligiblePackages(contentUri, parent));
@ -59,9 +72,29 @@ class RestoreBackupActivityController {
Log.e(TAG, "Error while obtaining package list: ", e); Log.e(TAG, "Error while obtaining package list: ", e);
} }
parent.runOnUiThread(() -> {
if (popupWindow.get() != null) {
popupWindow.get().dismiss();
}
packageListView.setOnItemClickListener(parent); packageListView.setOnItemClickListener(parent);
packageListView.setAdapter(new ArrayAdapter<>(parent, R.layout.checked_list_item, eligiblePackageList)); packageListView.setAdapter(new ArrayAdapter<>(parent, R.layout.checked_list_item, eligiblePackageList));
packageListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); packageListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
});
}
private PopupWindow showLoadingPopupWindow(Activity parent) {
LayoutInflater inflater = (LayoutInflater) parent.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup popupViewGroup = parent.findViewById(R.id.popup_layout);
View popupView = inflater.inflate(R.layout.progress_popup_window, popupViewGroup);
PopupWindow popupWindow = new PopupWindow(popupView, 750, 350, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
popupWindow.setElevation(10);
popupWindow.setFocusable(false);
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
popupWindow.setOutsideTouchable(false);
return popupWindow;
} }
private List<String> getEligiblePackages(Uri contentUri, Activity context) throws IOException { private List<String> getEligiblePackages(Uri contentUri, Activity context) throws IOException {
@ -93,8 +126,8 @@ class RestoreBackupActivityController {
passwordTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); passwordTextView.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
new AlertDialog.Builder(parent) new AlertDialog.Builder(parent)
.setMessage("Please enter a password.\n" + .setTitle("Enter a password")
"If you didn't enter one while creating the backup, you can leave this blank.") .setMessage("If you didn't enter one while creating the backup, you can leave this blank.")
.setView(passwordTextView) .setView(passwordTextView)
.setPositiveButton("Confirm", (dialog, button) -> .setPositiveButton("Confirm", (dialog, button) ->
@ -103,7 +136,6 @@ class RestoreBackupActivityController {
.show(); .show();
} }
private void restorePackages(Set<String> selectedPackages, Uri contentUri, Activity parent, String password) { private void restorePackages(Set<String> selectedPackages, Uri contentUri, Activity parent, String password) {
try { try {
ContentProviderBackupConfiguration backupConfiguration = new ContentProviderBackupConfigurationBuilder(). ContentProviderBackupConfiguration backupConfiguration = new ContentProviderBackupConfigurationBuilder().
@ -115,12 +147,12 @@ class RestoreBackupActivityController {
boolean success = initializeBackupTransport(backupConfiguration); boolean success = initializeBackupTransport(backupConfiguration);
if(!success) { if (!success) {
Toast.makeText(parent, R.string.restore_in_progress, Toast.LENGTH_LONG).show(); Toast.makeText(parent, R.string.restore_in_progress, Toast.LENGTH_LONG).show();
return; return;
} }
PopupWindow popupWindow = buildPopupWindow(parent); PopupWindow popupWindow = showLoadingPopupWindow(parent);
RestoreObserver restoreObserver = new RestoreObserver(parent, popupWindow, selectedPackages.size()); RestoreObserver restoreObserver = new RestoreObserver(parent, popupWindow, selectedPackages.size());
RestoreSession restoreSession = backupManager.restore(restoreObserver, selectedPackages); RestoreSession restoreSession = backupManager.restore(restoreObserver, selectedPackages);
@ -136,7 +168,7 @@ class RestoreBackupActivityController {
private boolean initializeBackupTransport(ContentProviderBackupConfiguration configuration) { private boolean initializeBackupTransport(ContentProviderBackupConfiguration configuration) {
ConfigurableBackupTransport backupTransport = ConfigurableBackupTransportService.getBackupTransport(); ConfigurableBackupTransport backupTransport = ConfigurableBackupTransportService.getBackupTransport();
if(backupTransport.isActive()) { if (backupTransport.isActive()) {
return false; return false;
} }
@ -145,17 +177,4 @@ class RestoreBackupActivityController {
backupTransport.initialize(backupComponent, restoreComponent); backupTransport.initialize(backupComponent, restoreComponent);
return true; return true;
} }
private PopupWindow buildPopupWindow(Activity parent) {
LayoutInflater inflater = (LayoutInflater) parent.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
ViewGroup popupViewGroup = parent.findViewById(R.id.popup_layout);
View popupView = inflater.inflate(R.layout.progress_popup_window, popupViewGroup);
PopupWindow popupWindow = new PopupWindow(popupView, 750, 350, true);
popupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE));
popupWindow.setElevation(10);
popupWindow.setFocusable(false);
popupWindow.showAtLocation(popupView, Gravity.CENTER, 0, 0);
return popupWindow;
}
} }

View file

@ -19,5 +19,7 @@
<string name="popup_cancel">Cancel</string> <string name="popup_cancel">Cancel</string>
<string name="select_all">Select all</string> <string name="select_all">Select all</string>
<string name="loading_backup">Loading backup…</string>
<string name="loading_packages">Loading packages…</string>
</resources> </resources>