diff --git a/briar-android/src/main/AndroidManifest.xml b/briar-android/src/main/AndroidManifest.xml
index cadb84903..c43e5aa27 100644
--- a/briar-android/src/main/AndroidManifest.xml
+++ b/briar-android/src/main/AndroidManifest.xml
@@ -32,6 +32,11 @@
+
+
+
SOUND_DELAY) {
+ boolean sound = settings.getBoolean(PREF_NOTIFY_SOUND, true);
String ringtoneUri = settings.get(PREF_NOTIFY_RINGTONE_URI);
- if (!StringUtils.isNullOrEmpty(ringtoneUri))
+ if (sound && !StringUtils.isNullOrEmpty(ringtoneUri))
b.setSound(Uri.parse(ringtoneUri));
b.setDefaults(getDefaults());
- lastSound = clock.currentTimeMillis();
+ lastSound = currentTime;
}
}
@@ -359,6 +349,23 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
return defaults;
}
+ private void setDeleteIntent(BriarNotificationBuilder b, String uri) {
+ Intent i = new Intent(appContext, NotificationCleanupService.class);
+ i.setData(Uri.parse(uri));
+ b.setDeleteIntent(PendingIntent.getService(appContext, nextRequestId++,
+ i, 0));
+ }
+
+ @Override
+ public void clearAllContactNotifications() {
+ androidExecutor.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ clearContactNotification();
+ }
+ });
+ }
+
@UiThread
private void showGroupMessageNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() {
@@ -370,7 +377,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
if (count == null) groupCounts.put(g, 1);
else groupCounts.put(g, count + 1);
groupTotal++;
- updateGroupMessageNotification();
+ updateGroupMessageNotification(true);
}
});
}
@@ -383,13 +390,13 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
Integer count = groupCounts.remove(g);
if (count == null) return; // Already cleared
groupTotal -= count;
- updateGroupMessageNotification();
+ updateGroupMessageNotification(false);
}
});
}
@UiThread
- private void updateGroupMessageNotification() {
+ private void updateGroupMessageNotification(boolean mayAlertAgain) {
if (groupTotal == 0) {
clearGroupMessageNotification();
} else if (settings.getBoolean(PREF_NOTIFY_GROUP, true)) {
@@ -405,7 +412,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
boolean showOnLockScreen =
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
b.setLockscreenVisibility(CATEGORY_SOCIAL, showOnLockScreen);
- playSound(b);
+ if (mayAlertAgain) setAlertProperties(b);
+ setDeleteIntent(b, GROUP_URI);
if (groupCounts.size() == 1) {
// Touching the notification shows the relevant group
Intent i = new Intent(appContext, GroupActivity.class);
@@ -435,6 +443,16 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}
}
+ @Override
+ public void clearAllGroupMessageNotifications() {
+ androidExecutor.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ clearGroupMessageNotification();
+ }
+ });
+ }
+
@UiThread
private void showForumPostNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() {
@@ -446,7 +464,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
if (count == null) forumCounts.put(g, 1);
else forumCounts.put(g, count + 1);
forumTotal++;
- updateForumPostNotification();
+ updateForumPostNotification(true);
}
});
}
@@ -459,13 +477,13 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
Integer count = forumCounts.remove(g);
if (count == null) return; // Already cleared
forumTotal -= count;
- updateForumPostNotification();
+ updateForumPostNotification(false);
}
});
}
@UiThread
- private void updateForumPostNotification() {
+ private void updateForumPostNotification(boolean mayAlertAgain) {
if (forumTotal == 0) {
clearForumPostNotification();
} else if (settings.getBoolean(PREF_NOTIFY_FORUM, true)) {
@@ -481,7 +499,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
boolean showOnLockScreen =
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
b.setLockscreenVisibility(CATEGORY_SOCIAL, showOnLockScreen);
- playSound(b);
+ if (mayAlertAgain) setAlertProperties(b);
+ setDeleteIntent(b, FORUM_URI);
if (forumCounts.size() == 1) {
// Touching the notification shows the relevant forum
Intent i = new Intent(appContext, ForumActivity.class);
@@ -511,6 +530,16 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}
}
+ @Override
+ public void clearAllForumPostNotifications() {
+ androidExecutor.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ clearForumPostNotification();
+ }
+ });
+ }
+
@UiThread
private void showBlogPostNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() {
@@ -522,7 +551,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
if (count == null) blogCounts.put(g, 1);
else blogCounts.put(g, count + 1);
blogTotal++;
- updateBlogPostNotification();
+ updateBlogPostNotification(true);
}
});
}
@@ -535,13 +564,13 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
Integer count = blogCounts.remove(g);
if (count == null) return; // Already cleared
blogTotal -= count;
- updateBlogPostNotification();
+ updateBlogPostNotification(false);
}
});
}
@UiThread
- private void updateBlogPostNotification() {
+ private void updateBlogPostNotification(boolean mayAlertAgain) {
if (blogTotal == 0) {
clearBlogPostNotification();
} else if (settings.getBoolean(PREF_NOTIFY_BLOG, true)) {
@@ -557,7 +586,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
boolean showOnLockScreen =
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
b.setLockscreenVisibility(CATEGORY_SOCIAL, showOnLockScreen);
- playSound(b);
+ if (mayAlertAgain) setAlertProperties(b);
+ setDeleteIntent(b, BLOG_URI);
// Touching the notification shows the combined blog feed
Intent i = new Intent(appContext, NavDrawerActivity.class);
i.putExtra(INTENT_BLOGS, true);
@@ -607,7 +637,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
boolean showOnLockScreen =
settings.getBoolean(PREF_NOTIFY_LOCK_SCREEN, false);
b.setLockscreenVisibility(CATEGORY_MESSAGE, showOnLockScreen);
- playSound(b);
+ setAlertProperties(b);
+ setDeleteIntent(b, INTRODUCTION_URI);
// Touching the notification shows the contact list
Intent i = new Intent(appContext, NavDrawerActivity.class);
i.putExtra(INTENT_CONTACTS, true);
@@ -623,6 +654,16 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
nm.notify(INTRODUCTION_SUCCESS_NOTIFICATION_ID, b.build());
}
+ @Override
+ public void clearAllIntroductionNotifications() {
+ androidExecutor.runOnUiThread(new Runnable() {
+ @Override
+ public void run() {
+ clearIntroductionSuccessNotification();
+ }
+ });
+ }
+
@Override
public void blockNotification(final GroupId g) {
androidExecutor.runOnUiThread(new Runnable() {
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/NotificationCleanupService.java b/briar-android/src/main/java/org/briarproject/briar/android/NotificationCleanupService.java
new file mode 100644
index 000000000..9c2a7cdef
--- /dev/null
+++ b/briar-android/src/main/java/org/briarproject/briar/android/NotificationCleanupService.java
@@ -0,0 +1,64 @@
+package org.briarproject.briar.android;
+
+import android.app.IntentService;
+import android.content.Intent;
+import android.support.annotation.Nullable;
+import android.util.Log;
+
+import org.briarproject.briar.api.android.AndroidNotificationManager;
+
+import javax.inject.Inject;
+
+import static org.briarproject.briar.api.android.AndroidNotificationManager.BLOG_URI;
+import static org.briarproject.briar.api.android.AndroidNotificationManager.CONTACT_URI;
+import static org.briarproject.briar.api.android.AndroidNotificationManager.FORUM_URI;
+import static org.briarproject.briar.api.android.AndroidNotificationManager.GROUP_URI;
+import static org.briarproject.briar.api.android.AndroidNotificationManager.INTRODUCTION_URI;
+
+public class NotificationCleanupService extends IntentService {
+
+ private static final String TAG =
+ NotificationCleanupService.class.getName();
+
+ @Inject
+ AndroidNotificationManager notificationManager;
+
+ public NotificationCleanupService() {
+ super(TAG);
+ }
+
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ AndroidComponent applicationComponent =
+ ((BriarApplication) getApplication()).getApplicationComponent();
+ applicationComponent.inject(this);
+ }
+
+ @Override
+ protected void onHandleIntent(@Nullable Intent i) {
+ if (i == null || i.getData() == null) {
+ Log.i(TAG, "No intent or no data");
+ return;
+ }
+ String uri = i.getData().toString();
+ if (uri.equals(CONTACT_URI)) {
+ Log.i(TAG, "Clearing contact notifications");
+ notificationManager.clearAllContactNotifications();
+ } else if (uri.equals(GROUP_URI)) {
+ Log.i(TAG, "Clearing group notifications");
+ notificationManager.clearAllGroupMessageNotifications();
+ } else if (uri.equals(FORUM_URI)) {
+ Log.i(TAG, "Clearing forum notifications");
+ notificationManager.clearAllForumPostNotifications();
+ } else if (uri.equals(BLOG_URI)) {
+ Log.i(TAG, "Clearing blog notifications");
+ notificationManager.clearAllBlogPostNotifications();
+ } else if (uri.equals(INTRODUCTION_URI)) {
+ Log.i(TAG, "Clearing introduction notifications");
+ notificationManager.clearAllIntroductionNotifications();
+ } else {
+ Log.w(TAG, "Unknown intent URI: " + uri);
+ }
+ }
+}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java
index d52915fce..0faca2341 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/contact/ContactListFragment.java
@@ -179,6 +179,8 @@ public class ContactListFragment extends BaseFragment implements EventListener {
public void onStart() {
super.onStart();
eventBus.addListener(this);
+ notificationManager.clearAllContactNotifications();
+ notificationManager.clearAllIntroductionNotifications();
loadContacts();
list.startPeriodicUpdate();
}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java
index 4873684cc..a1d88d884 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/forum/ForumListFragment.java
@@ -119,6 +119,7 @@ public class ForumListFragment extends BaseEventFragment implements
@Override
public void onStart() {
super.onStart();
+ notificationManager.clearAllForumPostNotifications();
loadForums();
loadAvailableForums();
list.startPeriodicUpdate();
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java
index 6cde4e955..cbe85631e 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/privategroup/list/GroupListControllerImpl.java
@@ -79,6 +79,7 @@ class GroupListControllerImpl extends DbControllerImpl
throw new IllegalStateException(
"GroupListListener needs to be attached");
eventBus.addListener(this);
+ notificationManager.clearAllGroupMessageNotifications();
}
@Override
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/BriarNotificationBuilder.java b/briar-android/src/main/java/org/briarproject/briar/android/util/BriarNotificationBuilder.java
index 76fab9de4..73c50d8dd 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/util/BriarNotificationBuilder.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/util/BriarNotificationBuilder.java
@@ -6,7 +6,6 @@ import android.support.annotation.ColorRes;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.NotificationCompat;
-import static android.support.v4.app.NotificationCompat.CATEGORY_MESSAGE;
import static android.support.v4.app.NotificationCompat.VISIBILITY_PRIVATE;
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
@@ -15,6 +14,8 @@ public class BriarNotificationBuilder extends NotificationCompat.Builder {
public BriarNotificationBuilder(Context context) {
super(context);
+ // Auto-cancel does not fire the delete intent, see
+ // https://issuetracker.google.com/issues/36961721
setAutoCancel(true);
}
@@ -27,10 +28,8 @@ public class BriarNotificationBuilder extends NotificationCompat.Builder {
boolean show) {
if (Build.VERSION.SDK_INT >= 21) {
setCategory(category);
- if (show)
- setVisibility(VISIBILITY_PRIVATE);
- else
- setVisibility(VISIBILITY_SECRET);
+ if (show) setVisibility(VISIBILITY_PRIVATE);
+ else setVisibility(VISIBILITY_SECRET);
}
return this;
}
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 167ee816b..d95d258da 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
@@ -9,6 +9,7 @@ import org.briarproject.bramble.api.sync.GroupId;
*/
public interface AndroidNotificationManager {
+ // Keys for notification preferences
String PREF_NOTIFY_PRIVATE = "notifyPrivateMessages";
String PREF_NOTIFY_GROUP = "notifyGroupMessages";
String PREF_NOTIFY_FORUM = "notifyForumPosts";
@@ -20,16 +21,31 @@ public interface AndroidNotificationManager {
String PREF_NOTIFY_VIBRATION = "notifyVibration";
String PREF_NOTIFY_LOCK_SCREEN = "notifyLockScreen";
+ // Content URIs for pending intents
+ String CONTACT_URI = "content://org.briarproject.briar/contact";
+ String GROUP_URI = "content://org.briarproject.briar/group";
+ String FORUM_URI = "content://org.briarproject.briar/forum";
+ String BLOG_URI = "content://org.briarproject.briar/blog";
+ String INTRODUCTION_URI = "content://org.briarproject.briar/introduction";
+
void clearContactNotification(ContactId c);
+ void clearAllContactNotifications();
+
void clearGroupMessageNotification(GroupId g);
+ void clearAllGroupMessageNotifications();
+
void clearForumPostNotification(GroupId g);
+ void clearAllForumPostNotifications();
+
void clearBlogPostNotification(GroupId g);
void clearAllBlogPostNotifications();
+ void clearAllIntroductionNotifications();
+
void blockContactNotification(ContactId c);
void unblockContactNotification(ContactId c);