diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/add/nearby/AddNearbyContactViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/add/nearby/AddNearbyContactViewModel.java index d79ef6b1b..2a284f685 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/contact/add/nearby/AddNearbyContactViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/add/nearby/AddNearbyContactViewModel.java @@ -86,6 +86,7 @@ import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContact import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.NO_ADAPTER; import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.REFUSED; import static org.briarproject.briar.android.contact.add.nearby.AddNearbyContactViewModel.BluetoothDecision.UNKNOWN; +import static org.briarproject.briar.android.util.UiUtils.handleException; @NotNullByDefault class AddNearbyContactViewModel extends AndroidViewModel @@ -485,7 +486,7 @@ class AddNearbyContactViewModel extends AndroidViewModel conn.getReader().dispose(true, true); conn.getWriter().dispose(true); } catch (IOException e) { - logException(LOG, WARNING, e); + handleException(getApplication(), androidExecutor, LOG, e); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java index 5193caa21..e971c8c9b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java @@ -25,6 +25,7 @@ import android.view.KeyEvent; import android.view.View; import android.view.inputmethod.InputMethodManager; import android.widget.TextView; +import android.widget.Toast; import com.google.android.material.textfield.TextInputLayout; @@ -32,12 +33,16 @@ import org.briarproject.bramble.api.contact.Contact; import org.briarproject.bramble.api.identity.Author; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.bramble.api.system.AndroidExecutor; +import org.briarproject.bramble.util.StringUtils; import org.briarproject.briar.R; import org.briarproject.briar.android.reporting.FeedbackActivity; import org.briarproject.briar.android.view.ArticleMovementMethod; import java.util.Locale; +import java.util.logging.Logger; +import androidx.annotation.AnyThread; import androidx.annotation.AttrRes; import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; @@ -84,6 +89,7 @@ import static android.view.KeyEvent.ACTION_DOWN; import static android.view.KeyEvent.KEYCODE_ENTER; import static android.view.inputmethod.EditorInfo.IME_NULL; import static android.view.inputmethod.InputMethodManager.SHOW_IMPLICIT; +import static android.widget.Toast.LENGTH_LONG; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_AUTO_TIME; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM; import static androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO; @@ -95,7 +101,9 @@ import static androidx.core.graphics.drawable.DrawableCompat.setTint; import static androidx.core.view.ViewCompat.LAYOUT_DIRECTION_RTL; import static java.util.Objects.requireNonNull; import static java.util.concurrent.TimeUnit.DAYS; +import static java.util.logging.Level.WARNING; import static org.briarproject.bramble.util.AndroidUtils.getSupportedImageContentTypes; +import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.briar.BuildConfig.APPLICATION_ID; import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE; import static org.briarproject.briar.android.reporting.CrashReportActivity.EXTRA_APP_LOGCAT; @@ -472,4 +480,26 @@ public class UiUtils { setTint(requireNonNull(icon), getColor(ctx, R.color.color_primary)); return icon; } + + /** + * Logs the exception and shows a Toast to the user. + *

+ * Errors that are likely or expected to happen should not use this method + * and show proper error states in UI. + */ + @AnyThread + public static void handleException(Context context, + AndroidExecutor androidExecutor, Logger logger, Exception e) { + logException(logger, WARNING, e); + androidExecutor.runOnUiThread(() -> { + String msg = "Error: " + e.getClass().getSimpleName(); + if (!StringUtils.isNullOrEmpty(e.getMessage())) { + msg += " " + e.getMessage(); + } + if (e.getCause() != null) { + msg += " caused by " + e.getCause().getClass().getSimpleName(); + } + Toast.makeText(context, msg, LENGTH_LONG).show(); + }); + } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/viewmodel/DbViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/viewmodel/DbViewModel.java index 681610da6..087e95f64 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/viewmodel/DbViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/viewmodel/DbViewModel.java @@ -1,7 +1,6 @@ package org.briarproject.briar.android.viewmodel; import android.app.Application; -import android.widget.Toast; import org.briarproject.bramble.api.db.DatabaseExecutor; import org.briarproject.bramble.api.db.DbCallable; @@ -12,7 +11,7 @@ import org.briarproject.bramble.api.db.TransactionManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.system.AndroidExecutor; -import org.briarproject.bramble.util.StringUtils; +import org.briarproject.briar.android.util.UiUtils; import java.util.ArrayList; import java.util.Collection; @@ -34,7 +33,6 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.recyclerview.widget.RecyclerView; -import static android.widget.Toast.LENGTH_LONG; import static java.util.logging.Level.WARNING; import static java.util.logging.Logger.getLogger; import static org.briarproject.bramble.util.LogUtils.logException; @@ -262,17 +260,7 @@ public abstract class DbViewModel extends AndroidViewModel { */ @AnyThread protected void handleException(Exception e) { - logException(LOG, WARNING, e); - androidExecutor.runOnUiThread(() -> { - String msg = "Error: " + e.getClass().getSimpleName(); - if (!StringUtils.isNullOrEmpty(e.getMessage())) { - msg += " " + e.getMessage(); - } - if (e.getCause() != null) { - msg += " caused by " + e.getCause().getClass().getSimpleName(); - } - Toast.makeText(getApplication(), msg, LENGTH_LONG).show(); - }); + UiUtils.handleException(getApplication(), androidExecutor, LOG, e); } }