diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxConstants.java index 6a2ede3ef..5a54e7f44 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxConstants.java @@ -2,6 +2,9 @@ package org.briarproject.bramble.api.mailbox; import org.briarproject.bramble.api.plugin.TransportId; +import java.util.List; + +import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.HOURS; import static org.briarproject.bramble.api.transport.TransportConstants.MAX_FRAME_LENGTH; import static org.briarproject.bramble.api.transport.TransportConstants.MAX_PAYLOAD_LENGTH; @@ -16,10 +19,25 @@ public interface MailboxConstants { TransportId ID = new TransportId("org.briarproject.bramble.mailbox"); /** - * The highest major version of the mailbox server - * that this client supports. + * Mailbox API versions that we support as a client. This is reported to our + * contacts by {@link MailboxUpdateManager}. */ - int MAILBOX_VERSION_MAJOR = 1; + List CLIENT_SUPPORTS = singletonList( + new MailboxVersion(1, 0)); + + /** + * The constant returned by + * {@link MailboxHelper#getHighestCommonMajorVersion(List, List)} + * when the server is too old to support our major version. + */ + int API_SERVER_TOO_OLD = -1; + + /** + * The constant returned by + * {@link MailboxHelper#getHighestCommonMajorVersion(List, List)} + * when we as a client are too old to support the server's major version. + */ + int API_CLIENT_TOO_OLD = -2; /** * The maximum length of a file that can be uploaded to or downloaded from diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxHelper.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxHelper.java new file mode 100644 index 000000000..c57eea29b --- /dev/null +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxHelper.java @@ -0,0 +1,35 @@ +package org.briarproject.bramble.api.mailbox; + +import java.util.List; +import java.util.TreeSet; + +import static org.briarproject.bramble.api.mailbox.MailboxConstants.API_CLIENT_TOO_OLD; +import static org.briarproject.bramble.api.mailbox.MailboxConstants.API_SERVER_TOO_OLD; + +class MailboxHelper { + + /** + * Returns the highest major version that both client and server support + * or {@link MailboxConstants#API_SERVER_TOO_OLD} if the server is too old + * or {@link MailboxConstants#API_CLIENT_TOO_OLD} if the client is too old. + */ + static int getHighestCommonMajorVersion( + List client, List server) { + TreeSet clientVersions = new TreeSet<>(); + for (MailboxVersion version : client) { + clientVersions.add(version.getMajor()); + } + TreeSet serverVersions = new TreeSet<>(); + for (MailboxVersion version : server) { + serverVersions.add(version.getMajor()); + } + for (int clientVersion : clientVersions.descendingSet()) { + if (serverVersions.contains(clientVersion)) return clientVersion; + } + if (clientVersions.last() < serverVersions.last()) { + return API_CLIENT_TOO_OLD; + } + return API_SERVER_TOO_OLD; + } + +} diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxStatus.java b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxStatus.java index 2e517d002..3ba6bb92f 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxStatus.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/mailbox/MailboxStatus.java @@ -6,9 +6,10 @@ import java.util.List; import javax.annotation.concurrent.Immutable; -import static org.briarproject.bramble.api.mailbox.MailboxConstants.MAILBOX_VERSION_MAJOR; +import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS; import static org.briarproject.bramble.api.mailbox.MailboxConstants.PROBLEM_MS_SINCE_LAST_SUCCESS; import static org.briarproject.bramble.api.mailbox.MailboxConstants.PROBLEM_NUM_CONNECTION_FAILURES; +import static org.briarproject.bramble.api.mailbox.MailboxHelper.getHighestCommonMajorVersion; @Immutable @NotNullByDefault @@ -75,14 +76,11 @@ public class MailboxStatus { } /** - * @return true if the Mailbox is incompatible with this version of Briar, - * so that the mailbox needs to be updated. + * @return a positive integer if the mailbox is compatible. Same result as + * {@link MailboxHelper#getHighestCommonMajorVersion(List, List)}. */ - public boolean isMailboxIncompatible() { - for (MailboxVersion version : serverSupports) { - if (version.getMajor() <= MAILBOX_VERSION_MAJOR) return false; - } - return true; + public int getMailboxCompatibility() { + return getHighestCommonMajorVersion(CLIENT_SUPPORTS, serverSupports); } } diff --git a/bramble-api/src/test/java/org/briarproject/bramble/api/mailbox/MailboxHelperTest.java b/bramble-api/src/test/java/org/briarproject/bramble/api/mailbox/MailboxHelperTest.java new file mode 100644 index 000000000..a156dba07 --- /dev/null +++ b/bramble-api/src/test/java/org/briarproject/bramble/api/mailbox/MailboxHelperTest.java @@ -0,0 +1,44 @@ +package org.briarproject.bramble.api.mailbox; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Random; + +import static org.briarproject.bramble.api.mailbox.MailboxConstants.API_CLIENT_TOO_OLD; +import static org.briarproject.bramble.api.mailbox.MailboxConstants.API_SERVER_TOO_OLD; +import static org.briarproject.bramble.api.mailbox.MailboxHelper.getHighestCommonMajorVersion; +import static org.junit.Assert.assertEquals; + +public class MailboxHelperTest { + + private final Random random = new Random(); + + @Test + public void testGetHighestCommonMajorVersion() { + assertEquals(2, getHighestCommonMajorVersion(v(2), v(2))); + assertEquals(2, getHighestCommonMajorVersion(v(1, 2), v(2, 3, 4))); + assertEquals(2, getHighestCommonMajorVersion(v(2, 3, 4), v(2))); + assertEquals(2, getHighestCommonMajorVersion(v(2), v(2, 3, 4))); + + assertEquals(API_CLIENT_TOO_OLD, + getHighestCommonMajorVersion(v(2), v(3, 4))); + assertEquals(API_CLIENT_TOO_OLD, + getHighestCommonMajorVersion(v(2), v(1, 3))); + assertEquals(API_SERVER_TOO_OLD, + getHighestCommonMajorVersion(v(3, 4, 5), v(2))); + assertEquals(API_SERVER_TOO_OLD, + getHighestCommonMajorVersion(v(1, 3), v(2))); + } + + private List v(int... ints) { + List versions = new ArrayList<>(ints.length); + for (int v : ints) { + // minor versions should not matter + versions.add(new MailboxVersion(v, random.nextInt(42))); + } + return versions; + } + +} diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java index 8f373d334..1e384009b 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxApi.java @@ -7,7 +7,6 @@ import org.briarproject.bramble.api.mailbox.MailboxAuthToken; import org.briarproject.bramble.api.mailbox.MailboxFileId; import org.briarproject.bramble.api.mailbox.MailboxFolderId; import org.briarproject.bramble.api.mailbox.MailboxProperties; -import org.briarproject.bramble.api.mailbox.MailboxUpdateManager; import org.briarproject.bramble.api.mailbox.MailboxVersion; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; @@ -19,18 +18,9 @@ import java.util.List; import javax.annotation.Nonnull; import javax.annotation.concurrent.Immutable; -import static java.util.Collections.singletonList; - @NotNullByDefault interface MailboxApi { - /** - * Mailbox API versions that we support as a client. This is reported to our - * contacts by {@link MailboxUpdateManager}. - */ - List CLIENT_SUPPORTS = singletonList( - new MailboxVersion(1, 0)); - List getServerSupports(MailboxProperties properties) throws IOException, ApiException; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxModule.java b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxModule.java index 3a675f774..7fe5d0824 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxModule.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/mailbox/MailboxModule.java @@ -22,10 +22,10 @@ import javax.inject.Singleton; import dagger.Module; import dagger.Provides; +import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS; import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.CLIENT_ID; import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MAJOR_VERSION; import static org.briarproject.bramble.api.mailbox.MailboxUpdateManager.MINOR_VERSION; -import static org.briarproject.bramble.mailbox.MailboxApi.CLIENT_SUPPORTS; @Module public class MailboxModule { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/ConnectivityCheckerImplTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/ConnectivityCheckerImplTest.java index 448b36ea9..09fb0df5b 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/ConnectivityCheckerImplTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/ConnectivityCheckerImplTest.java @@ -10,8 +10,8 @@ import org.junit.Test; import javax.annotation.Nonnull; +import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS; import static org.briarproject.bramble.mailbox.ConnectivityCheckerImpl.CONNECTIVITY_CHECK_FRESHNESS_MS; -import static org.briarproject.bramble.mailbox.MailboxApi.CLIENT_SUPPORTS; import static org.briarproject.bramble.test.TestUtils.getMailboxProperties; public class ConnectivityCheckerImplTest extends BrambleMockTestCase { diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/ContactMailboxConnectivityCheckerTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/ContactMailboxConnectivityCheckerTest.java index 2378e3d1b..a3b59d631 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/ContactMailboxConnectivityCheckerTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/ContactMailboxConnectivityCheckerTest.java @@ -13,7 +13,7 @@ import org.junit.Test; import java.io.IOException; import java.util.concurrent.atomic.AtomicReference; -import static org.briarproject.bramble.mailbox.MailboxApi.CLIENT_SUPPORTS; +import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS; import static org.briarproject.bramble.test.TestUtils.getMailboxProperties; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java index 757af0760..cbf5bd851 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/MailboxApiTest.java @@ -35,7 +35,7 @@ import okio.Buffer; import static java.util.Collections.singletonList; import static java.util.concurrent.TimeUnit.MILLISECONDS; -import static org.briarproject.bramble.mailbox.MailboxApi.CLIENT_SUPPORTS; +import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS; import static org.briarproject.bramble.test.TestUtils.getContactId; import static org.briarproject.bramble.test.TestUtils.getMailboxProperties; import static org.briarproject.bramble.test.TestUtils.getRandomBytes; diff --git a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/OwnMailboxConnectivityCheckerTest.java b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/OwnMailboxConnectivityCheckerTest.java index c94d87903..159d0262f 100644 --- a/bramble-core/src/test/java/org/briarproject/bramble/mailbox/OwnMailboxConnectivityCheckerTest.java +++ b/bramble-core/src/test/java/org/briarproject/bramble/mailbox/OwnMailboxConnectivityCheckerTest.java @@ -17,7 +17,7 @@ import org.junit.Test; import java.io.IOException; import java.util.concurrent.atomic.AtomicReference; -import static org.briarproject.bramble.mailbox.MailboxApi.CLIENT_SUPPORTS; +import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS; import static org.briarproject.bramble.test.TestUtils.getMailboxProperties; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxStatusFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxStatusFragment.java index e71cd48e6..ebdf3974b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxStatusFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxStatusFragment.java @@ -36,6 +36,7 @@ import static android.view.View.VISIBLE; import static androidx.core.content.ContextCompat.getColor; import static androidx.core.widget.ImageViewCompat.setImageTintList; import static androidx.transition.TransitionManager.beginDelayedTransition; +import static org.briarproject.bramble.api.mailbox.MailboxConstants.API_CLIENT_TOO_OLD; import static org.briarproject.briar.android.AppModule.getAndroidComponent; import static org.briarproject.briar.android.util.UiUtils.MIN_DATE_RESOLUTION; import static org.briarproject.briar.android.util.UiUtils.formatDate; @@ -58,8 +59,7 @@ public class MailboxStatusFragment extends Fragment { private boolean showUnlinkWarning = true; private ImageView imageView; - private TextView statusTitleView; - private TextView statusInfoView; + private TextView statusTitleView, statusMessageView, statusInfoView; private Button wizardButton; private Button unlinkButton; private ProgressBar unlinkProgress; @@ -94,6 +94,7 @@ public class MailboxStatusFragment extends Fragment { imageView = v.findViewById(R.id.imageView); statusTitleView = v.findViewById(R.id.statusTitleView); + statusMessageView = v.findViewById(R.id.statusMessageView); statusInfoView = v.findViewById(R.id.statusInfoView); viewModel.getStatus() .observe(getViewLifecycleOwner(), this::onMailboxStateChanged); @@ -132,6 +133,7 @@ public class MailboxStatusFragment extends Fragment { @ColorRes int tintRes; @DrawableRes int iconRes; String title; + String message = null; if (status.hasProblem(System.currentTimeMillis())) { tintRes = R.color.briar_red_500; title = getString(R.string.mailbox_status_failure_title); @@ -144,9 +146,18 @@ public class MailboxStatusFragment extends Fragment { tintRes = R.color.briar_orange_500; showUnlinkWarning = false; wizardButton.setVisibility(VISIBLE); - } else if (status.isMailboxIncompatible()) { + } else if (status.getMailboxCompatibility() < 0) { tintRes = R.color.briar_red_500; - title = getString(R.string.mailbox_status_incompatible_title); + if (status.getMailboxCompatibility() == API_CLIENT_TOO_OLD) { + title = getString(R.string.mailbox_status_app_too_old_title); + message = + getString(R.string.mailbox_status_app_too_old_message); + } else { + title = getString( + R.string.mailbox_status_mailbox_too_old_title); + message = getString( + R.string.mailbox_status_mailbox_too_old_message); + } iconRes = R.drawable.alerts_and_states_error; showUnlinkWarning = true; wizardButton.setVisibility(GONE); @@ -161,6 +172,12 @@ public class MailboxStatusFragment extends Fragment { int color = getColor(requireContext(), tintRes); setImageTintList(imageView, ColorStateList.valueOf(color)); statusTitleView.setText(title); + if (message == null) { + statusMessageView.setVisibility(GONE); + } else { + statusMessageView.setVisibility(VISIBLE); + statusMessageView.setText(message); + } long lastSuccess = status.getTimeOfLastSuccess(); String lastConnectionText; diff --git a/briar-android/src/main/res/layout/fragment_mailbox_status.xml b/briar-android/src/main/res/layout/fragment_mailbox_status.xml index 520a49f09..80737cbd8 100644 --- a/briar-android/src/main/res/layout/fragment_mailbox_status.xml +++ b/briar-android/src/main/res/layout/fragment_mailbox_status.xml @@ -31,12 +31,29 @@ android:gravity="center" android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6" app:layout_constrainedWidth="true" - app:layout_constraintBottom_toTopOf="@+id/checkButton" + app:layout_constraintBottom_toTopOf="@+id/statusMessageView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageView" tools:text="@string/mailbox_status_problem_title" /> + + Mailbox is running Briar is having trouble connecting to the Mailbox Mailbox is unavailable - Mailbox is incompatible. Ensure Briar and Mailbox are updated to latest version. + Briar is too old + Update Briar to the latest version of the app and try again. + Mailbox is too old + Update your Mailbox to the latest version of the app and try again. Check Connection Last connection: %s