From 2fe57d2597d610c9d268573e3c75d17cf0fbaa61 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Wed, 30 Nov 2022 17:17:08 +0000 Subject: [PATCH 1/4] Show progress while connecting to mailbox. --- .../api/mailbox/MailboxPairingState.java | 21 +++++++- .../mailbox/MailboxPairingTaskImpl.java | 6 ++- .../android/mailbox/MailboxActivity.java | 8 ++- .../mailbox/MailboxConnectingFragment.java | 53 ++++++++++++++++++- .../layout/fragment_mailbox_connecting.xml | 37 +++++++++---- briar-android/src/main/res/values/strings.xml | 4 +- 6 files changed, 108 insertions(+), 21 deletions(-) diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPairingState.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPairingState.java index 8e129e2fe..47c055aad 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPairingState.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxPairingState.java @@ -2,10 +2,27 @@ package org.briarproject.bramble.api.mailbox; public abstract class MailboxPairingState { - public static class QrCodeReceived extends MailboxPairingState { + public abstract static class Pending extends MailboxPairingState { + + public final long timeStarted; + + private Pending(long timeStarted) { + this.timeStarted = timeStarted; + } } - public static class Pairing extends MailboxPairingState { + public static class QrCodeReceived extends Pending { + + public QrCodeReceived(long timeStarted) { + super(timeStarted); + } + } + + public static class Pairing extends Pending { + + public Pairing(long timeStarted) { + super(timeStarted); + } } public static class Paired extends MailboxPairingState { diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java index 544a38bf1..8ce25be9d 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImpl.java @@ -52,6 +52,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask { private final MailboxApi api; private final MailboxSettingsManager mailboxSettingsManager; private final MailboxUpdateManager mailboxUpdateManager; + private final long timeStarted; private final Object lock = new Object(); @GuardedBy("lock") @@ -77,7 +78,8 @@ class MailboxPairingTaskImpl implements MailboxPairingTask { this.api = api; this.mailboxSettingsManager = mailboxSettingsManager; this.mailboxUpdateManager = mailboxUpdateManager; - state = new MailboxPairingState.QrCodeReceived(); + timeStarted = clock.currentTimeMillis(); + state = new MailboxPairingState.QrCodeReceived(timeStarted); } @Override @@ -114,7 +116,7 @@ class MailboxPairingTaskImpl implements MailboxPairingTask { private void pairMailbox() throws IOException, ApiException, DbException { MailboxProperties mailboxProperties = decodeQrCodePayload(payload); - setState(new MailboxPairingState.Pairing()); + setState(new MailboxPairingState.Pairing(timeStarted)); MailboxProperties ownerProperties = api.setup(mailboxProperties); long time = clock.currentTimeMillis(); db.transaction(false, txn -> { diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxActivity.java index c72993776..64aaeacd7 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxActivity.java @@ -158,11 +158,9 @@ public class MailboxActivity extends BriarActivity { } Fragment f; String tag; - if (s instanceof MailboxPairingState.QrCodeReceived) { - f = new MailboxConnectingFragment(); - tag = MailboxConnectingFragment.TAG; - } else if (s instanceof MailboxPairingState.Pairing) { - f = new MailboxConnectingFragment(); + if (s instanceof MailboxPairingState.Pending) { + long timeStarted = ((MailboxPairingState.Pending) s).timeStarted; + f = MailboxConnectingFragment.newInstance(timeStarted); tag = MailboxConnectingFragment.TAG; } else if (s instanceof MailboxPairingState.InvalidQrCode) { f = ErrorFragment.newInstance( diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxConnectingFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxConnectingFragment.java index 3da20a80e..b7d5c11b3 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxConnectingFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxConnectingFragment.java @@ -1,10 +1,15 @@ package org.briarproject.briar.android.mailbox; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ProgressBar; +import android.widget.TextView; +import org.briarproject.bramble.api.plugin.TorConstants; import org.briarproject.briar.R; import org.briarproject.nullsafety.MethodsNotNullByDefault; import org.briarproject.nullsafety.ParametersNotNullByDefault; @@ -12,25 +17,71 @@ import org.briarproject.nullsafety.ParametersNotNullByDefault; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; +import static org.briarproject.briar.android.util.UiUtils.formatDuration; + @MethodsNotNullByDefault @ParametersNotNullByDefault public class MailboxConnectingFragment extends Fragment { static final String TAG = MailboxConnectingFragment.class.getName(); + private static final String ARG_STARTED = "started"; + private static final long TIMEOUT_MS = TorConstants.EXTRA_CONNECT_TIMEOUT; + private static final long REFRESH_INTERVAL_MS = 1_000; + + private final Handler handler = new Handler(Looper.getMainLooper()); + // Capture a method reference so we use the same reference for posting + // and removing + private final Runnable refresher = this::updateProgressBar; + + private ProgressBar progressBar; + private long timeStarted; + + public static MailboxConnectingFragment newInstance(long timeStarted) { + MailboxConnectingFragment f = new MailboxConnectingFragment(); + Bundle args = new Bundle(); + args.putLong(ARG_STARTED, timeStarted); + f.setArguments(args); + return f; + } + @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - return inflater.inflate(R.layout.fragment_mailbox_connecting, + View v = inflater.inflate(R.layout.fragment_mailbox_connecting, container, false); + + progressBar = v.findViewById(R.id.progressBar); + TextView info = v.findViewById(R.id.info); + String duration = formatDuration(requireContext(), TIMEOUT_MS); + info.setText(getString(R.string.mailbox_setup_connecting_info, + duration)); + + timeStarted = requireArguments().getLong(ARG_STARTED); + + return v; } @Override public void onStart() { super.onStart(); requireActivity().setTitle(R.string.mailbox_setup_title); + updateProgressBar(); } + @Override + public void onStop() { + super.onStop(); + handler.removeCallbacks(refresher); + } + + private void updateProgressBar() { + long elapsedMs = System.currentTimeMillis() - timeStarted; + int percent = (int) (elapsedMs * 100 / TIMEOUT_MS); + percent = Math.min(Math.max(percent, 0), 100); + progressBar.setProgress(percent); + handler.postDelayed(refresher, REFRESH_INTERVAL_MS); + } } diff --git a/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml b/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml index c7cf2b242..2e39696f9 100644 --- a/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml +++ b/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml @@ -1,31 +1,48 @@ - + + + app:layout_constraintTop_toBottomOf="@+id/progressBar" + tools:text="This may take up to 2 minutes" /> diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 5e00eac0a..ad57f0bc6 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -633,7 +633,9 @@ Share Download Link Scan Mailbox QR code You have denied access to the camera, but scanning a QR code requires using the camera.\n\nPlease consider granting access. - Connecting… + Connecting to Mailbox… + + This may take up to %1s Wrong QR code The scanned code is invalid. Please open the Briar Mailbox app on your Mailbox device and scan the QR code it presents. Mailbox already linked From 1b8d1a5a8d253ee19b832a5b6d8256f3696262ad Mon Sep 17 00:00:00 2001 From: akwizgran Date: Wed, 30 Nov 2022 17:30:33 +0000 Subject: [PATCH 2/4] Update test expectations. --- .../mailbox/MailboxPairingTaskImplTest.java | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java index fbc817d3f..86763a525 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxPairingTaskImplTest.java @@ -68,8 +68,7 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { @Test public void testInitialQrCodeReceivedState() { - MailboxPairingTask task = - factory.createPairingTask(getRandomString(42)); + MailboxPairingTask task = createPairingTask(getRandomString(42)); task.addObserver(state -> assertTrue(state instanceof MailboxPairingState.QrCodeReceived) ); @@ -77,15 +76,14 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { @Test public void testInvalidQrCode() { - MailboxPairingTask task1 = - factory.createPairingTask(getRandomString(42)); + MailboxPairingTask task1 = createPairingTask(getRandomString(42)); task1.run(); task1.addObserver(state -> assertTrue(state instanceof MailboxPairingState.InvalidQrCode) ); String goodLength = "00" + getRandomString(63); - MailboxPairingTask task2 = factory.createPairingTask(goodLength); + MailboxPairingTask task2 = createPairingTask(goodLength); task2.run(); task2.addObserver(state -> assertTrue(state instanceof MailboxPairingState.InvalidQrCode) @@ -121,7 +119,7 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { }}); AtomicInteger i = new AtomicInteger(0); - MailboxPairingTask task = factory.createPairingTask(validPayload); + MailboxPairingTask task = createPairingTask(validPayload); task.addObserver(state -> { if (i.get() == 0) { assertEquals(MailboxPairingState.QrCodeReceived.class, @@ -165,7 +163,7 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { will(throwException(e)); }}); - MailboxPairingTask task = factory.createPairingTask(validPayload); + MailboxPairingTask task = createPairingTask(validPayload); task.run(); task.addObserver(state -> assertEquals(state.getClass(), s)); } @@ -188,7 +186,7 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { will(throwException(new DbException())); }}); - MailboxPairingTask task = factory.createPairingTask(validPayload); + MailboxPairingTask task = createPairingTask(validPayload); task.run(); task.addObserver(state -> assertEquals(state.getClass(), MailboxPairingState.UnexpectedError.class)); @@ -202,4 +200,12 @@ public class MailboxPairingTaskImplTest extends BrambleMockTestCase { p1.getServerSupports().equals(p2.getServerSupports())); } + private MailboxPairingTask createPairingTask(String qrCodePayload) { + context.checking(new Expectations() {{ + oneOf(clock).currentTimeMillis(); + will(returnValue(time)); + }}); + + return factory.createPairingTask(qrCodePayload); + } } From 186f61f771b7d87e22170f14992cbb2c288780b7 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Mon, 12 Dec 2022 16:14:34 +0000 Subject: [PATCH 3/4] Set width of text views to 0dp so margins are applied. --- .../src/main/res/layout/fragment_mailbox_connecting.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml b/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml index 2e39696f9..f36b5c4f0 100644 --- a/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml +++ b/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml @@ -8,7 +8,7 @@ Date: Wed, 14 Dec 2022 12:03:06 +0000 Subject: [PATCH 4/4] Center text, add margin at bottom to center layout. --- .../src/main/res/layout/fragment_mailbox_connecting.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml b/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml index f36b5c4f0..3f285764b 100644 --- a/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml +++ b/briar-android/src/main/res/layout/fragment_mailbox_connecting.xml @@ -12,6 +12,7 @@ android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/margin_xlarge" android:layout_marginTop="@dimen/margin_xlarge" + android:gravity="center" android:text="@string/mailbox_setup_connecting" app:layout_constraintBottom_toTopOf="@+id/progressBar" app:layout_constraintEnd_toEndOf="parent" @@ -38,6 +39,8 @@ android:layout_height="wrap_content" android:layout_marginHorizontal="@dimen/margin_xlarge" android:layout_marginTop="@dimen/margin_xlarge" + android:layout_marginBottom="@dimen/margin_xlarge" + android:gravity="center" android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"