diff --git a/briar-android/res/drawable-hdpi/message_notification_icon.png b/briar-android/res/drawable-hdpi/message_notification_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..082c1000ac6087199b68fd43f6e4851691199ee7 Binary files /dev/null and b/briar-android/res/drawable-hdpi/message_notification_icon.png differ diff --git a/briar-android/res/drawable-hdpi/notification_icon.png b/briar-android/res/drawable-hdpi/ongoing_notification_icon.png similarity index 100% rename from briar-android/res/drawable-hdpi/notification_icon.png rename to briar-android/res/drawable-hdpi/ongoing_notification_icon.png diff --git a/briar-android/res/drawable-ldpi/message_notification_icon.png b/briar-android/res/drawable-ldpi/message_notification_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a88b8f5611705e61713160235273b102a42850a4 Binary files /dev/null and b/briar-android/res/drawable-ldpi/message_notification_icon.png differ diff --git a/briar-android/res/drawable-ldpi/notification_icon.png b/briar-android/res/drawable-ldpi/ongoing_notification_icon.png similarity index 100% rename from briar-android/res/drawable-ldpi/notification_icon.png rename to briar-android/res/drawable-ldpi/ongoing_notification_icon.png diff --git a/briar-android/res/drawable-mdpi/message_notification_icon.png b/briar-android/res/drawable-mdpi/message_notification_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e2d666cc7241b8ade31d14e9bb5bbbad52b5bae2 Binary files /dev/null and b/briar-android/res/drawable-mdpi/message_notification_icon.png differ diff --git a/briar-android/res/drawable-mdpi/notification_icon.png b/briar-android/res/drawable-mdpi/ongoing_notification_icon.png similarity index 100% rename from briar-android/res/drawable-mdpi/notification_icon.png rename to briar-android/res/drawable-mdpi/ongoing_notification_icon.png diff --git a/briar-android/res/drawable-xhdpi/message_notification_icon.png b/briar-android/res/drawable-xhdpi/message_notification_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..b965d932070a7406007e746e9c5266f9de9031c1 Binary files /dev/null and b/briar-android/res/drawable-xhdpi/message_notification_icon.png differ diff --git a/briar-android/res/drawable-xhdpi/notification_icon.png b/briar-android/res/drawable-xhdpi/ongoing_notification_icon.png similarity index 100% rename from briar-android/res/drawable-xhdpi/notification_icon.png rename to briar-android/res/drawable-xhdpi/ongoing_notification_icon.png diff --git a/briar-android/res/values/strings.xml b/briar-android/res/values/strings.xml index 9920a91944c3dabae28c431adf5c4e5d68d8404c..f620adeef5986612c7fe0a47a5f75447d0ff8ec3 100644 --- a/briar-android/res/values/strings.xml +++ b/briar-android/res/values/strings.xml @@ -1,8 +1,8 @@ <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Briar</string> - <string name="notification_title">Briar is running</string> - <string name="notification_text">Touch to show the home screen.</string> + <string name="ongoing_notification_title">Briar is running</string> + <string name="ongoing_notification_text">Touch to show the home screen.</string> <string name="setup_title">Briar Setup</string> <string name="choose_nickname">Choose your nickname:</string> <string name="choose_password">Choose your password:</string> @@ -91,4 +91,8 @@ <string name="message_sent_toast">Message sent</string> <string name="post_sent_toast">Post sent</string> <string name="not_implemented_toast">Not implemented yet!</string> + <string name="private_message_notification_title">New private message</string> + <string name="private_message_notification_text">Touch to show.</string> + <string name="group_post_notification_title">New forum post</string> + <string name="group_post_notification_text">Touch to show.</string> </resources> \ No newline at end of file diff --git a/briar-android/src/org/briarproject/android/BriarService.java b/briar-android/src/org/briarproject/android/BriarService.java index f0a82a053bcbe2da6cffc250c3abc7cc856d1165..96de8c0795eacedc65475a4f3e4bce9485620f15 100644 --- a/briar-android/src/org/briarproject/android/BriarService.java +++ b/briar-android/src/org/briarproject/android/BriarService.java @@ -1,9 +1,11 @@ package org.briarproject.android; +import static android.app.Notification.DEFAULT_ALL; 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 java.util.logging.Level.INFO; +import static java.util.logging.Level.WARNING; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; @@ -13,27 +15,36 @@ import java.util.logging.Logger; import javax.inject.Inject; import org.briarproject.R; +import org.briarproject.android.contact.ContactListActivity; +import org.briarproject.android.groups.GroupListActivity; +import org.briarproject.api.ContactId; import org.briarproject.api.android.AndroidExecutor; import org.briarproject.api.android.DatabaseUiExecutor; import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseConfig; +import org.briarproject.api.db.DbException; +import org.briarproject.api.event.Event; +import org.briarproject.api.event.EventListener; +import org.briarproject.api.event.MessageAddedEvent; import org.briarproject.api.lifecycle.LifecycleManager; +import org.briarproject.api.messaging.GroupId; import roboguice.service.RoboService; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ComponentName; -import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Binder; import android.os.IBinder; import android.support.v4.app.NotificationCompat; -public class BriarService extends RoboService { +public class BriarService extends RoboService implements EventListener { private static final int ONGOING_NOTIFICATION_ID = 1; private static final int FAILURE_NOTIFICATION_ID = 2; + private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3; + private static final int GROUP_POST_NOTIFICATION_ID = 4; private static final Logger LOG = Logger.getLogger(BriarService.class.getName()); @@ -66,9 +77,9 @@ public class BriarService extends RoboService { } // Show an ongoing notification that the service is running NotificationCompat.Builder b = new NotificationCompat.Builder(this); - b.setSmallIcon(R.drawable.notification_icon); - b.setContentTitle(getText(R.string.notification_title)); - b.setContentText(getText(R.string.notification_text)); + b.setSmallIcon(R.drawable.ongoing_notification_icon); + b.setContentTitle(getText(R.string.ongoing_notification_title)); + b.setContentText(getText(R.string.ongoing_notification_text)); b.setWhen(0); // Don't show the time b.setOngoing(true); Intent i = new Intent(this, HomeScreenActivity.class); @@ -81,6 +92,7 @@ public class BriarService extends RoboService { @Override public void run() { if(lifecycleManager.startServices()) { + db.addListener(BriarService.this); started = true; } else { if(LOG.isLoggable(INFO)) LOG.info("Startup failed"); @@ -99,7 +111,7 @@ public class BriarService extends RoboService { Intent i = new Intent(this, HomeScreenActivity.class); i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP); b.setContentIntent(PendingIntent.getActivity(this, 0, i, 0)); - Object o = getSystemService(Context.NOTIFICATION_SERVICE); + Object o = getSystemService(NOTIFICATION_SERVICE); NotificationManager nm = (NotificationManager) o; nm.notify(FAILURE_NOTIFICATION_ID, b.build()); // Bring HomeScreenActivity to the front to clear all other activities @@ -130,11 +142,73 @@ public class BriarService extends RoboService { @Override public void run() { androidExecutor.shutdown(); - if(started) lifecycleManager.stopServices(); + if(started) { + db.removeListener(BriarService.this); + lifecycleManager.stopServices(); + } } }.start(); } + public void eventOccurred(Event e) { + if(e instanceof MessageAddedEvent) { + MessageAddedEvent m = (MessageAddedEvent) e; + GroupId g = m.getGroup().getId(); + ContactId c = m.getContactId(); + if(c != null) showMessageNotification(g, c); + } + } + + private void showMessageNotification(final GroupId g, final ContactId c) { + dbUiExecutor.execute(new Runnable() { + public void run() { + try { + lifecycleManager.waitForDatabase(); + if(g.equals(db.getInboxGroupId(c))) + showPrivateMessageNotification(); + else showGroupPostNotification(); + } catch(DbException e) { + if(LOG.isLoggable(WARNING)) + LOG.log(WARNING, e.toString(), e); + } catch(InterruptedException e) { + if(LOG.isLoggable(INFO)) + LOG.info("Interruped while waiting for database"); + Thread.currentThread().interrupt(); + } + } + }); + } + + private void showPrivateMessageNotification() { + NotificationCompat.Builder b = new NotificationCompat.Builder(this); + b.setSmallIcon(R.drawable.message_notification_icon); + b.setContentTitle(getText(R.string.private_message_notification_title)); + b.setContentText(getText(R.string.private_message_notification_text)); + b.setAutoCancel(true); + b.setDefaults(DEFAULT_ALL); + Intent i = new Intent(this, ContactListActivity.class); + i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP); + b.setContentIntent(PendingIntent.getActivity(this, 0, i, 0)); + Object o = getSystemService(NOTIFICATION_SERVICE); + NotificationManager nm = (NotificationManager) o; + nm.notify(PRIVATE_MESSAGE_NOTIFICATION_ID, b.build()); + } + + private void showGroupPostNotification() { + NotificationCompat.Builder b = new NotificationCompat.Builder(this); + b.setSmallIcon(R.drawable.message_notification_icon); + b.setContentTitle(getText(R.string.group_post_notification_title)); + b.setContentText(getText(R.string.group_post_notification_text)); + b.setAutoCancel(true); + b.setDefaults(DEFAULT_ALL); + Intent i = new Intent(this, GroupListActivity.class); + i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP); + b.setContentIntent(PendingIntent.getActivity(this, 0, i, 0)); + Object o = getSystemService(NOTIFICATION_SERVICE); + NotificationManager nm = (NotificationManager) o; + nm.notify(GROUP_POST_NOTIFICATION_ID, b.build()); + } + /** Waits for the database to be opened before returning. */ public void waitForDatabase() throws InterruptedException { lifecycleManager.waitForDatabase(); diff --git a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java index ded5cf3cdab5dde1828d4f26e35d8b9ff703ec19..b2d4ea85b5e5c4ff4a2573e95b8ae811a6c4b614 100644 --- a/briar-android/src/org/briarproject/android/contact/ConversationActivity.java +++ b/briar-android/src/org/briarproject/android/contact/ConversationActivity.java @@ -185,7 +185,6 @@ implements EventListener, OnClickListener, OnItemClickListener { super.onActivityResult(request, result, data); if(request == REQUEST_READ_MESSAGE && result == RESULT_PREV_NEXT) { int position = data.getIntExtra("briar.POSITION", -1); - if(position == -1) throw new IllegalStateException(); if(position >= 0 && position < adapter.getCount()) displayMessage(position); } diff --git a/briar-android/src/org/briarproject/android/groups/GroupActivity.java b/briar-android/src/org/briarproject/android/groups/GroupActivity.java index 506f16a52ec82e1455426a3929211560ad8c35f6..ff9970b7c0700816f3ba576ac406eb1ed993df21 100644 --- a/briar-android/src/org/briarproject/android/groups/GroupActivity.java +++ b/briar-android/src/org/briarproject/android/groups/GroupActivity.java @@ -173,7 +173,6 @@ OnClickListener, OnItemClickListener { super.onActivityResult(request, result, data); if(request == REQUEST_READ_POST && result == RESULT_PREV_NEXT) { int position = data.getIntExtra("briar.POSITION", -1); - if(position == -1) throw new IllegalStateException(); if(position >= 0 && position < adapter.getCount()) displayMessage(position); }