From f17a7608050c30792db8247af997ddeb5c0e049f Mon Sep 17 00:00:00 2001
From: akwizgran <akwizgran@users.sourceforge.net>
Date: Wed, 5 Feb 2014 17:19:24 +0000
Subject: [PATCH] Show notifications when messages are received. Dev task #30.

---
 .../message_notification_icon.png             | Bin 0 -> 366 bytes
 ...icon.png => ongoing_notification_icon.png} | Bin
 .../message_notification_icon.png             | Bin 0 -> 210 bytes
 ...icon.png => ongoing_notification_icon.png} | Bin
 .../message_notification_icon.png             | Bin 0 -> 175 bytes
 ...icon.png => ongoing_notification_icon.png} | Bin
 .../message_notification_icon.png             | Bin 0 -> 515 bytes
 ...icon.png => ongoing_notification_icon.png} | Bin
 briar-android/res/values/strings.xml          |   8 +-
 .../briarproject/android/BriarService.java    |  88 ++++++++++++++++--
 .../android/contact/ConversationActivity.java |   1 -
 .../android/groups/GroupActivity.java         |   1 -
 12 files changed, 87 insertions(+), 11 deletions(-)
 create mode 100644 briar-android/res/drawable-hdpi/message_notification_icon.png
 rename briar-android/res/drawable-hdpi/{notification_icon.png => ongoing_notification_icon.png} (100%)
 create mode 100644 briar-android/res/drawable-ldpi/message_notification_icon.png
 rename briar-android/res/drawable-ldpi/{notification_icon.png => ongoing_notification_icon.png} (100%)
 create mode 100644 briar-android/res/drawable-mdpi/message_notification_icon.png
 rename briar-android/res/drawable-mdpi/{notification_icon.png => ongoing_notification_icon.png} (100%)
 create mode 100644 briar-android/res/drawable-xhdpi/message_notification_icon.png
 rename briar-android/res/drawable-xhdpi/{notification_icon.png => ongoing_notification_icon.png} (100%)

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
GIT binary patch
literal 366
zcmV-!0g?WRP)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ00001b5ch_0Itp)
z=>Px$C`m*?R9M69S3wfPAP5wO|35kO(2yYrmZWNOa8FL7%Ze=8QWh2##sXx(%>1Yj
z04Svt@;=Vewre<nv<R8tO`HXc)Q-%OaC<Q*v!GYTG+(sgD$=%X94)#lO!H`7062;{
z6r_d8Vk<5y%-fLgK|pe{y*G)!2#GTp(Z3_28>6y4GatQ33zM-HmMwUpX$h$|>m5;a
zzM7<2nCe?3<Y!~lv1KeGy^KlmM=iq>;?-qUpVnQG8|+cq-L{I=I@dFatb>TS)k7d@
zGs#HCiIP#e)6itc-m%ykx!Nu$>lTmL3bU@UwUPm4yKU>@jgI@yWsN<a4|@;ma^KOv
z1ihasSYC#A3%cTlQO{VM{f_o}oEC+iV`hr6F{#x6pZM3Yu&^*1A29Y0IGaWjI{*Lx
M07*qoM6N<$f?=(oQ2+n{

literal 0
HcmV?d00001

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
GIT binary patch
literal 210
zcmeAS@N?(olHy`uVBq!ia0vp^LLkh+1|-AI^@Rf|#^NA%Cx&(BWL^R}J)SO(Ar`0K
z208K_HsIJC`2T;(ox@%(cf*{m{ho>(J$8fhz<n`B1!LDw<${w6Wf&MH9XoqYSJ6v~
zv+T`_hh1qdU)$t%cDu0X=P&V}d*IBJ<7zu)zARkhUH`^U@1Wh0Sa+72jQtP3o!<HX
zLs3Y}Nq(!i!sHFgi%W0JoApl3I{eb1?SAv#oxl6xK=l1A_L87HVYi%)(?EAIc)I$z
JtaD0e0swx3RcrtN

literal 0
HcmV?d00001

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
GIT binary patch
literal 175
zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|GCf@!Lp+YZ
zogBz@K!L|u_~XCucl%m=OJ;4<a{9b-+j%vvma=Y!gtTXu=A?X@r=Yv>#9_5bH4Oil
zrXD*x;r(o_6``j$MVJRW<frd$xcTU!YFop+^`}ZIkKMOYR-M0w<>%AZx&J3K3s^ab
YTg14CwcZhw0b0u7>FVdQ&MBb@0IoVitN;K2

literal 0
HcmV?d00001

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
GIT binary patch
literal 515
zcmV+e0{s1nP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm00001b5ch_0Itp)
z=>Px$y-7qtRA}DqSlf2PAPmDC{{NHlUdE2=NZ_O-qZ@u{(h!h*ks&E<+qP}nw*PEm
zZ&X!R1ZiQ3ND`4B+<ElEQr;FhV9OEKD}gu8PbsBTdZ1S&K?&G_tJZ<XmOXIGQdM6V
zKM@hXo(JwR98{>~na?+re|M7bfbH5=g#^5;OuiVoJ3zDf#XZPqKpTW6LEf2>F8;qm
zsu)}}g~%d`2%z7H0N8OTO}&uFV8WM&wN~|=&J#g^StLf0Li6;1Hw^Y!K^{T_+qI2|
zUz9}wJ@*QSwh732p}mj~Z6qQr%}|t3u}0TW)s%CVu8g8Z{EHFQLQ(Pe2zX0n*2Jic
z)>?Jckt0M{u}6TTb;A+x6R-kn*U@~vnvRhIrvz9*qUIKfNH0}-jcX*WWwiSnZKl2f
z=pnQn{bqGT^1a(I%h|0glD?i!Gm+@^iZk1kFaaiirXDB}-#eJ6uUNi%u!vZ#Rh!p)
zk$cC=yA!Y+MSbKB5@m)L*tx;UXL!T+IDwIJ+0))^n@-^Avvp1%Zhwowil0+P2cvTK
z%(?=RA%Q#OZpIgja0FQ6S@Fx<$3$S|8r`;S+qP}LXJ2I0;9N6{xRL+>002ovPDHLk
FV1f)N?j`^L

literal 0
HcmV?d00001

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 9920a91944..f620adeef5 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 f0a82a053b..96de8c0795 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 ded5cf3cda..b2d4ea85b5 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 506f16a52e..ff9970b7c0 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);
 		}
-- 
GitLab