From 8280b2e3b8a1b3685f7083f98c4b7b6fdf13ccb9 Mon Sep 17 00:00:00 2001 From: akwizgran Date: Fri, 23 Feb 2018 09:22:31 +0000 Subject: [PATCH 1/3] Inject StartupFailureActivity to prevent NPE. --- .../org/briarproject/briar/android/StartupFailureActivity.java | 2 +- .../briarproject/briar/android/activity/ActivityComponent.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/briar-android/src/main/java/org/briarproject/briar/android/StartupFailureActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/StartupFailureActivity.java index 2b8288e06..dc5c63fdc 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/StartupFailureActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/StartupFailureActivity.java @@ -25,7 +25,7 @@ public class StartupFailureActivity extends BaseActivity { @Override public void injectActivity(ActivityComponent component) { - + component.inject(this); } private void handleIntent(Intent i) { 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 4066c384a..7403d01e0 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 @@ -3,6 +3,7 @@ package org.briarproject.briar.android.activity; import android.app.Activity; import org.briarproject.briar.android.AndroidComponent; +import org.briarproject.briar.android.StartupFailureActivity; import org.briarproject.briar.android.blog.BlogActivity; import org.briarproject.briar.android.blog.BlogFragment; import org.briarproject.briar.android.blog.BlogModule; @@ -151,6 +152,8 @@ public interface ActivityComponent { void inject(RssFeedManageActivity activity); + void inject(StartupFailureActivity activity); + // Fragments void inject(AuthorNameFragment fragment); From 67aeb40d34cdef2739e5d5e2fb22d0c18b01d75b Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 26 Feb 2018 14:48:00 -0300 Subject: [PATCH 2/3] Backport ErrorFragment --- .../briar/android/fragment/ErrorFragment.java | 65 +++++++++++++++++++ .../src/main/res/layout/fragment_error.xml | 51 +++++++++++++++ briar-android/src/main/res/values/strings.xml | 1 + 3 files changed, 117 insertions(+) create mode 100644 briar-android/src/main/java/org/briarproject/briar/android/fragment/ErrorFragment.java create mode 100644 briar-android/src/main/res/layout/fragment_error.xml diff --git a/briar-android/src/main/java/org/briarproject/briar/android/fragment/ErrorFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/fragment/ErrorFragment.java new file mode 100644 index 000000000..81654e0aa --- /dev/null +++ b/briar-android/src/main/java/org/briarproject/briar/android/fragment/ErrorFragment.java @@ -0,0 +1,65 @@ +package org.briarproject.briar.android.fragment; + +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; +import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.briar.R; +import org.briarproject.briar.android.activity.ActivityComponent; + + +@MethodsNotNullByDefault +@ParametersNotNullByDefault +public class ErrorFragment extends BaseFragment { + + private static final String TAG = ErrorFragment.class.getSimpleName(); + + private static final String ERROR_MSG = "errorMessage"; + + public static ErrorFragment newInstance(String message) { + ErrorFragment f = new ErrorFragment(); + Bundle args = new Bundle(); + args.putString(ERROR_MSG, message); + f.setArguments(args); + return f; + } + + private String errorMessage; + + @Override + public String getUniqueTag() { + return TAG; + } + + @Override + public void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + Bundle args = getArguments(); + if (args == null) throw new AssertionError(); + errorMessage = args.getString(ERROR_MSG); + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, + @Nullable ViewGroup container, + @Nullable Bundle savedInstanceState) { + View v = inflater + .inflate(R.layout.fragment_error, container, false); + TextView msg = v.findViewById(R.id.errorMessage); + msg.setText(errorMessage); + return v; + } + + @Override + public void injectFragment(ActivityComponent component) { + // not necessary + } + +} diff --git a/briar-android/src/main/res/layout/fragment_error.xml b/briar-android/src/main/res/layout/fragment_error.xml new file mode 100644 index 000000000..ca0d029ce --- /dev/null +++ b/briar-android/src/main/res/layout/fragment_error.xml @@ -0,0 +1,51 @@ + + + + + + + + + + diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 776df599d..6bebe2b83 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -101,6 +101,7 @@ Show Help Dialog Fix Help + Sorry It seems that you are new here and have no contacts yet.\n\nTap the + icon at the top and follow the instructions to add some friends to your list.\n\nPlease remember: You can only add new contacts face-to-face to prevent anyone from impersonating you or reading your messages in the future. From 65c0e110c51edb4d4cdb6e0b5ef139482a7a9bd7 Mon Sep 17 00:00:00 2001 From: Torsten Grote Date: Mon, 26 Feb 2018 12:59:25 -0300 Subject: [PATCH 3/3] Improve UX for startup failures Show a proper error message when database is too new or too old. --- .../api/lifecycle/LifecycleManager.java | 7 +++- .../lifecycle/LifecycleManagerImpl.java | 10 +++++ .../briar/android/StartupFailureActivity.java | 37 +++++++++++++++---- .../res/layout/activity_startup_failure.xml | 24 ------------ briar-android/src/main/res/values/strings.xml | 6 ++- 5 files changed, 49 insertions(+), 35 deletions(-) delete mode 100644 briar-android/src/main/res/layout/activity_startup_failure.xml diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java index 2c680b101..b70c9dec9 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/lifecycle/LifecycleManager.java @@ -21,7 +21,12 @@ public interface LifecycleManager { * The result of calling {@link #startServices(String)}. */ enum StartResult { - ALREADY_RUNNING, DB_ERROR, SERVICE_ERROR, SUCCESS + ALREADY_RUNNING, + DB_ERROR, + DATA_TOO_OLD_ERROR, + DATA_TOO_NEW_ERROR, + SERVICE_ERROR, + SUCCESS } /** diff --git a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java index 7be465d99..029170c91 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/lifecycle/LifecycleManagerImpl.java @@ -2,6 +2,8 @@ package org.briarproject.bramble.lifecycle; import org.briarproject.bramble.api.crypto.CryptoComponent; import org.briarproject.bramble.api.crypto.KeyPair; +import org.briarproject.bramble.api.db.DataTooNewException; +import org.briarproject.bramble.api.db.DataTooOldException; import org.briarproject.bramble.api.db.DatabaseComponent; import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.db.Transaction; @@ -30,6 +32,8 @@ import javax.inject.Inject; import static java.util.logging.Level.INFO; import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.ALREADY_RUNNING; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DATA_TOO_NEW_ERROR; +import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DATA_TOO_OLD_ERROR; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.DB_ERROR; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SERVICE_ERROR; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS; @@ -159,6 +163,12 @@ class LifecycleManagerImpl implements LifecycleManager { } startupLatch.countDown(); return SUCCESS; + } catch (DataTooOldException e) { + if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); + return DATA_TOO_OLD_ERROR; + } catch (DataTooNewException e) { + if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); + return DATA_TOO_NEW_ERROR; } catch (DbException e) { if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); return DB_ERROR; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/StartupFailureActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/StartupFailureActivity.java index dc5c63fdc..6fa851707 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/StartupFailureActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/StartupFailureActivity.java @@ -3,23 +3,25 @@ package org.briarproject.briar.android; import android.app.NotificationManager; import android.content.Intent; import android.os.Bundle; -import android.widget.TextView; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BaseActivity; +import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener; +import org.briarproject.briar.android.fragment.ErrorFragment; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult; import static org.briarproject.briar.android.BriarService.EXTRA_NOTIFICATION_ID; import static org.briarproject.briar.android.BriarService.EXTRA_START_RESULT; -public class StartupFailureActivity extends BaseActivity { +public class StartupFailureActivity extends BaseActivity implements + BaseFragmentListener { @Override public void onCreate(Bundle state) { super.onCreate(state); - setContentView(R.layout.activity_startup_failure); + setContentView(R.layout.activity_fragment_container); handleIntent(getIntent()); } @@ -41,12 +43,31 @@ public class StartupFailureActivity extends BaseActivity { } // show proper error message - TextView view = findViewById(R.id.errorView); - if (result.equals(StartResult.DB_ERROR)) { - view.setText(getText(R.string.startup_failed_db_error)); - } else if (result.equals(StartResult.SERVICE_ERROR)) { - view.setText(getText(R.string.startup_failed_service_error)); + String errorMsg; + switch (result) { + case DATA_TOO_OLD_ERROR: + errorMsg = getString(R.string.startup_failed_db_error); + break; + case DATA_TOO_NEW_ERROR: + errorMsg = + getString(R.string.startup_failed_data_too_new_error); + break; + case DB_ERROR: + errorMsg = + getString(R.string.startup_failed_data_too_old_error); + break; + case SERVICE_ERROR: + errorMsg = getString(R.string.startup_failed_service_error); + break; + default: + throw new IllegalArgumentException(); } + showInitialFragment(ErrorFragment.newInstance(errorMsg)); + } + + @Override + public void runOnDbThread(Runnable runnable) { + throw new AssertionError("Deprecated and should not be used"); } } diff --git a/briar-android/src/main/res/layout/activity_startup_failure.xml b/briar-android/src/main/res/layout/activity_startup_failure.xml deleted file mode 100644 index 5b31a755f..000000000 --- a/briar-android/src/main/res/layout/activity_startup_failure.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 6bebe2b83..07a538119 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -34,9 +34,11 @@ Lost Password Your Briar account is stored encrypted on your device, not in the cloud, so we can\'t reset your password. Would you like to delete your account and start again?\n\nCaution: Your identities, contacts and messages will be permanently lost. Briar could not start - You may need to reinstall Briar. + Tap for more information. Briar Startup Failure - For some reason, your Briar database is corrupted beyond repair. Your account, your data and all your contacts are lost. Unfortunately, you need to reinstall Briar and set up a new account. + For some reason, your Briar database is corrupted beyond repair. Your account, your data and all your contacts are lost. Unfortunately, you need to reinstall Briar and set up a new account by choosing \'I have forgotten my password\' at the password prompt. + Your account was created with an old version of this app and cannot be opened with this version. You must either reinstall the old version or delete your old account by choosing \'I have forgotten my password\' at the password prompt. + This version of the app is too old. Please upgrade to the latest version and try again. Briar was unable to start a required plugin. Reinstalling Briar usually solves this problem. However, please note that you will then lose your account and all data associated with it since Briar is not using central servers to store your data on. This is a beta version of Briar. Your account will expire in %d day and cannot be renewed.