mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 21:59:54 +01:00
only display custodian help recover explainer screen if you are a custodian
This commit is contained in:
@@ -1,11 +1,22 @@
|
|||||||
package org.briarproject.briar.android.socialbackup;
|
package org.briarproject.briar.android.socialbackup;
|
||||||
|
|
||||||
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
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.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
|
import org.briarproject.briar.api.socialbackup.BackupMetadata;
|
||||||
|
import org.briarproject.briar.api.socialbackup.SocialBackupManager;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static org.briarproject.briar.android.conversation.ConversationActivity.CONTACT_ID;
|
||||||
|
|
||||||
public class CustodianHelpRecoverActivity extends BriarActivity implements
|
public class CustodianHelpRecoverActivity extends BriarActivity implements
|
||||||
BaseFragment.BaseFragmentListener, CustodianScanQrButtonListener {
|
BaseFragment.BaseFragmentListener, CustodianScanQrButtonListener {
|
||||||
@@ -14,15 +25,39 @@ public class CustodianHelpRecoverActivity extends BriarActivity implements
|
|||||||
component.inject(this);
|
component.inject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public SocialBackupManager socialBackupManager;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public DatabaseComponent db;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_recover); // TODO change this
|
setContentView(R.layout.activity_recover); // TODO change this
|
||||||
// TODO check if we have a shard for this secret owner
|
|
||||||
// if not we should not even display the menu item
|
Intent intent = getIntent();
|
||||||
CustodianRecoveryModeExplainerFragment fragment =
|
int id = intent.getIntExtra(CONTACT_ID, -1);
|
||||||
new CustodianRecoveryModeExplainerFragment();
|
if (id == -1) throw new IllegalStateException("No ContactId");
|
||||||
showInitialFragment(fragment);
|
ContactId contactId = new ContactId(id);
|
||||||
|
|
||||||
|
// check if we have a shard for this secret owner
|
||||||
|
try {
|
||||||
|
db.transaction(false, txn -> {
|
||||||
|
if (!socialBackupManager.amCustodian(txn, contactId)) {
|
||||||
|
throw new DbException();
|
||||||
|
}
|
||||||
|
CustodianRecoveryModeExplainerFragment fragment =
|
||||||
|
new CustodianRecoveryModeExplainerFragment();
|
||||||
|
showInitialFragment(fragment);
|
||||||
|
});
|
||||||
|
} catch (DbException e) {
|
||||||
|
// TODO improve this
|
||||||
|
Toast.makeText(this,
|
||||||
|
"You do not hold a backup shard from this contact",
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -8,162 +8,165 @@ import android.view.MenuInflater;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.SeekBar;
|
import android.widget.SeekBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.contactselection.ContactSelectorListener;
|
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
import org.magmacollective.darkcrystal.secretsharingwrapper.SecretSharingWrapper;
|
import org.magmacollective.darkcrystal.secretsharingwrapper.SecretSharingWrapper;
|
||||||
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
public class ThresholdSelectorFragment extends BaseFragment {
|
public class ThresholdSelectorFragment extends BaseFragment {
|
||||||
|
|
||||||
public static final String TAG = ThresholdSelectorFragment.class.getName();
|
public static final String TAG = ThresholdSelectorFragment.class.getName();
|
||||||
private static final String NUMBER_CUSTODIANS = "numberCustodians";
|
private static final String NUMBER_CUSTODIANS = "numberCustodians";
|
||||||
|
|
||||||
protected ThresholdDefinedListener listener;
|
protected ThresholdDefinedListener listener;
|
||||||
|
|
||||||
// TODO this should be the actual number of custodians
|
// TODO this should be the actual number of custodians
|
||||||
private int numberOfCustodians;
|
private int numberOfCustodians;
|
||||||
private int threshold;
|
private int threshold;
|
||||||
private int recommendedThreshold;
|
private int recommendedThreshold;
|
||||||
private SeekBar seekBar;
|
private SeekBar seekBar;
|
||||||
private TextView thresholdRepresentation;
|
private TextView thresholdRepresentation;
|
||||||
private TextView message;
|
private TextView message;
|
||||||
private TextView mOfn;
|
private TextView mOfn;
|
||||||
|
|
||||||
public static ThresholdSelectorFragment newInstance(int numberCustodians) {
|
public static ThresholdSelectorFragment newInstance(int numberCustodians) {
|
||||||
Bundle bundle = new Bundle();
|
Bundle bundle = new Bundle();
|
||||||
bundle.putInt(NUMBER_CUSTODIANS, numberCustodians);
|
bundle.putInt(NUMBER_CUSTODIANS, numberCustodians);
|
||||||
ThresholdSelectorFragment fragment = new ThresholdSelectorFragment();
|
ThresholdSelectorFragment fragment = new ThresholdSelectorFragment();
|
||||||
fragment.setArguments(bundle);
|
fragment.setArguments(bundle);
|
||||||
return fragment;
|
return fragment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
requireActivity().setTitle(R.string.title_define_threshold);
|
requireActivity().setTitle(R.string.title_define_threshold);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||||
View view = inflater.inflate(R.layout.fragment_select_threshold,
|
@Nullable ViewGroup container,
|
||||||
container, false);
|
@Nullable Bundle savedInstanceState) {
|
||||||
Bundle args = requireArguments();
|
View view = inflater.inflate(R.layout.fragment_select_threshold,
|
||||||
numberOfCustodians = args.getInt(NUMBER_CUSTODIANS);
|
container, false);
|
||||||
|
Bundle args = requireArguments();
|
||||||
|
numberOfCustodians = args.getInt(NUMBER_CUSTODIANS);
|
||||||
|
|
||||||
seekBar = view.findViewById(R.id.seekBar);
|
seekBar = view.findViewById(R.id.seekBar);
|
||||||
thresholdRepresentation = view.findViewById(R.id.textViewThresholdRepresentation);
|
thresholdRepresentation =
|
||||||
message = view.findViewById(R.id.textViewMessage);
|
view.findViewById(R.id.textViewThresholdRepresentation);
|
||||||
mOfn = view.findViewById(R.id.textViewmOfn);
|
message = view.findViewById(R.id.textViewMessage);
|
||||||
int max = numberOfCustodians - 3;
|
mOfn = view.findViewById(R.id.textViewmOfn);
|
||||||
seekBar.setMax(max);
|
int max = numberOfCustodians - 3;
|
||||||
seekBar.setOnSeekBarChangeListener(new SeekBarListener());
|
seekBar.setMax(max);
|
||||||
recommendedThreshold = SecretSharingWrapper.defaultThreshold(numberOfCustodians);
|
seekBar.setOnSeekBarChangeListener(new SeekBarListener());
|
||||||
threshold = recommendedThreshold;
|
recommendedThreshold =
|
||||||
seekBar.setProgress(threshold - 2);
|
SecretSharingWrapper.defaultThreshold(numberOfCustodians);
|
||||||
|
threshold = recommendedThreshold;
|
||||||
|
seekBar.setProgress(threshold - 2);
|
||||||
|
|
||||||
thresholdRepresentation.setText(buildThresholdRepresentationString());
|
thresholdRepresentation.setText(buildThresholdRepresentationString());
|
||||||
setmOfnText();
|
setmOfnText();
|
||||||
return view;
|
return view;
|
||||||
// return super.onCreateView(inflater, container, savedInstanceState);
|
// return super.onCreateView(inflater, container, savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setmOfnText() {
|
private void setmOfnText() {
|
||||||
mOfn.setText(String.format("%d of %d contacts needed to recover your account", threshold, numberOfCustodians));
|
mOfn.setText(String.format(
|
||||||
}
|
"%d of %d contacts needed to recover your account", threshold,
|
||||||
|
numberOfCustodians));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
listener = (ThresholdDefinedListener) context;
|
listener = (ThresholdDefinedListener) context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUniqueTag() {
|
public String getUniqueTag() {
|
||||||
return TAG;
|
return TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectFragment(ActivityComponent component) {
|
public void injectFragment(ActivityComponent component) {
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||||
inflater.inflate(R.menu.define_threshold_actions, menu);
|
inflater.inflate(R.menu.define_threshold_actions, menu);
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
super.onCreateOptionsMenu(menu, inflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
case R.id.action_threshold_defined:
|
case R.id.action_threshold_defined:
|
||||||
try {
|
try {
|
||||||
listener.thresholdDefined(threshold);
|
listener.thresholdDefined(threshold);
|
||||||
} catch (DbException e) {
|
} catch (DbException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
return super.onOptionsItemSelected(item);
|
return super.onOptionsItemSelected(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String buildThresholdRepresentationString () {
|
private String buildThresholdRepresentationString() {
|
||||||
String thresholdRepresentationText = "";
|
String thresholdRepresentationText = "";
|
||||||
for (int i = 0; i < threshold; i++) {
|
for (int i = 0; i < threshold; i++) {
|
||||||
thresholdRepresentationText += getString(R.string.filled_bullet);
|
thresholdRepresentationText += getString(R.string.filled_bullet);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < (numberOfCustodians - threshold); i++) {
|
for (int i = 0; i < (numberOfCustodians - threshold); i++) {
|
||||||
thresholdRepresentationText += getString(R.string.linear_bullet);
|
thresholdRepresentationText += getString(R.string.linear_bullet);
|
||||||
}
|
}
|
||||||
return thresholdRepresentationText;
|
return thresholdRepresentationText;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SeekBarListener implements SeekBar.OnSeekBarChangeListener {
|
private class SeekBarListener implements SeekBar.OnSeekBarChangeListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProgressChanged(SeekBar seekBar, int progress,
|
public void onProgressChanged(SeekBar seekBar, int progress,
|
||||||
boolean fromUser) {
|
boolean fromUser) {
|
||||||
threshold = progress + 2;
|
threshold = progress + 2;
|
||||||
|
|
||||||
thresholdRepresentation.setText(
|
thresholdRepresentation.setText(
|
||||||
buildThresholdRepresentationString()
|
buildThresholdRepresentationString()
|
||||||
);
|
);
|
||||||
setmOfnText();
|
setmOfnText();
|
||||||
|
|
||||||
int sanityLevel = SecretSharingWrapper.thresholdSanity(threshold, numberOfCustodians);
|
int sanityLevel = SecretSharingWrapper
|
||||||
int text = R.string.threshold_secure;
|
.thresholdSanity(threshold, numberOfCustodians);
|
||||||
if (threshold == recommendedThreshold) text = R.string.threshold_recommended;
|
int text = R.string.threshold_secure;
|
||||||
if (sanityLevel < -1) text = R.string.threshold_low_insecure;
|
if (threshold == recommendedThreshold)
|
||||||
if (sanityLevel > 0) text = R.string.threshold_high_insecure;
|
text = R.string.threshold_recommended;
|
||||||
message.setText(text);
|
if (sanityLevel < -1) text = R.string.threshold_low_insecure;
|
||||||
// TODO change colour of thresholdRepresentation to green/red based on sanityLevel
|
if (sanityLevel > 0) text = R.string.threshold_high_insecure;
|
||||||
}
|
message.setText(text);
|
||||||
|
// TODO change colour of thresholdRepresentation to green/red based on sanityLevel
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user