Add revoke remote wipe status option to conversation actions menu

This commit is contained in:
ameba23
2021-08-31 12:39:52 +02:00
parent 25029e1fca
commit 6e67c1dfbf
12 changed files with 270 additions and 2 deletions

View File

@@ -499,6 +499,15 @@
android:value="org.briarproject.briar.android.conversation.ConversationActivity" />
</activity>
<activity
android:name="org.briarproject.briar.android.remotewipe.revoke.RevokeRemoteWipeActivity"
android:label="@string/activity_name_revoke_remote_wipe"
android:parentActivityName="org.briarproject.briar.android.conversation.ConversationActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="org.briarproject.briar.android.conversation.ConversationActivity" />
</activity>
<activity
android:name="org.briarproject.briar.android.logout.ExitActivity"
android:theme="@android:style/Theme.NoDisplay" />

View File

@@ -73,6 +73,9 @@ 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.remotewipe.activate.ActivateRemoteWipeSuccessFragment;
import org.briarproject.briar.android.remotewipe.revoke.RevokeRemoteWipeActivity;
import org.briarproject.briar.android.remotewipe.revoke.RevokeRemoteWipeState;
import org.briarproject.briar.android.remotewipe.revoke.RevokeRemoteWipeSuccessFragment;
import org.briarproject.briar.android.reporting.CrashFragment;
import org.briarproject.briar.android.reporting.CrashReportActivity;
import org.briarproject.briar.android.reporting.ReportFormFragment;
@@ -229,6 +232,8 @@ public interface ActivityComponent {
void inject(RemoteWipeActivatedActivity remoteWipeActivatedActivity);
void inject(RevokeRemoteWipeActivity revokeRemoteWipeActivity);
// Fragments
void inject(AuthorNameFragment fragment);
@@ -330,4 +335,6 @@ public interface ActivityComponent {
void inject(ActivateRemoteWipeExplainerFragment activateRemoteWipeExplainerFragment);
void inject(ActivateRemoteWipeSuccessFragment activateRemoteWipeSuccessFragment);
void inject(RevokeRemoteWipeSuccessFragment revokeRemoteWipeSuccessFragment);
}

View File

@@ -53,6 +53,7 @@ import org.briarproject.briar.android.forum.ForumActivity;
import org.briarproject.briar.android.introduction.IntroductionActivity;
import org.briarproject.briar.android.privategroup.conversation.GroupActivity;
import org.briarproject.briar.android.remotewipe.activate.ActivateRemoteWipeActivity;
import org.briarproject.briar.android.remotewipe.revoke.RevokeRemoteWipeActivity;
import org.briarproject.briar.android.socialbackup.recover.CustodianReturnShardActivity;
import org.briarproject.briar.android.util.BriarSnackbarBuilder;
import org.briarproject.briar.android.view.BriarRecyclerView;
@@ -379,6 +380,13 @@ public class ConversationActivity extends BriarActivity
}
});
// enable revoke remote wipe action if available
observeOnce(viewModel.isRemoteWiper(), this, isWiper -> {
if (isWiper != null && isWiper) {
menu.findItem(R.id.action_revoke_remote_wipe).setEnabled(true);
}
});
return super.onCreateOptionsMenu(menu);
}
@@ -417,6 +425,12 @@ public class ConversationActivity extends BriarActivity
r.putExtra(CONTACT_ID, contactId.getInt());
startActivity(r);
return true;
case R.id.action_revoke_remote_wipe:
if (contactId == null) return false;
Intent s = new Intent(this, RevokeRemoteWipeActivity.class);
s.putExtra(CONTACT_ID, contactId.getInt());
startActivity(s);
return true;
default:
return super.onOptionsItemSelected(item);
}

View File

@@ -107,6 +107,7 @@ public class ConversationViewModel extends DbViewModel
private final MutableLiveEvent<PrivateMessageHeader> addedHeader =
new MutableLiveEvent<>();
private final MutableLiveData<Boolean> amRemoteWiper = new MutableLiveData<>();
private final MutableLiveData<Boolean> isRemoteWiper = new MutableLiveData<>();
@Inject
ConversationViewModel(Application application,
@@ -306,6 +307,10 @@ public class ConversationViewModel extends DbViewModel
boolean amWiper = db.transactionWithResult(true,
txn -> remoteWipeManager.amWiper(txn, c));
amRemoteWiper.postValue(amWiper);
boolean isWiper = db.transactionWithResult(true,
txn -> remoteWipeManager.isWiper(txn, c));
isRemoteWiper.postValue(isWiper);
}
@DatabaseExecutor
@@ -395,6 +400,10 @@ public class ConversationViewModel extends DbViewModel
return amRemoteWiper;
}
LiveData<Boolean> isRemoteWiper() {
return isRemoteWiper;
}
@UiThread
void recheckFeaturesAndOnboarding(ContactId contactId) {
runOnDbThread(() -> {

View File

@@ -9,6 +9,7 @@ import android.widget.Button;
import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.fragment.BaseFragment;
import org.briarproject.briar.android.remotewipe.revoke.RevokeRemoteWipeViewModel;
import javax.inject.Inject;
@@ -24,13 +25,13 @@ public class ActivateRemoteWipeSuccessFragment extends BaseFragment {
@Inject
ViewModelProvider.Factory viewModelFactory;
private ActivateRemoteWipeViewModel viewModel;
private RevokeRemoteWipeViewModel viewModel;
@Override
public void injectFragment(ActivityComponent component) {
component.inject(this);
viewModel = new ViewModelProvider(requireActivity(), viewModelFactory)
.get(ActivateRemoteWipeViewModel.class);
.get(RevokeRemoteWipeViewModel.class);
}
@Nullable
@@ -38,6 +39,7 @@ public class ActivateRemoteWipeSuccessFragment extends BaseFragment {
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
// TODO change layout
View view = inflater.inflate(R.layout.fragment_activate_remote_wipe_success,
container, false);

View File

@@ -0,0 +1,67 @@
package org.briarproject.briar.android.remotewipe.revoke;
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 org.briarproject.briar.android.fragment.BaseFragment;
import javax.inject.Inject;
import androidx.lifecycle.ViewModelProvider;
import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID;
public class RevokeRemoteWipeActivity extends BriarActivity implements
BaseFragment.BaseFragmentListener {
@Inject
ViewModelProvider.Factory viewModelFactory;
RevokeRemoteWipeViewModel viewModel;
@Override
public void injectActivity(ActivityComponent component) {
component.inject(this);
viewModel = new ViewModelProvider(this, viewModelFactory)
.get(RevokeRemoteWipeViewModel.class);
viewModel.getState().observe(this, this::onStateChanged);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_distributed_backup);
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.revokeRemoteWipeStatus(contactId);
// showInitialFragment(new ActivateRemoteWipeExplainerFragment());
}
}
private void onStateChanged(RevokeRemoteWipeState state) {
switch(state) {
case FAILED:
// TODO change text
Toast.makeText(this,
R.string.remote_wipe_activate_failure,
Toast.LENGTH_LONG).show();
break;
case SUCCESS:
showNextFragment(new RevokeRemoteWipeSuccessFragment());
break;
default: // FINISHED or CANCELLED
finish();
break;
}
}
}

View File

@@ -0,0 +1,7 @@
package org.briarproject.briar.android.remotewipe.revoke;
public enum RevokeRemoteWipeState {
FAILED,
SUCCESS,
FINISHED
}

View File

@@ -0,0 +1,55 @@
package org.briarproject.briar.android.remotewipe.revoke;
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 org.briarproject.briar.android.remotewipe.activate.ActivateRemoteWipeSuccessFragment;
import org.briarproject.briar.android.remotewipe.activate.ActivateRemoteWipeViewModel;
import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.ViewModelProvider;
public class RevokeRemoteWipeSuccessFragment extends BaseFragment {
public static final String TAG =
ActivateRemoteWipeSuccessFragment.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_success,
container, false);
Button button = view.findViewById(R.id.button);
button.setOnClickListener(e -> viewModel.onSuccessDismissed());
return view;
}
@Override
public String getUniqueTag() {
return TAG;
}
}

View File

@@ -0,0 +1,60 @@
package org.briarproject.briar.android.remotewipe.revoke;
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.activate.ActivateRemoteWipeState;
import org.briarproject.briar.api.remotewipe.RemoteWipeManager;
import javax.inject.Inject;
import androidx.annotation.NonNull;
import androidx.lifecycle.AndroidViewModel;
import androidx.lifecycle.MutableLiveData;
public class RevokeRemoteWipeViewModel extends AndroidViewModel {
private final RemoteWipeManager remoteWipeManager;
private final DatabaseComponent db;
private final MutableLiveData<RevokeRemoteWipeState> state = new MutableLiveData<>();
private ContactId contactId;
@Inject
public RevokeRemoteWipeViewModel(
@NonNull Application application,
RemoteWipeManager remoteWipeManager,
DatabaseComponent db) {
super(application);
this.remoteWipeManager = remoteWipeManager;
this.db = db;
}
public MutableLiveData<RevokeRemoteWipeState> getState() {
return state;
}
public void revokeRemoteWipeStatus(ContactId c) {
contactId = c;
try {
db.transaction(false, txn -> {
remoteWipeManager.revoke(txn, contactId);
});
} catch (DbException e) {
state.postValue(RevokeRemoteWipeState.FAILED);
} catch (FormatException e) {
state.postValue(RevokeRemoteWipeState.FAILED);
}
state.postValue(RevokeRemoteWipeState.SUCCESS);
}
public void onCancelClicked() {
// state.postValue(ActivateRemoteWipeState.CANCELLED);
}
public void onSuccessDismissed() {
state.postValue(RevokeRemoteWipeState.FINISHED);
}
}

View File

@@ -0,0 +1,27 @@
package org.briarproject.briar.android.socialbackup;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.briarproject.briar.R;
import org.briarproject.briar.android.contact.BaseContactListAdapter;
import org.briarproject.briar.android.contact.ContactItem;
import org.briarproject.briar.android.contact.ContactItemViewHolder;
public class CustodianStatusAdapter extends BaseContactListAdapter<ContactItem, ContactItemViewHolder<ContactItem>> {
CustodianStatusAdapter(Context context) {
super(context, ContactItem.class, null);
}
@Override
public ContactItemViewHolder<ContactItem> onCreateViewHolder(
ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(
R.layout.list_item_contact_small, viewGroup, false);
return new ContactItemViewHolder<>(v);
}
}

View File

@@ -39,4 +39,11 @@
android:title="@string/activate_remote_wipe"
android:enabled="false"
app:showAsAction="never"/>
<item
android:id="@+id/action_revoke_remote_wipe"
android:icon="@drawable/action_delete_white"
android:title="@string/revoke_remote_wipe"
android:enabled="false"
app:showAsAction="never"/>
</menu>

View File

@@ -760,5 +760,9 @@
<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.</string>
<!-- revoke -->
<string name="activity_name_revoke_remote_wipe">Revoke Remote Wipe</string>
<string name="revoke_remote_wipe">Revoke remote wipe status</string>
<string name="button_confirm">Ok</string>
</resources>