diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java index 05135062e..433410c7e 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidNotificationManagerImpl.java @@ -18,6 +18,9 @@ import org.briarproject.bramble.api.event.Event; import org.briarproject.bramble.api.event.EventListener; import org.briarproject.bramble.api.lifecycle.Service; import org.briarproject.bramble.api.lifecycle.ServiceException; +import org.briarproject.bramble.api.mailbox.MailboxStatus; +import org.briarproject.bramble.api.mailbox.event.MailboxProblemEvent; +import org.briarproject.bramble.api.mailbox.event.OwnMailboxConnectionStatusEvent; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.settings.Settings; @@ -32,6 +35,7 @@ import org.briarproject.briar.android.conversation.ConversationActivity; import org.briarproject.briar.android.forum.ForumActivity; import org.briarproject.briar.android.hotspot.HotspotActivity; import org.briarproject.briar.android.login.SignInReminderReceiver; +import org.briarproject.briar.android.mailbox.MailboxActivity; import org.briarproject.briar.android.navdrawer.NavDrawerActivity; import org.briarproject.briar.android.privategroup.conversation.GroupActivity; import org.briarproject.briar.android.splash.SplashScreenActivity; @@ -69,10 +73,12 @@ import static android.content.Context.NOTIFICATION_SERVICE; import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP; +import static android.net.Uri.EMPTY; import static android.os.Build.VERSION.SDK_INT; import static androidx.core.app.NotificationCompat.CATEGORY_MESSAGE; import static androidx.core.app.NotificationCompat.CATEGORY_SERVICE; import static androidx.core.app.NotificationCompat.CATEGORY_SOCIAL; +import static androidx.core.app.NotificationCompat.PRIORITY_HIGH; import static androidx.core.app.NotificationCompat.PRIORITY_LOW; import static androidx.core.app.NotificationCompat.PRIORITY_MIN; import static androidx.core.app.NotificationCompat.VISIBILITY_SECRET; @@ -182,6 +188,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, clearForumPostNotification(); clearBlogPostNotification(); clearContactAddedNotification(); + clearMailboxProblemNotification(); return null; }); try { @@ -250,6 +257,13 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, ContactAddedEvent c = (ContactAddedEvent) e; // Don't show notifications for contacts added in person if (!c.isVerified()) showContactAddedNotification(); + } else if (e instanceof MailboxProblemEvent) { + showMailboxProblemNotification(); + } else if (e instanceof OwnMailboxConnectionStatusEvent) { + MailboxStatus s = ((OwnMailboxConnectionStatusEvent) e).getStatus(); + if (s.getAttemptsSinceSuccess() == 0) { + clearMailboxProblemNotification(); + } } } @@ -757,4 +771,45 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager, public void clearHotspotNotification() { notificationManager.cancel(HOTSPOT_NOTIFICATION_ID); } + + @Override + public void showMailboxProblemNotification() { + if (SDK_INT >= 26) { + NotificationChannel channel = new NotificationChannel( + MAILBOX_PROBLEM_CHANNEL_ID, appContext.getString( + R.string.mailbox_error_notification_channel_title), + IMPORTANCE_DEFAULT); + channel.setLockscreenVisibility(VISIBILITY_SECRET); + notificationManager.createNotificationChannel(channel); + } + + NotificationCompat.Builder b = new NotificationCompat.Builder( + appContext, MAILBOX_PROBLEM_CHANNEL_ID); + b.setSmallIcon(R.drawable.ic_mailbox); + b.setColor(getColor(appContext, R.color.briar_red_500)); + b.setContentTitle( + appContext.getText(R.string.mailbox_error_notification_title)); + b.setContentText( + appContext.getText(R.string.mailbox_error_notification_text)); + b.setAutoCancel(true); + b.setNotificationSilent(); // not important enough for sound + b.setWhen(0); // Don't show the time + b.setPriority(PRIORITY_HIGH); + + // Touching the notification shows the mailbox status page + Intent i = new Intent(appContext, MailboxActivity.class); + i.setData(EMPTY); // for some reason, the back navigation needs an Uri + i.setFlags(FLAG_ACTIVITY_CLEAR_TOP); + TaskStackBuilder t = TaskStackBuilder.create(appContext); + t.addParentStack(MailboxActivity.class); + t.addNextIntent(i); + b.setContentIntent(t.getPendingIntent(nextRequestId++, 0)); + + notificationManager.notify(MAILBOX_PROBLEM_NOTIFICATION_ID, b.build()); + } + + @Override + public void clearMailboxProblemNotification() { + notificationManager.cancel(MAILBOX_PROBLEM_NOTIFICATION_ID); + } } 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 c4382a0a2..6b205979b 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 @@ -117,6 +117,7 @@ public class MailboxStatusFragment extends Fragment { public void onStart() { super.onStart(); requireActivity().setTitle(R.string.mailbox_status_title); + viewModel.clearProblemNotification(); refresher = this::refreshLastConnection; handler.postDelayed(refresher, MIN_DATE_RESOLUTION); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxViewModel.java index 27dbab0f5..e10ee9402 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/mailbox/MailboxViewModel.java @@ -17,7 +17,7 @@ import org.briarproject.bramble.api.mailbox.MailboxManager; import org.briarproject.bramble.api.mailbox.MailboxPairingState; import org.briarproject.bramble.api.mailbox.MailboxPairingTask; import org.briarproject.bramble.api.mailbox.MailboxStatus; -import org.briarproject.bramble.api.mailbox.OwnMailboxConnectionStatusEvent; +import org.briarproject.bramble.api.mailbox.event.OwnMailboxConnectionStatusEvent; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.api.plugin.Plugin; import org.briarproject.bramble.api.plugin.PluginManager; @@ -30,6 +30,7 @@ import org.briarproject.briar.android.qrcode.QrCodeDecoder; import org.briarproject.briar.android.viewmodel.DbViewModel; import org.briarproject.briar.android.viewmodel.LiveEvent; import org.briarproject.briar.android.viewmodel.MutableLiveEvent; +import org.briarproject.briar.api.android.AndroidNotificationManager; import java.util.concurrent.Executor; import java.util.logging.Logger; @@ -59,6 +60,7 @@ class MailboxViewModel extends DbViewModel private final QrCodeDecoder qrCodeDecoder; private final PluginManager pluginManager; private final MailboxManager mailboxManager; + private final AndroidNotificationManager notificationManager; private final MutableLiveEvent pairingState = new MutableLiveEvent<>(); @@ -77,12 +79,14 @@ class MailboxViewModel extends DbViewModel EventBus eventBus, @IoExecutor Executor ioExecutor, PluginManager pluginManager, - MailboxManager mailboxManager) { + MailboxManager mailboxManager, + AndroidNotificationManager notificationManager) { super(app, dbExecutor, lifecycleManager, db, androidExecutor); this.eventBus = eventBus; this.ioExecutor = ioExecutor; this.pluginManager = pluginManager; this.mailboxManager = mailboxManager; + this.notificationManager = notificationManager; qrCodeDecoder = new QrCodeDecoder(androidExecutor, ioExecutor, this); eventBus.addListener(this); checkIfSetup(); @@ -251,6 +255,10 @@ class MailboxViewModel extends DbViewModel }); } + void clearProblemNotification() { + notificationManager.clearMailboxProblemNotification(); + } + @UiThread LiveEvent getPairingState() { return pairingState; diff --git a/briar-android/src/main/java/org/briarproject/briar/api/android/AndroidNotificationManager.java b/briar-android/src/main/java/org/briarproject/briar/api/android/AndroidNotificationManager.java index 908b27322..c1b54275b 100644 --- a/briar-android/src/main/java/org/briarproject/briar/api/android/AndroidNotificationManager.java +++ b/briar-android/src/main/java/org/briarproject/briar/api/android/AndroidNotificationManager.java @@ -32,6 +32,7 @@ public interface AndroidNotificationManager { int BLOG_POST_NOTIFICATION_ID = 7; int CONTACT_ADDED_NOTIFICATION_ID = 8; int HOTSPOT_NOTIFICATION_ID = 9; + int MAILBOX_PROBLEM_NOTIFICATION_ID = 10; // Channel IDs String CONTACT_CHANNEL_ID = "contacts"; @@ -44,6 +45,7 @@ public interface AndroidNotificationManager { String ONGOING_CHANNEL_ID = "zForegroundService2"; String REMINDER_CHANNEL_ID = "zSignInReminder"; String HOTSPOT_CHANNEL_ID = "zHotspot"; + String MAILBOX_PROBLEM_CHANNEL_ID = "zMailboxProblem"; // This channel is no longer used - keep the ID so we can remove the // channel from existing installations @@ -104,4 +106,8 @@ public interface AndroidNotificationManager { void showHotspotNotification(); void clearHotspotNotification(); + + void showMailboxProblemNotification(); + + void clearMailboxProblemNotification(); } diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 660fc00c5..f4e3acec8 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -652,6 +652,9 @@ Your Mailbox has been unlinked Next time you have access to your Mailbox device, please open the Mailbox app and tap the \"Unlink\" button to complete the process.\n\nIf you no longer have access to your Mailbox device, don\'t worry. Your data is encrypted so it will remain secure even if you don\'t complete the process. + Briar Mailbox problem + Briar Mailbox is unavailable + Tap to fix problem. Fix problem Mailbox troubleshooting wizard Do you have access to your Mailbox device?