Add explainer fragment for activating a remote wipe

This commit is contained in:
ameba23
2021-05-25 11:18:22 +02:00
parent 4d5bad13ca
commit 7eea532a81
8 changed files with 283 additions and 3 deletions

View File

@@ -69,6 +69,8 @@ import org.briarproject.briar.android.remotewipe.RemoteWipeDisplayFragment;
import org.briarproject.briar.android.remotewipe.RemoteWipeSetupActivity;
import org.briarproject.briar.android.remotewipe.RemoteWipeSuccessFragment;
import org.briarproject.briar.android.remotewipe.WiperSelectorFragment;
import org.briarproject.briar.android.remotewipe.activate.ActivateRemoteWipeActivity;
import org.briarproject.briar.android.remotewipe.activate.ActivateRemoteWipeExplainerFragment;
import org.briarproject.briar.android.reporting.CrashFragment;
import org.briarproject.briar.android.reporting.CrashReportActivity;
import org.briarproject.briar.android.reporting.ReportFormFragment;
@@ -221,6 +223,8 @@ public interface ActivityComponent {
void inject(RemoteWipeSetupActivity remoteWipeSetupActivity);
void inject(ActivateRemoteWipeActivity activateRemoteWipeActivity);
// Fragments
void inject(AuthorNameFragment fragment);
@@ -318,4 +322,6 @@ public interface ActivityComponent {
void inject(RemoteWipeDisplayFragment remoteWipeDisplayFragment);
void inject(RemoteWipeSuccessFragment remoteWipeSuccessFragment);
void inject(ActivateRemoteWipeExplainerFragment activateRemoteWipeExplainerFragment);
}

View File

@@ -1,4 +1,70 @@
package org.briarproject.briar.android.remotewipe.activate;
public class ActivateRemoteWipeActivity {
import android.content.Intent;
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 javax.inject.Inject;
import androidx.lifecycle.ViewModelProvider;
import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID;
public class ActivateRemoteWipeActivity extends BriarActivity {
@Inject
ViewModelProvider.Factory viewModelFactory;
ActivateRemoteWipeViewModel viewModel;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
viewModel = new ViewModelProvider(this, viewModelFactory)
.get(ActivateRemoteWipeViewModel.class);
viewModel.getState().observe(this, this::onStateChanged);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState == null) {
Intent intent = getIntent();
int id = intent.getIntExtra(CONTACT_ID, -1);
if (id == -1) throw new IllegalStateException("No ContactId");
ContactId contactId = new ContactId(id);
viewModel.setContactId(contactId);
showInitialFragment(new ActivateRemoteWipeExplainerFragment());
}
}
private void onStateChanged(ActivateRemoteWipeState state) {
switch(state) {
case FAILED:
Toast.makeText(this,
R.string.remote_wipe_activate_failure,
Toast.LENGTH_LONG).show();
break;
case SUCCESS:
// showNextFragment(new ActivateRemoteWipeSuccessFragment());
Toast.makeText(this,
R.string.remote_wipe_activate_success,
Toast.LENGTH_LONG).show();
finish();
break;
case FINISHED:
finish();
break;
case CANCELLED:
finish();
break;
}
}
}

View File

@@ -1,4 +1,56 @@
package org.briarproject.briar.android.remotewipe.activate;
public class ActivateRemoteWipeExplainerFragment {
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseFragment;
import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
public class ActivateRemoteWipeExplainerFragment extends
BaseFragment {
public static final String TAG =
ActivateRemoteWipeExplainerFragment.class.getName();
@Inject
ViewModelProvider.Factory viewModelFactory;
private ActivateRemoteWipeViewModel viewModel;
@Override
public void injectFragment(ActivityComponent component) {
component.inject(this);
viewModel = new ViewModelProvider(requireActivity(), viewModelFactory)
.get(ActivateRemoteWipeViewModel.class);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_activate_remote_wipe_explainer,
container, false);
Button cancelButton = view.findViewById(R.id.button_cancel);
cancelButton.setOnClickListener(e -> viewModel.onCancelClicked());
Button confirmButton = view.findViewById(R.id.button_confirm);
confirmButton.setOnClickListener(e -> viewModel.onConfirmClicked());
return view;
}
@Override
public String getUniqueTag() {
return TAG;
}
}

View File

@@ -0,0 +1,8 @@
package org.briarproject.briar.android.remotewipe.activate;
public enum ActivateRemoteWipeState {
FAILED,
SUCCESS,
FINISHED,
CANCELLED
}

View File

@@ -2,15 +2,68 @@ package org.briarproject.briar.android.remotewipe.activate;
import android.app.Application;
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.android.remotewipe.RemoteWipeSetupState;
import org.briarproject.briar.api.remotewipe.RemoteWipeManager;
import java.text.Normalizer;
import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.MutableLiveData;
public class ActivateRemoteWipeViewModel extends AndroidViewModel {
private final RemoteWipeManager remoteWipeManager;
private final DatabaseComponent db;
private final MutableLiveData<ActivateRemoteWipeState> state = new MutableLiveData<>();
private ContactId contactId;
@Inject
public ActivateRemoteWipeViewModel(
@NonNull Application application) {
@NonNull Application application,
RemoteWipeManager remoteWipeManager,
DatabaseComponent db) {
super(application);
this.remoteWipeManager = remoteWipeManager;
this.db = db;
}
private void activateWipe() {
try {
db.transaction(false, txn -> {
try {
remoteWipeManager.wipe(txn, db.getContact(txn, contactId));
} catch (DbException e) {
state.postValue(ActivateRemoteWipeState.FAILED);
} catch (FormatException e) {
state.postValue(ActivateRemoteWipeState.FAILED);
}
state.postValue(ActivateRemoteWipeState.SUCCESS);
});
} catch (DbException e) {
state.postValue(ActivateRemoteWipeState.FAILED);
}
}
public MutableLiveData<ActivateRemoteWipeState> getState() {
return state;
}
public void setContactId(ContactId c) {
contactId = c;
}
public void onCancelClicked() {
state.postValue(ActivateRemoteWipeState.CANCELLED);
}
public void onConfirmClicked() {
activateWipe();
}
}

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="409.2dp"
android:height="161.7dp"
android:viewportHeight="161.7"
android:viewportWidth="409.2">
<path
android:fillColor="#FF000000"
android:pathData="M369.8,157.4l-4.3,-4.3l-7.1,-2.4c-3.9,-1.3 -8.7,-3 -10.7,-3.7l-3.7,-1.3l3.5,-0.2c8.2,-0.4 13,-4 14.3,-10.9c0.8,-4.1 1.1,-17.3 0.8,-33c-0.2,-8.1 -0.2,-15.4 0,-16.3c0.1,-0.9 0.5,-2.4 0.9,-3.4c1.2,-3.5 0.3,-11.9 -1.9,-17.6c-0.3,-0.9 -1.9,-4.2 -3.5,-7.4c-4.2,-8.2 -4.5,-8.9 -4.9,-10.5c-0.5,-1.8 -0.2,-5.4 0.5,-6.8c0.7,-1.3 2.2,-2.9 3.2,-3.5c1.3,-0.7 2.6,0.1 4.7,2.9c3.4,4.5 14,19.4 15.7,22.2c3.7,6 6,11.2 8,18.8c0.7,2.5 1.9,7 2.7,10.1c0.8,3.1 2.7,10.2 4.1,15.8l2.6,10.2l4.6,5.2c2.6,2.9 5.8,6.5 7.2,8c1.4,1.6 2.5,3 2.5,3.2c0,0.3 -34.5,29.3 -34.9,29.3C374.2,161.7 372.2,159.7 369.8,157.4zM275.9,141c-1.3,-0.6 -2.2,-1.4 -2.9,-2.3c-2.1,-2.7 -2,2.4 -1.9,-68.5l0.1,-64l0.7,-1.2c1,-1.9 2,-2.9 3.7,-3.9l1.6,-0.9l37.8,-0.1c42.5,-0.1 39.4,-0.2 42.1,2.2c0.9,0.8 1.8,2 2.2,2.9c0.7,1.6 0.7,1.6 0.8,14.2l0.1,12.6l-1.8,-0.1c-1.4,-0.1 -2.1,0 -3.2,0.5c-2,1 -3.9,2.9 -5.1,5.1l-1,2l0,-12.8l0,-12.8h-33.6h-33.6v51.3v51.3h33.6h33.6l0.1,-34.4c0.1,-33 0.1,-34.4 0.6,-32.9c0.3,0.8 1.8,4 3.4,7c5.5,10.6 5.4,9.9 5.4,47.2c0,27.6 -0.1,30 -1.7,33.1c-1.1,2.2 -2.7,3.7 -5.1,4.7l-1.7,0.7L314,141.8l-36.2,0.1L275.9,141L275.9,141zM318.3,135.9c2.9,-1.3 4.5,-3.7 4.4,-6.6c0,-4.1 -3.1,-7.2 -7.1,-7.2c-2.1,0 -3.6,0.6 -5.2,2.2c-2.2,2.2 -2.8,5.4 -1.3,8.3c0.7,1.4 2.5,3 4,3.5C314.6,136.6 317,136.6 318.3,135.9z"/>
<path
android:fillColor="#FF000000"
android:pathData="M39.4,157.4l4.3,-4.3l7.1,-2.4c3.9,-1.3 8.7,-3 10.7,-3.7l3.7,-1.3l-3.5,-0.2c-8.2,-0.4 -13,-4 -14.3,-10.9c-0.8,-4.1 -1.1,-17.3 -0.8,-33c0.2,-8.1 0.2,-15.4 0,-16.3c-0.1,-0.9 -0.5,-2.4 -0.9,-3.4c-1.2,-3.5 -0.3,-11.9 1.9,-17.6c0.3,-0.9 1.9,-4.2 3.5,-7.4c4.2,-8.2 4.5,-8.9 4.9,-10.5c0.5,-1.8 0.2,-5.4 -0.5,-6.8c-0.7,-1.3 -2.2,-2.9 -3.2,-3.5c-1.3,-0.7 -2.6,0.1 -4.7,2.9c-3.4,4.5 -14,19.4 -15.7,22.2c-3.7,6 -6,11.2 -8,18.8c-0.7,2.5 -1.9,7 -2.7,10.1c-0.8,3.1 -2.7,10.2 -4.1,15.8l-2.6,10.2l-4.6,5.2c-2.6,2.9 -5.8,6.5 -7.2,8s-2.5,3 -2.5,3.2c0,0.3 34.5,29.3 34.9,29.3C35,161.7 37.1,159.7 39.4,157.4zM133.3,141c1.3,-0.6 2.2,-1.4 2.9,-2.3c2.1,-2.7 2,2.4 1.9,-68.5l-0.1,-64l-0.7,-1.2c-1,-1.9 -2,-2.9 -3.7,-3.9l-1.6,-0.9l-37.8,-0.1c-42.5,-0.1 -39.4,-0.2 -42.1,2.2c-0.9,0.8 -1.8,2 -2.2,2.9c-0.7,1.6 -0.7,1.6 -0.8,14.2L49,32l1.8,-0.1c1.4,-0.1 2.1,0 3.2,0.5c2,1 3.9,2.9 5.1,5.1l1,2l0,-12.8l0,-12.8h33.6h33.6v51.3v51.3L93.8,116.5L60.2,116.5l-0.1,-34.4c-0.1,-33 -0.1,-34.4 -0.6,-32.9c-0.3,0.8 -1.8,4 -3.4,7c-5.5,10.6 -5.4,9.9 -5.4,47.2c0,27.6 0.1,30 1.7,33.1c1.1,2.2 2.7,3.7 5.1,4.7l1.7,0.7l36.2,0.1l36.2,0.1L133.3,141L133.3,141zM90.9,135.9c-2.9,-1.3 -4.5,-3.7 -4.4,-6.6c0,-4.1 3.1,-7.2 7.1,-7.2c2.1,0 3.6,0.6 5.2,2.2c2.2,2.2 2.8,5.4 1.3,8.3c-0.7,1.4 -2.5,3 -4,3.5C94.6,136.6 92.3,136.6 90.9,135.9z"/>
<path
android:fillColor="#000000"
android:pathData="M 207.61295,88.782357 h -6.42588 v -12.85177 h 6.42588 m 0,25.703533 h -6.42588 v -6.425883 h 6.42588 m -38.5553,16.064713 h 70.68472 L 204.40001,50.227047 Z"
android:strokeWidth="3.21294165"/>
</vector>

View File

@@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/margin_large"
android:paddingTop="@dimen/margin_medium"
android:paddingRight="@dimen/margin_large"
android:paddingBottom="@dimen/margin_medium"
tools:ignore="VectorDrawableCompat">
<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center"
android:text="@string/remote_wipe_activate_explain_short"
android:textSize="24sp"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="16dp" />
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
app:srcCompat="@drawable/remote_wipe_activate_explain" />
<TextView
android:id="@+id/textViewExplain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:gravity="center"
android:text="@string/remote_wipe_activate_explain_long"
android:textSize="20sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/imageView"
tools:layout_editor_absoluteX="16dp" />
<Button
android:id="@+id/button_confirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/remote_wipe_activate_button_confirm"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textViewExplain" />
<Button
android:id="@+id/button_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/remote_wipe_activate_button_cancel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button_confirm" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -750,4 +750,12 @@
<string name="assigned_wipers">Your assigned trusted wipers</string>
<string name="activate_remote_wipe">Activate remote wipe</string>
<!-- activate -->
<string name="remote_wipe_activate_success">Remote wipe signal sent</string>
<string name="remote_wipe_activate_failure">Failed to send remote wipe signal</string>
<string name="remote_wipe_activate_button_confirm">Activate remote wipe</string>
<string name="remote_wipe_activate_button_cancel">Cancel</string>
<string name="remote_wipe_activate_explain_short">Activate a remote wipe of this contact\'s device</string>
<string name="remote_wipe_activate_explain_long">If confirmed by a second contact, sending this signal will remove all briar contacts and messages from this contact\s device.\n\nAre you sure you want to do this?</string>
</resources>