mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-24 15:56:07 +00:00
Prevent a crash on rotation while a ProgressDialogTask is still running
This patch ensures ProgressDialogs are dismissed when the ON_PAUSE event is fired.
This commit is contained in:
parent
7d38bc9b71
commit
bb2716f640
7 changed files with 86 additions and 8 deletions
|
@ -0,0 +1,39 @@
|
||||||
|
package com.beemdevelopment.aegis.helpers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.ContextWrapper;
|
||||||
|
|
||||||
|
import androidx.activity.ComponentActivity;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.lifecycle.Lifecycle;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ContextHelper contains some disgusting hacks to obtain the Activity/Lifecycle from a Context.
|
||||||
|
*/
|
||||||
|
public class ContextHelper {
|
||||||
|
private ContextHelper() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// source: https://github.com/androidx/androidx/blob/e32e1da51a0c7448c74861c667fa76738a415a89/mediarouter/mediarouter/src/main/java/androidx/mediarouter/app/MediaRouteButton.java#L425-L435
|
||||||
|
@Nullable
|
||||||
|
public static ComponentActivity getActivity(@NonNull Context context) {
|
||||||
|
while (context instanceof ContextWrapper) {
|
||||||
|
if (context instanceof ComponentActivity) {
|
||||||
|
return (ComponentActivity) context;
|
||||||
|
}
|
||||||
|
|
||||||
|
context = ((ContextWrapper) context).getBaseContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static Lifecycle getLifecycle(@NonNull Context context) {
|
||||||
|
ComponentActivity activity = getActivity(context);
|
||||||
|
return activity == null ? null : activity.getLifecycle();
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package com.beemdevelopment.aegis.importers;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.lifecycle.Lifecycle;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.R;
|
import com.beemdevelopment.aegis.R;
|
||||||
import com.beemdevelopment.aegis.crypto.CryptParameters;
|
import com.beemdevelopment.aegis.crypto.CryptParameters;
|
||||||
|
@ -10,6 +11,7 @@ import com.beemdevelopment.aegis.crypto.CryptResult;
|
||||||
import com.beemdevelopment.aegis.crypto.CryptoUtils;
|
import com.beemdevelopment.aegis.crypto.CryptoUtils;
|
||||||
import com.beemdevelopment.aegis.encoding.Base32;
|
import com.beemdevelopment.aegis.encoding.Base32;
|
||||||
import com.beemdevelopment.aegis.encoding.EncodingException;
|
import com.beemdevelopment.aegis.encoding.EncodingException;
|
||||||
|
import com.beemdevelopment.aegis.helpers.ContextHelper;
|
||||||
import com.beemdevelopment.aegis.otp.HotpInfo;
|
import com.beemdevelopment.aegis.otp.HotpInfo;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfo;
|
import com.beemdevelopment.aegis.otp.OtpInfo;
|
||||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||||
|
@ -148,7 +150,8 @@ public class AndOtpImporter extends DatabaseImporter {
|
||||||
listener.onError(e);
|
listener.onError(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
task.execute(params);
|
Lifecycle lifecycle = ContextHelper.getLifecycle(context);
|
||||||
|
task.execute(lifecycle, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,8 @@ public class AuthActivity extends AegisActivity {
|
||||||
char[] password = EditTextHelper.getEditTextChars(_textPassword);
|
char[] password = EditTextHelper.getEditTextChars(_textPassword);
|
||||||
List<PasswordSlot> slots = _slots.findAll(PasswordSlot.class);
|
List<PasswordSlot> slots = _slots.findAll(PasswordSlot.class);
|
||||||
PasswordSlotDecryptTask.Params params = new PasswordSlotDecryptTask.Params(slots, password);
|
PasswordSlotDecryptTask.Params params = new PasswordSlotDecryptTask.Params(slots, password);
|
||||||
new PasswordSlotDecryptTask(AuthActivity.this, new PasswordDerivationListener()).execute(params);
|
PasswordSlotDecryptTask task = new PasswordSlotDecryptTask(AuthActivity.this, new PasswordDerivationListener());
|
||||||
|
task.execute(getLifecycle(), params);
|
||||||
});
|
});
|
||||||
|
|
||||||
biometricsButton.setOnClickListener(v -> {
|
biometricsButton.setOnClickListener(v -> {
|
||||||
|
|
|
@ -23,6 +23,7 @@ import android.widget.NumberPicker;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.activity.ComponentActivity;
|
||||||
import androidx.annotation.StringRes;
|
import androidx.annotation.StringRes;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
@ -94,7 +95,7 @@ public class Dialogs {
|
||||||
.create());
|
.create());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void showSetPasswordDialog(Activity activity, Dialogs.SlotListener listener) {
|
public static void showSetPasswordDialog(ComponentActivity activity, Dialogs.SlotListener listener) {
|
||||||
Zxcvbn zxcvbn = new Zxcvbn();
|
Zxcvbn zxcvbn = new Zxcvbn();
|
||||||
View view = activity.getLayoutInflater().inflate(R.layout.dialog_password, null);
|
View view = activity.getLayoutInflater().inflate(R.layout.dialog_password, null);
|
||||||
EditText textPassword = view.findViewById(R.id.text_password);
|
EditText textPassword = view.findViewById(R.id.text_password);
|
||||||
|
@ -150,7 +151,8 @@ public class Dialogs {
|
||||||
listener.onSlotResult(slot, cipher);
|
listener.onSlotResult(slot, cipher);
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
});
|
});
|
||||||
task.execute(new KeyDerivationTask.Params(slot, password));
|
KeyDerivationTask.Params params = new KeyDerivationTask.Params(slot, password);
|
||||||
|
task.execute(activity.getLifecycle(), params);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ import com.beemdevelopment.aegis.services.NotificationService;
|
||||||
import com.beemdevelopment.aegis.ui.models.ImportEntry;
|
import com.beemdevelopment.aegis.ui.models.ImportEntry;
|
||||||
import com.beemdevelopment.aegis.ui.preferences.SwitchPreference;
|
import com.beemdevelopment.aegis.ui.preferences.SwitchPreference;
|
||||||
import com.beemdevelopment.aegis.ui.tasks.PasswordSlotDecryptTask;
|
import com.beemdevelopment.aegis.ui.tasks.PasswordSlotDecryptTask;
|
||||||
|
import com.beemdevelopment.aegis.ui.tasks.ProgressDialogTask;
|
||||||
import com.beemdevelopment.aegis.util.UUIDMap;
|
import com.beemdevelopment.aegis.util.UUIDMap;
|
||||||
import com.beemdevelopment.aegis.vault.VaultBackupManager;
|
import com.beemdevelopment.aegis.vault.VaultBackupManager;
|
||||||
import com.beemdevelopment.aegis.vault.VaultEntry;
|
import com.beemdevelopment.aegis.vault.VaultEntry;
|
||||||
|
@ -384,7 +385,8 @@ public class PreferencesFragment extends PreferenceFragmentCompat {
|
||||||
if (isDigitsOnly(new String(password))) {
|
if (isDigitsOnly(new String(password))) {
|
||||||
List<PasswordSlot> slots = _vault.getCredentials().getSlots().findAll(PasswordSlot.class);
|
List<PasswordSlot> slots = _vault.getCredentials().getSlots().findAll(PasswordSlot.class);
|
||||||
PasswordSlotDecryptTask.Params params = new PasswordSlotDecryptTask.Params(slots, password);
|
PasswordSlotDecryptTask.Params params = new PasswordSlotDecryptTask.Params(slots, password);
|
||||||
new PasswordSlotDecryptTask(getActivity(), new PasswordConfirmationListener()).execute(params);
|
PasswordSlotDecryptTask task = new PasswordSlotDecryptTask(getActivity(), new PasswordConfirmationListener());
|
||||||
|
task.execute(getLifecycle(), params);
|
||||||
} else {
|
} else {
|
||||||
setPinKeyboardPreference(false);
|
setPinKeyboardPreference(false);
|
||||||
Dialogs.showSecureDialog(new AlertDialog.Builder(getActivity())
|
Dialogs.showSecureDialog(new AlertDialog.Builder(getActivity())
|
||||||
|
|
|
@ -125,7 +125,8 @@ public class SecuritySetupSlide extends SlideFragment {
|
||||||
private void deriveKey() {
|
private void deriveKey() {
|
||||||
PasswordSlot slot = new PasswordSlot();
|
PasswordSlot slot = new PasswordSlot();
|
||||||
KeyDerivationTask.Params params = new KeyDerivationTask.Params(slot, EditTextHelper.getEditTextChars(_textPassword));
|
KeyDerivationTask.Params params = new KeyDerivationTask.Params(slot, EditTextHelper.getEditTextChars(_textPassword));
|
||||||
new KeyDerivationTask(getContext(), new PasswordDerivationListener()).execute(params);
|
KeyDerivationTask task = new KeyDerivationTask(getContext(), new PasswordDerivationListener());
|
||||||
|
task.execute(getLifecycle(), params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
package com.beemdevelopment.aegis.ui.tasks;
|
package com.beemdevelopment.aegis.ui.tasks;
|
||||||
|
|
||||||
|
import android.app.Dialog;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
|
||||||
import com.beemdevelopment.aegis.ui.Dialogs;
|
|
||||||
|
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.lifecycle.Lifecycle;
|
||||||
|
import androidx.lifecycle.LifecycleObserver;
|
||||||
|
import androidx.lifecycle.OnLifecycleEvent;
|
||||||
|
|
||||||
|
import com.beemdevelopment.aegis.ui.Dialogs;
|
||||||
|
|
||||||
public abstract class ProgressDialogTask<Params, Result> extends AsyncTask<Params, String, Result> {
|
public abstract class ProgressDialogTask<Params, Result> extends AsyncTask<Params, String, Result> {
|
||||||
private ProgressDialog _dialog;
|
private ProgressDialog _dialog;
|
||||||
|
@ -47,4 +52,29 @@ public abstract class ProgressDialogTask<Params, Result> extends AsyncTask<Param
|
||||||
protected final ProgressDialog getDialog() {
|
protected final ProgressDialog getDialog() {
|
||||||
return _dialog;
|
return _dialog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SafeVarargs
|
||||||
|
public final void execute(@Nullable Lifecycle lifecycle, Params... params) {
|
||||||
|
if (lifecycle != null) {
|
||||||
|
LifecycleObserver observer = new Observer(getDialog());
|
||||||
|
lifecycle.addObserver(observer);
|
||||||
|
}
|
||||||
|
execute(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Observer implements LifecycleObserver {
|
||||||
|
private Dialog _dialog;
|
||||||
|
|
||||||
|
public Observer(Dialog dialog) {
|
||||||
|
_dialog = dialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
|
||||||
|
void onPause() {
|
||||||
|
if (_dialog != null && _dialog.isShowing()) {
|
||||||
|
_dialog.dismiss();
|
||||||
|
_dialog = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue