mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Better notifications. Development task #67.
This commit is contained in:
@@ -76,10 +76,8 @@
|
||||
<string name="add_button">Add</string>
|
||||
<string name="cancel_button">Cancel</string>
|
||||
<string name="post_sent_toast">Post sent</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>
|
||||
<string name="private_message_notification_text">New private message.</string>
|
||||
<string name="group_post_notification_text">New forum post.</string>
|
||||
<string name="settings_title">Settings</string>
|
||||
<string name="activate_bluetooth_option">Activate Bluetooth while signed in</string>
|
||||
<string name="activate_bluetooth_explanation">Briar uses Bluetooth to communicate with nearby contacts</string>
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.util.concurrent.ThreadPoolExecutor;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import org.briarproject.api.android.AndroidExecutor;
|
||||
import org.briarproject.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.api.android.DatabaseUiExecutor;
|
||||
import org.briarproject.api.android.ReferenceManager;
|
||||
import org.briarproject.api.db.DatabaseConfig;
|
||||
@@ -57,9 +58,12 @@ public class AndroidModule extends AbstractModule {
|
||||
}
|
||||
|
||||
protected void configure() {
|
||||
bind(AndroidExecutor.class).to(AndroidExecutorImpl.class);
|
||||
bind(ReferenceManager.class).to(
|
||||
ReferenceManagerImpl.class).in(Singleton.class);
|
||||
bind(AndroidExecutor.class).to(AndroidExecutorImpl.class).in(
|
||||
Singleton.class);
|
||||
bind(AndroidNotificationManager.class).to(
|
||||
AndroidNotificationManagerImpl.class).in(Singleton.class);
|
||||
bind(ReferenceManager.class).to(ReferenceManagerImpl.class).in(
|
||||
Singleton.class);
|
||||
bind(UiCallback.class).toInstance(uiCallback);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
package org.briarproject.android;
|
||||
|
||||
import static android.app.Notification.DEFAULT_ALL;
|
||||
import static android.content.Context.NOTIFICATION_SERVICE;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
|
||||
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import org.briarproject.R;
|
||||
import org.briarproject.android.contact.ContactListActivity;
|
||||
import org.briarproject.android.contact.ConversationActivity;
|
||||
import org.briarproject.android.groups.GroupActivity;
|
||||
import org.briarproject.android.groups.GroupListActivity;
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.api.messaging.GroupId;
|
||||
|
||||
import android.app.Application;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.TaskStackBuilder;
|
||||
|
||||
class AndroidNotificationManagerImpl implements AndroidNotificationManager {
|
||||
|
||||
private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3;
|
||||
private static final int GROUP_POST_NOTIFICATION_ID = 4;
|
||||
|
||||
private final Context appContext;
|
||||
private final Map<ContactId, Integer> contactCounts =
|
||||
new HashMap<ContactId, Integer>(); // Locking: this
|
||||
private final Map<GroupId, Integer> groupCounts =
|
||||
new HashMap<GroupId, Integer>(); // Locking: this
|
||||
|
||||
private int privateTotal = 0, groupTotal = 0; // Locking: this
|
||||
|
||||
@Inject
|
||||
public AndroidNotificationManagerImpl(Application app) {
|
||||
this.appContext = app.getApplicationContext();
|
||||
}
|
||||
|
||||
public synchronized void showPrivateMessageNotification(ContactId c) {
|
||||
Integer count = contactCounts.get(c);
|
||||
if(count == null) contactCounts.put(c, 1);
|
||||
else contactCounts.put(c, count + 1);
|
||||
privateTotal++;
|
||||
updatePrivateMessageNotification();
|
||||
}
|
||||
|
||||
public synchronized void clearPrivateMessageNotification(ContactId c) {
|
||||
Integer count = contactCounts.remove(c);
|
||||
if(count == null) return; // Already cleared
|
||||
privateTotal -= count;
|
||||
updatePrivateMessageNotification();
|
||||
}
|
||||
|
||||
// Locking: this
|
||||
private void updatePrivateMessageNotification() {
|
||||
if(privateTotal == 0) {
|
||||
clearPrivateMessageNotification();
|
||||
} else {
|
||||
NotificationCompat.Builder b =
|
||||
new NotificationCompat.Builder(appContext);
|
||||
b.setSmallIcon(R.drawable.message_notification_icon);
|
||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||
b.setContentText(appContext.getText(
|
||||
R.string.private_message_notification_text));
|
||||
b.setDefaults(DEFAULT_ALL);
|
||||
b.setOnlyAlertOnce(true);
|
||||
if(contactCounts.size() == 1) {
|
||||
Intent i = new Intent(appContext, ConversationActivity.class);
|
||||
ContactId c = contactCounts.keySet().iterator().next();
|
||||
i.putExtra("briar.CONTACT_ID", c.getInt());
|
||||
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP);
|
||||
TaskStackBuilder tsb = TaskStackBuilder.create(appContext);
|
||||
tsb.addParentStack(ConversationActivity.class);
|
||||
tsb.addNextIntent(i);
|
||||
b.setContentIntent(tsb.getPendingIntent(0, 0));
|
||||
} else {
|
||||
Intent i = new Intent(appContext, ContactListActivity.class);
|
||||
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP);
|
||||
TaskStackBuilder tsb = TaskStackBuilder.create(appContext);
|
||||
tsb.addParentStack(ContactListActivity.class);
|
||||
tsb.addNextIntent(i);
|
||||
b.setContentIntent(tsb.getPendingIntent(0, 0));
|
||||
}
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.notify(PRIVATE_MESSAGE_NOTIFICATION_ID, b.build());
|
||||
}
|
||||
}
|
||||
|
||||
// Locking: this
|
||||
private void clearPrivateMessageNotification() {
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.cancel(PRIVATE_MESSAGE_NOTIFICATION_ID);
|
||||
}
|
||||
|
||||
public synchronized void showGroupPostNotification(GroupId g) {
|
||||
Integer count = groupCounts.get(g);
|
||||
if(count == null) groupCounts.put(g, 1);
|
||||
else groupCounts.put(g, count + 1);
|
||||
groupTotal++;
|
||||
updateGroupPostNotification();
|
||||
}
|
||||
|
||||
public synchronized void clearGroupPostNotification(GroupId g) {
|
||||
Integer count = groupCounts.remove(g);
|
||||
if(count == null) return; // Already cleared
|
||||
groupTotal -= count;
|
||||
updateGroupPostNotification();
|
||||
}
|
||||
|
||||
// Locking: this
|
||||
private void updateGroupPostNotification() {
|
||||
if(groupTotal == 0) {
|
||||
clearGroupPostNotification();
|
||||
} else {
|
||||
NotificationCompat.Builder b =
|
||||
new NotificationCompat.Builder(appContext);
|
||||
b.setSmallIcon(R.drawable.message_notification_icon);
|
||||
b.setContentTitle(appContext.getText(R.string.app_name));
|
||||
b.setContentText(appContext.getText(
|
||||
R.string.group_post_notification_text));
|
||||
b.setDefaults(DEFAULT_ALL);
|
||||
b.setOnlyAlertOnce(true);
|
||||
if(groupCounts.size() == 1) {
|
||||
Intent i = new Intent(appContext, GroupActivity.class);
|
||||
GroupId g = groupCounts.keySet().iterator().next();
|
||||
i.putExtra("briar.GROUP_ID", g.getBytes());
|
||||
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP);
|
||||
TaskStackBuilder tsb = TaskStackBuilder.create(appContext);
|
||||
tsb.addParentStack(GroupActivity.class);
|
||||
tsb.addNextIntent(i);
|
||||
b.setContentIntent(tsb.getPendingIntent(0, 0));
|
||||
} else {
|
||||
Intent i = new Intent(appContext, GroupListActivity.class);
|
||||
i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_SINGLE_TOP);
|
||||
TaskStackBuilder tsb = TaskStackBuilder.create(appContext);
|
||||
tsb.addParentStack(GroupListActivity.class);
|
||||
tsb.addNextIntent(i);
|
||||
b.setContentIntent(tsb.getPendingIntent(0, 0));
|
||||
}
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.notify(GROUP_POST_NOTIFICATION_ID, b.build());
|
||||
}
|
||||
}
|
||||
|
||||
// Locking: this
|
||||
private void clearGroupPostNotification() {
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.cancel(GROUP_POST_NOTIFICATION_ID);
|
||||
}
|
||||
|
||||
public synchronized void clearNotifications() {
|
||||
contactCounts.clear();
|
||||
groupCounts.clear();
|
||||
privateTotal = groupTotal = 0;
|
||||
clearPrivateMessageNotification();
|
||||
clearGroupPostNotification();
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
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;
|
||||
@@ -15,10 +14,9 @@ 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.AndroidNotificationManager;
|
||||
import org.briarproject.api.android.DatabaseUiExecutor;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DatabaseConfig;
|
||||
@@ -38,14 +36,11 @@ import android.content.ServiceConnection;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.TaskStackBuilder;
|
||||
|
||||
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());
|
||||
@@ -54,6 +49,7 @@ public class BriarService extends RoboService implements EventListener {
|
||||
private final Binder binder = new BriarBinder();
|
||||
|
||||
@Inject private DatabaseConfig databaseConfig;
|
||||
@Inject private AndroidNotificationManager notificationManager;
|
||||
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
@Inject private volatile LifecycleManager lifecycleManager;
|
||||
@@ -135,11 +131,8 @@ public class BriarService extends RoboService implements EventListener {
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Destroyed");
|
||||
Object o = getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.cancel(PRIVATE_MESSAGE_NOTIFICATION_ID);
|
||||
nm.cancel(GROUP_POST_NOTIFICATION_ID);
|
||||
stopForeground(true);
|
||||
notificationManager.clearNotifications();
|
||||
// Stop the services in a background thread
|
||||
new Thread() {
|
||||
@Override
|
||||
@@ -168,8 +161,8 @@ public class BriarService extends RoboService implements EventListener {
|
||||
try {
|
||||
lifecycleManager.waitForDatabase();
|
||||
if(g.equals(db.getInboxGroupId(c)))
|
||||
showPrivateMessageNotification();
|
||||
else showGroupPostNotification();
|
||||
notificationManager.showPrivateMessageNotification(c);
|
||||
else notificationManager.showGroupPostNotification(g);
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
@@ -182,42 +175,6 @@ public class BriarService extends RoboService implements EventListener {
|
||||
});
|
||||
}
|
||||
|
||||
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);
|
||||
TaskStackBuilder tsb = TaskStackBuilder.create(this);
|
||||
tsb.addParentStack(ContactListActivity.class);
|
||||
tsb.addNextIntent(i);
|
||||
b.setContentIntent(tsb.getPendingIntent(0, 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);
|
||||
TaskStackBuilder tsb = TaskStackBuilder.create(this);
|
||||
tsb.addParentStack(GroupListActivity.class);
|
||||
tsb.addNextIntent(i);
|
||||
b.setContentIntent(tsb.getPendingIntent(0, 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();
|
||||
|
||||
@@ -37,7 +37,9 @@ import org.briarproject.android.util.HorizontalBorder;
|
||||
import org.briarproject.android.util.LayoutUtils;
|
||||
import org.briarproject.android.util.ListLoadingProgressBar;
|
||||
import org.briarproject.api.AuthorId;
|
||||
import org.briarproject.api.Contact;
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.api.crypto.CryptoExecutor;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
@@ -81,9 +83,9 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(ConversationActivity.class.getName());
|
||||
|
||||
@Inject private AndroidNotificationManager notificationManager;
|
||||
@Inject @CryptoExecutor private Executor cryptoExecutor;
|
||||
private Map<MessageId, byte[]> bodyCache = new HashMap<MessageId, byte[]>();
|
||||
private String contactName = null;
|
||||
private TextView empty = null;
|
||||
private ConversationAdapter adapter = null;
|
||||
private ListView list = null;
|
||||
@@ -95,6 +97,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
@Inject private volatile DatabaseComponent db;
|
||||
@Inject private volatile MessageFactory messageFactory;
|
||||
private volatile ContactId contactId = null;
|
||||
private volatile String contactName = null;
|
||||
private volatile GroupId groupId = null;
|
||||
private volatile Group group = null;
|
||||
private volatile AuthorId localAuthorId = null;
|
||||
@@ -107,15 +110,6 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
int id = i.getIntExtra("briar.CONTACT_ID", -1);
|
||||
if(id == -1) throw new IllegalStateException();
|
||||
contactId = new ContactId(id);
|
||||
contactName = i.getStringExtra("briar.CONTACT_NAME");
|
||||
if(contactName == null) throw new IllegalStateException();
|
||||
setTitle(contactName);
|
||||
byte[] b = i.getByteArrayExtra("briar.GROUP_ID");
|
||||
if(b == null) throw new IllegalStateException();
|
||||
groupId = new GroupId(b);
|
||||
b = i.getByteArrayExtra("briar.LOCAL_AUTHOR_ID");
|
||||
if(b == null) throw new IllegalStateException();
|
||||
localAuthorId = new AuthorId(b);
|
||||
|
||||
Intent data = new Intent();
|
||||
data.putExtra("briar.CONTACT_ID", id);
|
||||
@@ -194,25 +188,59 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
db.addListener(this);
|
||||
loadHeadersAndGroup();
|
||||
loadContactAndGroup();
|
||||
loadHeaders();
|
||||
}
|
||||
|
||||
private void loadHeadersAndGroup() {
|
||||
private void loadContactAndGroup() {
|
||||
runOnDbThread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
long now = System.currentTimeMillis();
|
||||
Contact contact = db.getContact(contactId);
|
||||
contactName = contact.getAuthor().getName();
|
||||
localAuthorId = contact.getLocalAuthorId();
|
||||
groupId = db.getInboxGroupId(contactId);
|
||||
group = db.getGroup(groupId);
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO)) {
|
||||
LOG.info("Loading contact and group took "
|
||||
+ duration + " ms");
|
||||
}
|
||||
displayContactName();
|
||||
} catch(NoSuchContactException e) {
|
||||
finishOnUiThread();
|
||||
} catch(NoSuchSubscriptionException e) {
|
||||
finishOnUiThread();
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void displayContactName() {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
setTitle(contactName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadHeaders() {
|
||||
runOnDbThread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
long now = System.currentTimeMillis();
|
||||
Collection<MessageHeader> headers =
|
||||
db.getInboxMessageHeaders(contactId);
|
||||
group = db.getGroup(groupId);
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info("Load took " + duration + " ms");
|
||||
LOG.info("Loading headers took " + duration + " ms");
|
||||
displayHeaders(headers);
|
||||
} catch(NoSuchContactException e) {
|
||||
finishOnUiThread();
|
||||
} catch(NoSuchSubscriptionException e) {
|
||||
finishOnUiThread();
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
@@ -225,6 +253,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
loading.setVisibility(GONE);
|
||||
setTitle(contactName);
|
||||
sendButton.setEnabled(true);
|
||||
adapter.clear();
|
||||
if(headers.isEmpty()) {
|
||||
@@ -306,6 +335,7 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
}
|
||||
|
||||
private void markMessagesRead() {
|
||||
notificationManager.clearPrivateMessageNotification(contactId);
|
||||
List<MessageId> unread = new ArrayList<MessageId>();
|
||||
int count = adapter.getCount();
|
||||
for(int i = 0; i < count; i++) {
|
||||
@@ -346,11 +376,11 @@ implements EventListener, OnClickListener, OnItemClickListener {
|
||||
GroupId g = ((MessageAddedEvent) e).getGroup().getId();
|
||||
if(g.equals(groupId)) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Message added, reloading");
|
||||
loadHeadersAndGroup();
|
||||
loadHeaders();
|
||||
}
|
||||
} else if(e instanceof MessageExpiredEvent) {
|
||||
if(LOG.isLoggable(INFO)) LOG.info("Message expired, reloading");
|
||||
loadHeadersAndGroup();
|
||||
loadHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.briarproject.android.BriarActivity;
|
||||
import org.briarproject.android.util.HorizontalBorder;
|
||||
import org.briarproject.android.util.ListLoadingProgressBar;
|
||||
import org.briarproject.api.Author;
|
||||
import org.briarproject.api.android.AndroidNotificationManager;
|
||||
import org.briarproject.api.db.DatabaseComponent;
|
||||
import org.briarproject.api.db.DbException;
|
||||
import org.briarproject.api.db.MessageHeader;
|
||||
@@ -37,6 +38,7 @@ import org.briarproject.api.event.EventListener;
|
||||
import org.briarproject.api.event.MessageAddedEvent;
|
||||
import org.briarproject.api.event.MessageExpiredEvent;
|
||||
import org.briarproject.api.event.SubscriptionRemovedEvent;
|
||||
import org.briarproject.api.messaging.Group;
|
||||
import org.briarproject.api.messaging.GroupId;
|
||||
import org.briarproject.api.messaging.MessageId;
|
||||
|
||||
@@ -59,8 +61,8 @@ OnClickListener, OnItemClickListener {
|
||||
private static final Logger LOG =
|
||||
Logger.getLogger(GroupActivity.class.getName());
|
||||
|
||||
@Inject private AndroidNotificationManager notificationManager;
|
||||
private Map<MessageId, byte[]> bodyCache = new HashMap<MessageId, byte[]>();
|
||||
private String groupName = null;
|
||||
private TextView empty = null;
|
||||
private GroupAdapter adapter = null;
|
||||
private ListView list = null;
|
||||
@@ -69,6 +71,7 @@ OnClickListener, OnItemClickListener {
|
||||
// Fields that are accessed from background threads must be volatile
|
||||
@Inject private volatile DatabaseComponent db;
|
||||
private volatile GroupId groupId = null;
|
||||
private volatile String groupName = null;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle state) {
|
||||
@@ -78,9 +81,6 @@ OnClickListener, OnItemClickListener {
|
||||
byte[] b = i.getByteArrayExtra("briar.GROUP_ID");
|
||||
if(b == null) throw new IllegalStateException();
|
||||
groupId = new GroupId(b);
|
||||
groupName = i.getStringExtra("briar.GROUP_NAME");
|
||||
if(groupName == null) throw new IllegalStateException();
|
||||
setTitle(groupName);
|
||||
|
||||
LinearLayout layout = new LinearLayout(this);
|
||||
layout.setLayoutParams(MATCH_MATCH);
|
||||
@@ -128,9 +128,39 @@ OnClickListener, OnItemClickListener {
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
db.addListener(this);
|
||||
loadGroup();
|
||||
loadHeaders();
|
||||
}
|
||||
|
||||
private void loadGroup() {
|
||||
runOnDbThread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
long now = System.currentTimeMillis();
|
||||
Group g = db.getGroup(groupId);
|
||||
groupName = g.getName();
|
||||
long duration = System.currentTimeMillis() - now;
|
||||
if(LOG.isLoggable(INFO))
|
||||
LOG.info("Loading group " + duration + " ms");
|
||||
displayGroupName();
|
||||
} catch(NoSuchSubscriptionException e) {
|
||||
finishOnUiThread();
|
||||
} catch(DbException e) {
|
||||
if(LOG.isLoggable(WARNING))
|
||||
LOG.log(WARNING, e.toString(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void displayGroupName() {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
setTitle(groupName);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void loadHeaders() {
|
||||
runOnDbThread(new Runnable() {
|
||||
public void run() {
|
||||
@@ -236,6 +266,7 @@ OnClickListener, OnItemClickListener {
|
||||
}
|
||||
|
||||
private void markMessagesRead() {
|
||||
notificationManager.clearGroupPostNotification(groupId);
|
||||
List<MessageId> unread = new ArrayList<MessageId>();
|
||||
int count = adapter.getCount();
|
||||
for(int i = 0; i < count; i++) {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
package org.briarproject.api.android;
|
||||
|
||||
import org.briarproject.api.ContactId;
|
||||
import org.briarproject.api.messaging.GroupId;
|
||||
|
||||
/**
|
||||
* Manages notifications for private messages and group posts. All methods must
|
||||
* be called from the Android UI thread.
|
||||
*/
|
||||
public interface AndroidNotificationManager {
|
||||
|
||||
public void showPrivateMessageNotification(ContactId c);
|
||||
|
||||
public void clearPrivateMessageNotification(ContactId c);
|
||||
|
||||
public void showGroupPostNotification(GroupId g);
|
||||
|
||||
public void clearGroupPostNotification(GroupId g);
|
||||
|
||||
public void clearNotifications();
|
||||
}
|
||||
Reference in New Issue
Block a user