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 089038184..d8a88e482 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 @@ -65,6 +65,8 @@ import org.briarproject.briar.android.privategroup.memberlist.GroupMemberModule; import org.briarproject.briar.android.privategroup.reveal.GroupRevealModule; import org.briarproject.briar.android.privategroup.reveal.RevealContactsActivity; import org.briarproject.briar.android.privategroup.reveal.RevealContactsFragment; +import org.briarproject.briar.android.remotewipe.RemoteWipeSetupActivity; +import org.briarproject.briar.android.remotewipe.WiperSelectorFragment; import org.briarproject.briar.android.reporting.CrashFragment; import org.briarproject.briar.android.reporting.CrashReportActivity; import org.briarproject.briar.android.reporting.ReportFormFragment; @@ -215,6 +217,8 @@ public interface ActivityComponent { void inject(RestoreAccountActivity restoreAccountActivity); + void inject(RemoteWipeSetupActivity remoteWipeSetupActivity); + // Fragments void inject(AuthorNameFragment fragment); @@ -306,4 +310,6 @@ public interface ActivityComponent { void inject(OwnerRecoveryModeErrorFragment ownerRecoveryModeErrorFragment); void inject(CustodianReturnShardErrorFragment custodianReturnShardErrorFragment); + + void inject(WiperSelectorFragment wiperSelectorFragment); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/remotewipe/RemoteWipeSetupActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/remotewipe/RemoteWipeSetupActivity.java new file mode 100644 index 000000000..b7b2e4112 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/remotewipe/RemoteWipeSetupActivity.java @@ -0,0 +1,60 @@ +package org.briarproject.briar.android.remotewipe; + +import android.os.Bundle; +import android.widget.Toast; + +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.activity.BriarActivity; +import org.briarproject.briar.android.contactselection.ContactSelectorListener; +import org.briarproject.briar.android.fragment.BaseFragment; +import org.briarproject.briar.android.socialbackup.ThresholdSelectorFragment; + +import java.util.Collection; + +import javax.inject.Inject; + +import androidx.lifecycle.ViewModelProvider; + +public class RemoteWipeSetupActivity extends BriarActivity implements + BaseFragment.BaseFragmentListener, ContactSelectorListener { + + @Inject + ViewModelProvider.Factory viewModelFactory; + RemoteWipeSetupViewModel viewModel; + + @Override + public void injectActivity(ActivityComponent component) { + component.inject(this); + + viewModel = new ViewModelProvider(this, viewModelFactory) + .get(RemoteWipeSetupViewModel.class); + +// viewModel.getState().observeEvent(this, this::onStateChanged); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_distributed_backup); + if (viewModel.remoteWipeIsSetup()) { +// showInitialFragment(); + } else { + showInitialFragment(WiperSelectorFragment.newInstance()); + } + } + + @Override + public void contactsSelected(Collection contacts) { + Toast.makeText(this, + String.format("Selected %d contacts", contacts.size()), + Toast.LENGTH_SHORT).show(); + try { + viewModel.setupRemoteWipe(contacts); + } catch (Exception e) { + // Display error fragment + } + } + +} diff --git a/briar-android/src/main/java/org/briarproject/briar/android/remotewipe/RemoteWipeSetupViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/remotewipe/RemoteWipeSetupViewModel.java new file mode 100644 index 000000000..a842289e0 --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/remotewipe/RemoteWipeSetupViewModel.java @@ -0,0 +1,50 @@ +package org.briarproject.briar.android.remotewipe; + +import android.app.Application; +import android.provider.ContactsContract; + +import org.briarproject.bramble.api.FormatException; +import org.briarproject.bramble.api.contact.ContactId; +import org.briarproject.bramble.api.db.DatabaseComponent; +import org.briarproject.bramble.api.db.DbException; +import org.briarproject.briar.api.remotewipe.RemoteWipeManager; + +import java.util.Collection; +import java.util.List; + +import javax.inject.Inject; + +import androidx.annotation.NonNull; +import androidx.lifecycle.AndroidViewModel; + +public class RemoteWipeSetupViewModel extends AndroidViewModel { + private final RemoteWipeManager remoteWipeManager; + private final DatabaseComponent db; + + @Inject + RemoteWipeSetupViewModel( + @NonNull Application application, + RemoteWipeManager remoteWipeManager, + DatabaseComponent db) { + super(application); + this.remoteWipeManager = remoteWipeManager; + this.db = db; + } + + public boolean remoteWipeIsSetup() { + try { + return db.transactionWithResult(true, + txn -> remoteWipeManager.remoteWipeIsSetup(txn)); + } catch (DbException e) { + return false; + } + } + + public void setupRemoteWipe(Collection wipers) + throws DbException, FormatException { + db.transaction(false, txn -> { + remoteWipeManager.setup(txn, (List) wipers); + }); + } +} + diff --git a/briar-android/src/main/java/org/briarproject/briar/android/remotewipe/WiperSelectorFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/remotewipe/WiperSelectorFragment.java new file mode 100644 index 000000000..fd93a37cc --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/remotewipe/WiperSelectorFragment.java @@ -0,0 +1,86 @@ +package org.briarproject.briar.android.remotewipe; + +import android.os.Bundle; +import android.view.MenuItem; +import android.widget.Toast; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; +import org.briarproject.briar.android.contactselection.BaseContactSelectorAdapter; +import org.briarproject.briar.android.contactselection.ContactSelectorController; +import org.briarproject.briar.android.contactselection.ContactSelectorFragment; +import org.briarproject.briar.android.contactselection.SelectableContactItem; +import org.briarproject.briar.android.socialbackup.creation.CreateBackupController; + +import javax.inject.Inject; + +import androidx.annotation.Nullable; + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class WiperSelectorFragment extends ContactSelectorFragment { + + public static final String TAG = WiperSelectorFragment.class.getName(); + + @Inject + CreateBackupController controller; + + public static WiperSelectorFragment newInstance() { + Bundle args = new Bundle(); + + WiperSelectorFragment + fragment = new WiperSelectorFragment(); + fragment.setArguments(args); + + return fragment; + } + + @Override + public void injectFragment(ActivityComponent component) { + component.inject(this); + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + requireActivity().setTitle(R.string.title_select_wipers); + } + + @Override + protected ContactSelectorController getController() { + return controller; + } + + @Override + public String getUniqueTag() { + return TAG; + } + + @Override + protected void onSelectionChanged() { + super.onSelectionChanged(); + if (menu == null) return; + MenuItem item = menu.findItem(R.id.action_contacts_selected); + if (item == null) return; + + BaseContactSelectorAdapter a = adapter; + selectedContacts = a.getSelectedContactIds(); + + int n = selectedContacts.size(); + int min = 2; + boolean enough = n >= min; + + item.setVisible(enough); + if (n == 0) { + Toast.makeText(getContext(), String.format(getString(R.string.select_at_least_n_contacts), min), + Toast.LENGTH_SHORT).show(); + } else if (n < min) { + Toast.makeText(getContext(), String.format(getString(R.string.select_at_least_n_more_contacts), min - n), + Toast.LENGTH_SHORT).show(); + } + } + +} diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index dbd7d62a2..b7342fb24 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -732,6 +732,9 @@ + + Select Trusted Contacts + You have been added a remote wiper. You have added this contact as a remote wiper.