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 eb409419c..e4859d5c8 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 @@ -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.CustodianReturnShardFragment; 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.RecoverActivity; import org.briarproject.briar.android.socialbackup.ShardsSentFragment; @@ -205,7 +206,9 @@ public interface ActivityComponent { void inject(ReturnShardActivity returnShardActivity); - void inject(CustodianReturnShardActivity custodianSendShardActivity); + void inject(CustodianReturnShardActivity custodianReturnShardActivity); + + void inject(OwnerReturnShardActivity ownerReturnShardActivity); // Fragments diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardActivity.java index c2982f698..08f6e4e61 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardActivity.java @@ -12,15 +12,13 @@ import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BaseActivity; import org.briarproject.briar.android.contact.add.nearby.AddNearbyContactErrorFragment; 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 javax.annotation.Nullable; import javax.inject.Inject; -import androidx.activity.result.ActivityResultLauncher; -import androidx.activity.result.contract.ActivityResultContracts; import androidx.fragment.app.FragmentManager; import androidx.lifecycle.ViewModelProvider; @@ -87,8 +85,8 @@ public class OwnerReturnShardActivity extends BaseActivity viewModel.getShowQrCodeFragment().observeEvent(this, show -> { if (show) showQrCodeFragment(); }); -// viewModel.getState() -// .observe(this, this::onReturnShardStateChanged); + viewModel.getState() + .observe(this, this::onReturnShardStateChanged); } @Override @@ -120,9 +118,9 @@ public class OwnerReturnShardActivity extends BaseActivity @Override public void onBackPressed() { if (viewModel.getState() - .getValue() instanceof ReturnShardState.Failed) { + .getValue() instanceof SecretOwnerTask.State.Failure) { // 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); startActivity(i); } else { @@ -141,16 +139,16 @@ public class OwnerReturnShardActivity extends BaseActivity } } - private void onReturnShardStateChanged(ReturnShardState state) { - if (state instanceof ReturnShardState.SocialBackupExchangeFinished) { - ReturnShardState.SocialBackupExchangeResult result = - ((ReturnShardState.SocialBackupExchangeFinished) state).result; - onSocialBackupExchangeResult(result); - } else if (state instanceof ReturnShardState.Failed) { - Boolean qrCodeTooOld = - ((ReturnShardState.Failed) state).qrCodeTooOld; - onAddingContactFailed(qrCodeTooOld); - } + private void onReturnShardStateChanged(SecretOwnerTask.State state) { +// if (state instanceof ReturnShardState.SocialBackupExchangeFinished) { +// ReturnShardState.SocialBackupExchangeResult result = +// ((ReturnShardState.SocialBackupExchangeFinished) state).result; +// onSocialBackupExchangeResult(result); +// } else if (state instanceof ReturnShardState.Failed) { +// Boolean qrCodeTooOld = +// ((ReturnShardState.Failed) state).qrCodeTooOld; +// onAddingContactFailed(qrCodeTooOld); +// } } private void onSocialBackupExchangeResult( diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardFragment.java index 8582466d9..2c9f5e474 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardFragment.java @@ -129,8 +129,7 @@ public class OwnerReturnShardFragment extends BaseFragment @UiThread private void onReturnShardStateChanged(@Nullable SecretOwnerTask.State state) { if (state instanceof SecretOwnerTask.State.Listening) { - Bitmap qrCode = - ((ReturnShardState.KeyAgreementListening) state).qrCode; + Bitmap qrCode = viewModel.getQrCodeBitmap(); qrCodeView.setQrCode(qrCode); } else if (state instanceof SecretOwnerTask.State.ReceivingShard) { statusView.setVisibility(VISIBLE); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardViewModel.java index a4bb76a43..4c7917a6d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/socialbackup/recover/OwnerReturnShardViewModel.java @@ -4,23 +4,14 @@ import android.app.Application; import android.graphics.Bitmap; 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.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.briar.android.contact.add.nearby.QrCodeUtils; import org.briarproject.briar.android.viewmodel.LiveEvent; import org.briarproject.briar.android.viewmodel.MutableLiveEvent; -import org.briarproject.briar.api.socialbackup.ReturnShardPayload; import org.briarproject.briar.api.socialbackup.recovery.SecretOwnerTask; -import java.io.IOException; import java.nio.charset.Charset; import java.util.concurrent.Executor; import java.util.logging.Logger; @@ -33,12 +24,10 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import static java.util.logging.Level.INFO; -import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; -import static org.briarproject.bramble.util.LogUtils.logException; @NotNullByDefault -class OwnerReturnShardViewModel extends AndroidViewModel { +class OwnerReturnShardViewModel extends AndroidViewModel implements SecretOwnerTask.Observer { private static final Logger LOG = getLogger(OwnerReturnShardViewModel.class.getName()); @@ -46,10 +35,11 @@ class OwnerReturnShardViewModel extends AndroidViewModel { @SuppressWarnings("CharsetObjectCanBeUsed") // Requires minSdkVersion >= 19 private static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1"); - private ReturnShardPayload returnShardPayload; +// private ReturnShardPayload returnShardPayload; private final AndroidExecutor androidExecutor; private final Executor ioExecutor; + private final SecretOwnerTask task; private final MutableLiveEvent showQrCodeFragment = new MutableLiveEvent<>(); @@ -58,14 +48,17 @@ class OwnerReturnShardViewModel extends AndroidViewModel { private boolean wasContinueClicked = false; private boolean isActivityResumed = false; + private Bitmap qrCodeBitmap; @Inject OwnerReturnShardViewModel(Application app, AndroidExecutor androidExecutor, + SecretOwnerTask task, @IoExecutor Executor ioExecutor) { super(app); this.androidExecutor = androidExecutor; this.ioExecutor = ioExecutor; + this.task = task; // 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 // hasEnabledWifi = false; startListening(); - showQrCodeFragment.setEvent(true); } @UiThread private void startListening() { + task.start(this); // KeyAgreementTask oldTask = task; // KeyAgreementTask newTask = keyAgreementTaskProvider.get(); // task = newTask; @@ -105,6 +98,7 @@ class OwnerReturnShardViewModel extends AndroidViewModel { @UiThread private void stopListening() { + task.cancel(); // KeyAgreementTask oldTask = task; // ioExecutor.execute(() -> { // 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 // private void startContactExchange(KeyAgreementResult result) { // TransportId t = result.getTransportId(); @@ -218,7 +192,6 @@ class OwnerReturnShardViewModel extends AndroidViewModel { * https://issuetracker.google.com/issues/37067655. * TODO check if this is still happening with new permission requesting */ - @UiThread void setIsActivityResumed(boolean resumed) { isActivityResumed = resumed; // Workaround for @@ -233,4 +206,26 @@ class OwnerReturnShardViewModel extends AndroidViewModel { LiveData getState() { 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); + }); + } + } }