mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-16 12:49:55 +01:00
Secret owner return shard - activity, view model and fragment - qr code generation
This commit is contained in:
@@ -88,6 +88,7 @@ import org.briarproject.briar.android.socialbackup.ExistingBackupFragment;
|
|||||||
import org.briarproject.briar.android.socialbackup.recover.CustodianReturnShardActivity;
|
import org.briarproject.briar.android.socialbackup.recover.CustodianReturnShardActivity;
|
||||||
import org.briarproject.briar.android.socialbackup.recover.CustodianReturnShardFragment;
|
import org.briarproject.briar.android.socialbackup.recover.CustodianReturnShardFragment;
|
||||||
import org.briarproject.briar.android.socialbackup.recover.OwnerRecoveryModeExplainerFragment;
|
import org.briarproject.briar.android.socialbackup.recover.OwnerRecoveryModeExplainerFragment;
|
||||||
|
import org.briarproject.briar.android.socialbackup.recover.OwnerReturnShardActivity;
|
||||||
import org.briarproject.briar.android.socialbackup.recover.OwnerReturnShardFragment;
|
import org.briarproject.briar.android.socialbackup.recover.OwnerReturnShardFragment;
|
||||||
import org.briarproject.briar.android.socialbackup.recover.RecoverActivity;
|
import org.briarproject.briar.android.socialbackup.recover.RecoverActivity;
|
||||||
import org.briarproject.briar.android.socialbackup.ShardsSentFragment;
|
import org.briarproject.briar.android.socialbackup.ShardsSentFragment;
|
||||||
@@ -205,7 +206,9 @@ public interface ActivityComponent {
|
|||||||
|
|
||||||
void inject(ReturnShardActivity returnShardActivity);
|
void inject(ReturnShardActivity returnShardActivity);
|
||||||
|
|
||||||
void inject(CustodianReturnShardActivity custodianSendShardActivity);
|
void inject(CustodianReturnShardActivity custodianReturnShardActivity);
|
||||||
|
|
||||||
|
void inject(OwnerReturnShardActivity ownerReturnShardActivity);
|
||||||
|
|
||||||
// Fragments
|
// Fragments
|
||||||
|
|
||||||
|
|||||||
@@ -12,15 +12,13 @@ import org.briarproject.briar.android.activity.ActivityComponent;
|
|||||||
import org.briarproject.briar.android.activity.BaseActivity;
|
import org.briarproject.briar.android.activity.BaseActivity;
|
||||||
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactErrorFragment;
|
import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactErrorFragment;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
import org.briarproject.briar.android.util.RequestBluetoothDiscoverable;
|
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
@@ -87,8 +85,8 @@ public class OwnerReturnShardActivity extends BaseActivity
|
|||||||
viewModel.getShowQrCodeFragment().observeEvent(this, show -> {
|
viewModel.getShowQrCodeFragment().observeEvent(this, show -> {
|
||||||
if (show) showQrCodeFragment();
|
if (show) showQrCodeFragment();
|
||||||
});
|
});
|
||||||
// viewModel.getState()
|
viewModel.getState()
|
||||||
// .observe(this, this::onReturnShardStateChanged);
|
.observe(this, this::onReturnShardStateChanged);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -120,9 +118,9 @@ public class OwnerReturnShardActivity extends BaseActivity
|
|||||||
@Override
|
@Override
|
||||||
public void onBackPressed() {
|
public void onBackPressed() {
|
||||||
if (viewModel.getState()
|
if (viewModel.getState()
|
||||||
.getValue() instanceof ReturnShardState.Failed) {
|
.getValue() instanceof SecretOwnerTask.State.Failure) {
|
||||||
// re-create this activity when going back in failed state
|
// re-create this activity when going back in failed state
|
||||||
Intent i = new Intent(this, ReturnShardActivity.class);
|
Intent i = new Intent(this, OwnerReturnShardActivity.class);
|
||||||
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
|
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP);
|
||||||
startActivity(i);
|
startActivity(i);
|
||||||
} else {
|
} else {
|
||||||
@@ -141,16 +139,16 @@ public class OwnerReturnShardActivity extends BaseActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onReturnShardStateChanged(ReturnShardState state) {
|
private void onReturnShardStateChanged(SecretOwnerTask.State state) {
|
||||||
if (state instanceof ReturnShardState.SocialBackupExchangeFinished) {
|
// if (state instanceof ReturnShardState.SocialBackupExchangeFinished) {
|
||||||
ReturnShardState.SocialBackupExchangeResult result =
|
// ReturnShardState.SocialBackupExchangeResult result =
|
||||||
((ReturnShardState.SocialBackupExchangeFinished) state).result;
|
// ((ReturnShardState.SocialBackupExchangeFinished) state).result;
|
||||||
onSocialBackupExchangeResult(result);
|
// onSocialBackupExchangeResult(result);
|
||||||
} else if (state instanceof ReturnShardState.Failed) {
|
// } else if (state instanceof ReturnShardState.Failed) {
|
||||||
Boolean qrCodeTooOld =
|
// Boolean qrCodeTooOld =
|
||||||
((ReturnShardState.Failed) state).qrCodeTooOld;
|
// ((ReturnShardState.Failed) state).qrCodeTooOld;
|
||||||
onAddingContactFailed(qrCodeTooOld);
|
// onAddingContactFailed(qrCodeTooOld);
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onSocialBackupExchangeResult(
|
private void onSocialBackupExchangeResult(
|
||||||
|
|||||||
@@ -129,8 +129,7 @@ public class OwnerReturnShardFragment extends BaseFragment
|
|||||||
@UiThread
|
@UiThread
|
||||||
private void onReturnShardStateChanged(@Nullable SecretOwnerTask.State state) {
|
private void onReturnShardStateChanged(@Nullable SecretOwnerTask.State state) {
|
||||||
if (state instanceof SecretOwnerTask.State.Listening) {
|
if (state instanceof SecretOwnerTask.State.Listening) {
|
||||||
Bitmap qrCode =
|
Bitmap qrCode = viewModel.getQrCodeBitmap();
|
||||||
((ReturnShardState.KeyAgreementListening) state).qrCode;
|
|
||||||
qrCodeView.setQrCode(qrCode);
|
qrCodeView.setQrCode(qrCode);
|
||||||
} else if (state instanceof SecretOwnerTask.State.ReceivingShard) {
|
} else if (state instanceof SecretOwnerTask.State.ReceivingShard) {
|
||||||
statusView.setVisibility(VISIBLE);
|
statusView.setVisibility(VISIBLE);
|
||||||
|
|||||||
@@ -4,23 +4,14 @@ import android.app.Application;
|
|||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.util.DisplayMetrics;
|
import android.util.DisplayMetrics;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.crypto.SecretKey;
|
|
||||||
import org.briarproject.bramble.api.db.ContactExistsException;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
|
||||||
import org.briarproject.bramble.api.keyagreement.KeyAgreementResult;
|
|
||||||
import org.briarproject.bramble.api.keyagreement.Payload;
|
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.plugin.TransportId;
|
|
||||||
import org.briarproject.bramble.api.plugin.duplex.DuplexTransportConnection;
|
|
||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.briar.android.contact.add.nearby.QrCodeUtils;
|
import org.briarproject.briar.android.contact.add.nearby.QrCodeUtils;
|
||||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||||
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
|
||||||
import org.briarproject.briar.api.socialbackup.ReturnShardPayload;
|
|
||||||
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
|
import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -33,12 +24,10 @@ import androidx.lifecycle.LiveData;
|
|||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
import static java.util.logging.Level.INFO;
|
import static java.util.logging.Level.INFO;
|
||||||
import static java.util.logging.Level.WARNING;
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
class OwnerReturnShardViewModel extends AndroidViewModel {
|
class OwnerReturnShardViewModel extends AndroidViewModel implements SecretOwnerTask.Observer {
|
||||||
|
|
||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
getLogger(OwnerReturnShardViewModel.class.getName());
|
getLogger(OwnerReturnShardViewModel.class.getName());
|
||||||
@@ -46,10 +35,11 @@ class OwnerReturnShardViewModel extends AndroidViewModel {
|
|||||||
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
|
@SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19
|
||||||
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
|
||||||
|
|
||||||
private ReturnShardPayload returnShardPayload;
|
// private ReturnShardPayload returnShardPayload;
|
||||||
|
|
||||||
private final AndroidExecutor androidExecutor;
|
private final AndroidExecutor androidExecutor;
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
|
private final SecretOwnerTask task;
|
||||||
|
|
||||||
private final MutableLiveEvent<Boolean> showQrCodeFragment =
|
private final MutableLiveEvent<Boolean> showQrCodeFragment =
|
||||||
new MutableLiveEvent<>();
|
new MutableLiveEvent<>();
|
||||||
@@ -58,14 +48,17 @@ class OwnerReturnShardViewModel extends AndroidViewModel {
|
|||||||
|
|
||||||
private boolean wasContinueClicked = false;
|
private boolean wasContinueClicked = false;
|
||||||
private boolean isActivityResumed = false;
|
private boolean isActivityResumed = false;
|
||||||
|
private Bitmap qrCodeBitmap;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
OwnerReturnShardViewModel(Application app,
|
OwnerReturnShardViewModel(Application app,
|
||||||
AndroidExecutor androidExecutor,
|
AndroidExecutor androidExecutor,
|
||||||
|
SecretOwnerTask task,
|
||||||
@IoExecutor Executor ioExecutor) {
|
@IoExecutor Executor ioExecutor) {
|
||||||
super(app);
|
super(app);
|
||||||
this.androidExecutor = androidExecutor;
|
this.androidExecutor = androidExecutor;
|
||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
|
this.task = task;
|
||||||
// IntentFilter filter = new IntentFilter(ACTION_SCAN_MODE_CHANGED);
|
// IntentFilter filter = new IntentFilter(ACTION_SCAN_MODE_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,11 +82,11 @@ class OwnerReturnShardViewModel extends AndroidViewModel {
|
|||||||
// If we return to the intro fragment, we may need to enable wifi and
|
// If we return to the intro fragment, we may need to enable wifi and
|
||||||
// hasEnabledWifi = false;
|
// hasEnabledWifi = false;
|
||||||
startListening();
|
startListening();
|
||||||
showQrCodeFragment.setEvent(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
private void startListening() {
|
private void startListening() {
|
||||||
|
task.start(this);
|
||||||
// KeyAgreementTask oldTask = task;
|
// KeyAgreementTask oldTask = task;
|
||||||
// KeyAgreementTask newTask = keyAgreementTaskProvider.get();
|
// KeyAgreementTask newTask = keyAgreementTaskProvider.get();
|
||||||
// task = newTask;
|
// task = newTask;
|
||||||
@@ -105,6 +98,7 @@ class OwnerReturnShardViewModel extends AndroidViewModel {
|
|||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
private void stopListening() {
|
private void stopListening() {
|
||||||
|
task.cancel();
|
||||||
// KeyAgreementTask oldTask = task;
|
// KeyAgreementTask oldTask = task;
|
||||||
// ioExecutor.execute(() -> {
|
// ioExecutor.execute(() -> {
|
||||||
// if (oldTask != null) oldTask.stopListening();
|
// if (oldTask != null) oldTask.stopListening();
|
||||||
@@ -153,26 +147,6 @@ class OwnerReturnShardViewModel extends AndroidViewModel {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
|
||||||
* This sets the QR code by setting the state to KeyAgreementListening.
|
|
||||||
*/
|
|
||||||
private void onLocalPayloadReceived(Payload localPayload) {
|
|
||||||
if (gotLocalPayload) return;
|
|
||||||
DisplayMetrics dm = getApplication().getResources().getDisplayMetrics();
|
|
||||||
ioExecutor.execute(() -> {
|
|
||||||
byte[] payloadBytes = payloadEncoder.encode(localPayload);
|
|
||||||
if (LOG.isLoggable(INFO)) {
|
|
||||||
LOG.info("Local payload is " + payloadBytes.length
|
|
||||||
+ " bytes");
|
|
||||||
}
|
|
||||||
// Use ISO 8859-1 to encode bytes directly as a string
|
|
||||||
String content = new String(payloadBytes, ISO_8859_1);
|
|
||||||
Bitmap qrCode = QrCodeUtils.createQrCode(dm, content);
|
|
||||||
gotLocalPayload = true;
|
|
||||||
state.postValue(new SecretOwnerTask.State.Listening(qrCode));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
// private void startContactExchange(KeyAgreementResult result) {
|
// private void startContactExchange(KeyAgreementResult result) {
|
||||||
// TransportId t = result.getTransportId();
|
// TransportId t = result.getTransportId();
|
||||||
@@ -218,7 +192,6 @@ class OwnerReturnShardViewModel extends AndroidViewModel {
|
|||||||
* https://issuetracker.google.com/issues/37067655.
|
* https://issuetracker.google.com/issues/37067655.
|
||||||
* TODO check if this is still happening with new permission requesting
|
* TODO check if this is still happening with new permission requesting
|
||||||
*/
|
*/
|
||||||
@UiThread
|
|
||||||
void setIsActivityResumed(boolean resumed) {
|
void setIsActivityResumed(boolean resumed) {
|
||||||
isActivityResumed = resumed;
|
isActivityResumed = resumed;
|
||||||
// Workaround for
|
// Workaround for
|
||||||
@@ -233,4 +206,26 @@ class OwnerReturnShardViewModel extends AndroidViewModel {
|
|||||||
LiveData<SecretOwnerTask.State> getState() {
|
LiveData<SecretOwnerTask.State> getState() {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Bitmap getQrCodeBitmap() {
|
||||||
|
return qrCodeBitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStateChanged(SecretOwnerTask.State state) {
|
||||||
|
if (state instanceof SecretOwnerTask.State.Listening) {
|
||||||
|
DisplayMetrics dm = getApplication().getResources().getDisplayMetrics();
|
||||||
|
ioExecutor.execute(() -> {
|
||||||
|
byte[] payloadBytes = ((SecretOwnerTask.State.Listening) state).getLocalPayload();
|
||||||
|
if (LOG.isLoggable(INFO)) {
|
||||||
|
LOG.info("Local payload is " + payloadBytes.length
|
||||||
|
+ " bytes");
|
||||||
|
}
|
||||||
|
// Use ISO 8859-1 to encode bytes directly as a string
|
||||||
|
String content = new String(payloadBytes, ISO_8859_1);
|
||||||
|
qrCodeBitmap = QrCodeUtils.createQrCode(dm, content);
|
||||||
|
showQrCodeFragment.setEvent(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user