From b1c6c602a6b7e212dd53313c0631cfb5661df070 Mon Sep 17 00:00:00 2001 From: ameba23 Date: Thu, 22 Apr 2021 17:41:58 +0200 Subject: [PATCH] Add DozeView --- .../briar/android/account/DozeView.java | 2 +- .../briar/android/account/HuaweiView.java | 2 +- .../briar/android/account/PowerView.java | 4 +- .../android/activity/ActivityComponent.java | 3 + .../recover/RestoreAccountActivity.java | 2 +- .../recover/RestoreAccountDozeFragment.java | 118 ++++++++++++++++++ .../recover/RestoreAccountViewModel.java | 26 ++-- 7 files changed, 145 insertions(+), 12 deletions(-) create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountDozeFragment.java diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeView.java b/briar-android/src/main/java/org/briarproject/briar/android/account/DozeView.java index c036f657b..17d2ba78f 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/DozeView.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/DozeView.java @@ -14,7 +14,7 @@ import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting; @UiThread @NotNullByDefault -class DozeView extends PowerView { +public class DozeView extends PowerView { @Nullable private Runnable onButtonClickListener; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiView.java b/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiView.java index 54b4f4831..c120a305d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiView.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/HuaweiView.java @@ -21,7 +21,7 @@ import static android.os.Build.VERSION.SDK_INT; @UiThread @NotNullByDefault -class HuaweiView extends PowerView { +public class HuaweiView extends PowerView { private final static String PACKAGE_NAME = "com.huawei.systemmanager"; private final static String CLASS_NAME = diff --git a/briar-android/src/main/java/org/briarproject/briar/android/account/PowerView.java b/briar-android/src/main/java/org/briarproject/briar/android/account/PowerView.java index 4fd4d167c..37d34d0f7 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/account/PowerView.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/account/PowerView.java @@ -24,7 +24,7 @@ import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog; @UiThread @NotNullByDefault -abstract class PowerView extends ConstraintLayout { +public abstract class PowerView extends ConstraintLayout { private final TextView textView; private final ImageView checkImage; @@ -156,7 +156,7 @@ abstract class PowerView extends ConstraintLayout { }; } - interface OnCheckedChangedListener { + public interface OnCheckedChangedListener { void onCheckedChanged(); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java index a3b587a0d..f441e651b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/ActivityComponent.java @@ -95,6 +95,7 @@ import org.briarproject.briar.android.socialbackup.ShardsSentFragment; import org.briarproject.briar.android.socialbackup.ThresholdSelectorFragment; import org.briarproject.briar.android.socialbackup.creation.CreateBackupModule; import org.briarproject.briar.android.socialbackup.recover.RestoreAccountActivity; +import org.briarproject.briar.android.socialbackup.recover.RestoreAccountDozeFragment; import org.briarproject.briar.android.socialbackup.recover.RestoreAccountSetPasswordFragment; import org.briarproject.briar.android.splash.SplashScreenActivity; import org.briarproject.briar.android.test.TestDataActivity; @@ -294,4 +295,6 @@ public interface ActivityComponent { void inject(CustodianReturnShardSuccessFragment custodianReturnShardSuccessFragment); void inject(RestoreAccountSetPasswordFragment restoreAccountSetPasswordFragment); + + void inject(RestoreAccountDozeFragment restoreAccountDozeFragment); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountActivity.java index e63ed26ae..afdaccb7d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountActivity.java @@ -52,7 +52,7 @@ public class RestoreAccountActivity extends BaseActivity if (state == State.SET_PASSWORD) { showInitialFragment(RestoreAccountSetPasswordFragment.newInstance()); } else if (state == State.DOZE) { -// showDozeFragment(); + showDozeFragment(); } else if (state == State.CREATED || state == State.FAILED) { // TODO: Show an error if failed showApp(); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountDozeFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountDozeFragment.java new file mode 100644 index 000000000..719a56470 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountDozeFragment.java @@ -0,0 +1,118 @@ +package org.briarproject.briar.android.socialbackup.recover; + +import android.annotation.SuppressLint; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ProgressBar; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.account.DozeView; +import org.briarproject.briar.android.account.HuaweiView; +import org.briarproject.briar.android.account.PowerView; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.util.UiUtils; + +import androidx.annotation.Nullable; + +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; +import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING; +import static org.briarproject.briar.android.util.UiUtils.showOnboardingDialog; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class RestoreAccountDozeFragment extends RestoreAccountFragment + implements PowerView.OnCheckedChangedListener { + + private final static String TAG = org.briarproject.briar.android.account.DozeFragment.class.getName(); + + private DozeView dozeView; + private HuaweiView huaweiView; + private Button next; + private boolean secondAttempt = false; + + public static RestoreAccountDozeFragment newInstance() { + return new RestoreAccountDozeFragment(); + } + + @Override + public void injectFragment(ActivityComponent component) { + component.inject(this); + } + + @Override + public View onCreateView(LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + requireActivity().setTitle(getString(R.string.setup_doze_title)); + setHasOptionsMenu(false); + View v = inflater.inflate(R.layout.fragment_setup_doze, container, + false); + dozeView = v.findViewById(R.id.dozeView); + dozeView.setOnCheckedChangedListener(this); + huaweiView = v.findViewById(R.id.huaweiView); + huaweiView.setOnCheckedChangedListener(this); + next = v.findViewById(R.id.next); + ProgressBar progressBar = v.findViewById(R.id.progress); + + dozeView.setOnButtonClickListener(this::askForDozeWhitelisting); + next.setOnClickListener(this); + + viewModel.getIsCreatingAccount() + .observe(getViewLifecycleOwner(), isCreatingAccount -> { + if (isCreatingAccount) { + next.setVisibility(INVISIBLE); + progressBar.setVisibility(VISIBLE); + } + }); + + return v; + } + + @Override + public String getUniqueTag() { + return TAG; + } + + @Override + protected String getHelpText() { + return getString(R.string.setup_doze_explanation); + } + + @Override + public void onActivityResult(int request, int result, + @Nullable Intent data) { + super.onActivityResult(request, result, data); + if (request == REQUEST_DOZE_WHITELISTING) { + if (!dozeView.needsToBeShown() || secondAttempt) { + dozeView.setChecked(true); + } else if (getContext() != null) { + secondAttempt = true; + showOnboardingDialog(getContext(), getHelpText()); + } + } + } + + @Override + public void onCheckedChanged() { + next.setEnabled(dozeView.isChecked() && huaweiView.isChecked()); + } + + @SuppressLint("BatteryLife") + private void askForDozeWhitelisting() { + if (getContext() == null) return; + Intent i = UiUtils.getDozeWhitelistingIntent(getContext()); + startActivityForResult(i, REQUEST_DOZE_WHITELISTING); + } + + @Override + public void onClick(View view) { + viewModel.dozeExceptionConfirmed(); + } +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountViewModel.java index d7708b225..7f2b3c2f5 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/RestoreAccountViewModel.java @@ -3,7 +3,9 @@ package org.briarproject.briar.android.socialbackup.recover; import android.app.Application; import org.briarproject.bramble.api.account.AccountManager; +import org.briarproject.bramble.api.contact.ContactManager; import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator; +import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.identity.Identity; import org.briarproject.bramble.api.lifecycle.IoExecutor; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; @@ -42,6 +44,7 @@ class RestoreAccountViewModel extends AndroidViewModel { new MutableLiveData<>(false); private final AccountManager accountManager; + private final ContactManager contactManager; private final Executor ioExecutor; private final PasswordStrengthEstimator strengthEstimator; private final DozeHelper dozeHelper; @@ -50,12 +53,14 @@ class RestoreAccountViewModel extends AndroidViewModel { @Inject RestoreAccountViewModel(Application app, AccountManager accountManager, + ContactManager contactManager, RestoreAccount restoreAccount, @IoExecutor Executor ioExecutor, PasswordStrengthEstimator strengthEstimator, DozeHelper dozeHelper) { super(app); this.accountManager = accountManager; + this.contactManager = contactManager; this.ioExecutor = ioExecutor; this.strengthEstimator = strengthEstimator; this.dozeHelper = dozeHelper; @@ -78,11 +83,6 @@ class RestoreAccountViewModel extends AndroidViewModel { return isCreatingAccount; } -// void setAuthorName(String authorName) { -// this.authorName = authorName; -// state.setEvent(SET_PASSWORD); -// } - void setPassword(String password) { this.password = password; if (needToShowDozeFragment()) { @@ -105,7 +105,6 @@ class RestoreAccountViewModel extends AndroidViewModel { } private void createAccount() { -// if (authorName == null) throw new IllegalStateException(); if (password == null) throw new IllegalStateException(); isCreatingAccount.setValue(true); SocialBackup socialBackup = restoreAccount.getSocialBackup(); @@ -116,7 +115,20 @@ class RestoreAccountViewModel extends AndroidViewModel { Identity identity = socialBackup.getIdentity(); ioExecutor.execute(() -> { if (accountManager.restoreAccount(identity, password)) { - LOG.info("Restore account"); + LOG.info("Restored account"); + + try { + restoreAccount.addContactsToDb(); + } catch (InterruptedException e) { + LOG.warning("Process interrupted when waiting for db to open"); + state.postEvent(State.FAILED); + return; + } catch (DbException e) { + LOG.warning("DbException when adding contacts"); + state.postEvent(State.FAILED); + return; + } + LOG.info("Added recovered contacts to database"); state.postEvent(State.CREATED); } else { LOG.warning("Failed to create account");