--- a/src/com/beem/project/beem/BeemService.java Tue Jul 24 18:30:07 2012 +0200
+++ b/src/com/beem/project/beem/BeemService.java Fri Aug 10 05:38:39 2012 +0200
@@ -223,8 +223,8 @@
if (!"".equals(tmpPort))
mPort = Integer.parseInt(tmpPort);
}
- if (mSettings.getBoolean(BeemApplication.FULL_JID_LOGIN_KEY, false) ||
- "gmail.com".equals(mService) || "googlemail.com".equals(mService)) {
+ if (mSettings.getBoolean(BeemApplication.FULL_JID_LOGIN_KEY, false)
+ || "gmail.com".equals(mService) || "googlemail.com".equals(mService)) {
mLogin = tmpJid;
}
@@ -291,8 +291,9 @@
notif.ledARGB = 0xff0000ff; // Blue color
notif.ledOnMS = 1000;
notif.ledOffMS = 1000;
- notif.defaults |= Notification.DEFAULT_LIGHTS;
- String ringtoneStr = mSettings.getString(BeemApplication.NOTIFICATION_SOUND_KEY, Settings.System.DEFAULT_NOTIFICATION_URI.toString());
+ notif.flags |= Notification.FLAG_SHOW_LIGHTS;
+ String ringtoneStr = mSettings.getString(BeemApplication.NOTIFICATION_SOUND_KEY,
+ Settings.System.DEFAULT_NOTIFICATION_URI.toString());
notif.sound = Uri.parse(ringtoneStr);
mNotificationManager.notify(id, notif);
}
--- a/src/com/beem/project/beem/service/BeemChatManager.java Tue Jul 24 18:30:07 2012 +0200
+++ b/src/com/beem/project/beem/service/BeemChatManager.java Fri Aug 10 05:38:39 2012 +0200
@@ -44,12 +44,37 @@
package com.beem.project.beem.service;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.preference.PreferenceManager;
+import android.support.v4.app.NotificationCompat;
+import android.util.Log;
+
+import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.BeemService;
+import com.beem.project.beem.R;
+import com.beem.project.beem.providers.AvatarProvider;
+import com.beem.project.beem.service.aidl.IChat;
+import com.beem.project.beem.service.aidl.IChatManager;
+import com.beem.project.beem.service.aidl.IChatManagerListener;
+import com.beem.project.beem.service.aidl.IMessageListener;
+import com.beem.project.beem.service.aidl.IRoster;
+import com.beem.project.beem.utils.Status;
+
import net.java.otr4j.OtrException;
import org.jivesoftware.smack.Chat;
@@ -60,25 +85,6 @@
import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.util.StringUtils;
-import android.app.Notification;
-import android.app.PendingIntent;
-import android.content.Intent;
-import android.content.SharedPreferences;
-import android.os.Environment;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.preference.PreferenceManager;
-import android.util.Log;
-
-import com.beem.project.beem.BeemApplication;
-import com.beem.project.beem.BeemService;
-import com.beem.project.beem.service.aidl.IChat;
-import com.beem.project.beem.service.aidl.IChatManager;
-import com.beem.project.beem.service.aidl.IChatManagerListener;
-import com.beem.project.beem.service.aidl.IMessageListener;
-import com.beem.project.beem.service.aidl.IRoster;
-import com.beem.project.beem.utils.Status;
-
/**
* An adapter for smack's ChatManager. This class provides functionnality to handle chats.
* @author darisk
@@ -92,6 +98,7 @@
private final RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners =
new RemoteCallbackList<IChatManagerListener>();
private final BeemService mService;
+ private final Roster mRoster;
private final ChatRosterListener mChatRosterListn = new ChatRosterListener();
/**
@@ -103,7 +110,8 @@
public BeemChatManager(final ChatManager chatManager, final BeemService service, final Roster roster) {
mService = service;
mAdaptee = chatManager;
- roster.addRosterListener(mChatRosterListn);
+ mRoster = roster;
+ mRoster.addRosterListener(mChatRosterListn);
mAdaptee.addChatListener(mChatListener);
}
@@ -212,11 +220,10 @@
*/
public List<Contact> getOpenedChatList() throws RemoteException {
List<Contact> openedChats = new ArrayList<Contact>();
- IRoster mRoster = mService.getBind().getRoster();
-
+ IRoster r = mService.getBind().getRoster();
for (ChatAdapter chat : mChats.values()) {
if (chat.getMessages().size() > 0) {
- Contact t = mRoster.getContact(chat.getParticipant().getJID());
+ Contact t = r.getContact(chat.getParticipant().getJID());
if (t == null)
t = new Contact(chat.getParticipant().getJID());
openedChats.add(t);
@@ -294,21 +301,48 @@
* @param msgBody the body of the new message
*/
private void notifyNewChat(IChat chat, String msgBody) {
- SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(mService);
+ NotificationCompat.Builder notif = new NotificationCompat.Builder(mService);
try {
- CharSequence tickerText = mService.getBind().getRoster().getContact(chat.getParticipant().getJID())
- .getName();
- Notification notification = new Notification(android.R.drawable.stat_notify_chat, tickerText, System
- .currentTimeMillis());
- notification.flags = Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
- notification.setLatestEventInfo(mService, tickerText, msgBody, makeChatIntent(chat));
- mService.sendNotification(chat.getParticipant().getJID().hashCode(), notification);
+ String contactJid = chat.getParticipant().getJID();
+ Contact c = mService.getBind().getRoster().getContact(contactJid);
+ String contactName = contactJid;
+ if (c != null) {
+ contactName = c.getName();
+ Bitmap avatar = getAvatar(c);
+ notif.setLargeIcon(avatar);
+ }
+ notif.setTicker(contactName).setContentTitle(contactName);
+ notif.setContentText(msgBody);
+ notif.setSmallIcon(R.drawable.beem_status_icon_gray);
+ notif.setNumber(chat.getUnreadMessageCount());
+ notif.setContentIntent(makeChatIntent(chat));
+ notif.setAutoCancel(true).setWhen(System.currentTimeMillis());
+ mService.sendNotification(chat.getParticipant().getJID().hashCode(), notif.getNotification());
} catch (RemoteException e) {
Log.e(TAG, e.getMessage());
}
}
/**
+ * Get the avatar of a contact.
+ * @param c the contact
+ * @return the avatar of c or null if avatar is not defined
+ */
+ private Bitmap getAvatar(Contact c) {
+ String id = c.getAvatarId();
+ if (id == null)
+ id = "";
+ Uri uri = AvatarProvider.CONTENT_URI.buildUpon().appendPath(id).build();
+ try {
+ InputStream in = mService.getContentResolver().openInputStream(uri);
+ return BitmapFactory.decodeStream(in);
+ } catch (FileNotFoundException e) {
+ Log.d(TAG, "Error loading avatar id: " + id, e);
+ return null;
+ }
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
--- a/src/com/beem/project/beem/service/ChatAdapter.java Tue Jul 24 18:30:07 2012 +0200
+++ b/src/com/beem/project/beem/service/ChatAdapter.java Fri Aug 10 05:38:39 2012 +0200
@@ -50,6 +50,15 @@
import java.util.LinkedList;
import java.util.List;
+import android.os.Environment;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.beem.project.beem.otr.BeemOtrManager;
+import com.beem.project.beem.service.aidl.IChat;
+import com.beem.project.beem.service.aidl.IMessageListener;
+
import net.java.otr4j.OtrException;
import net.java.otr4j.session.SessionID;
@@ -59,15 +68,6 @@
import org.jivesoftware.smackx.ChatState;
import org.jivesoftware.smackx.ChatStateListener;
-import android.os.Environment;
-import android.os.RemoteCallbackList;
-import android.os.RemoteException;
-import android.util.Log;
-
-import com.beem.project.beem.otr.BeemOtrManager;
-import com.beem.project.beem.service.aidl.IChat;
-import com.beem.project.beem.service.aidl.IMessageListener;
-
/**
* An adapter for smack's Chat class.
* @author darisk
@@ -88,6 +88,7 @@
private boolean mIsHistory;
private File mHistoryPath;
private String mAccountUser;
+ private int mUnreadMsgCount;
/**
* Constructor.
@@ -204,6 +205,8 @@
@Override
public void setOpen(boolean isOpen) {
this.mIsOpen = isOpen;
+ if (isOpen)
+ mUnreadMsgCount = 0;
}
/**
@@ -230,6 +233,8 @@
if (mMessages.size() == HISTORY_MAX_SIZE)
mMessages.remove(0);
mMessages.add(msg);
+ if (!isOpen())
+ mUnreadMsgCount++;
if (!"".equals(msg.getBody()) && msg.getBody() != null) {
logMessage(msg);
}
@@ -327,7 +332,8 @@
if (mOtrSessionId != null && unencrypted != null && unencrypted.getBody() != null) {
try {
- String body = BeemOtrManager.getInstance().getOtrManager().transformSending(mOtrSessionId, unencrypted.getBody());
+ String body = BeemOtrManager.getInstance().getOtrManager()
+ .transformSending(mOtrSessionId, unencrypted.getBody());
Message result = new Message(unencrypted.getTo(), unencrypted.getType());
result.setBody(body);
return result;
@@ -339,67 +345,6 @@
}
/**
- * Listener.
- */
- private class MsgListener implements ChatStateListener {
- /**
- * Constructor.
- */
- public MsgListener() {
- }
-
- @Override
- public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
- Message msg = new Message(message);
- Log.d(TAG, "new msg " + msg.getBody());
- String body;
-
- if (mOtrSessionId != null) {
- try {
- body = BeemOtrManager.getInstance().getOtrManager()
- .transformReceiving(mOtrSessionId, msg.getBody());
- msg.setBody(body);
- } catch (OtrException e) {
- Log.w(TAG, "Unable to decrypt OTR message", e);
- }
- }
- //TODO add que les message pas de type errors
- ChatAdapter.this.addMessage(msg);
- final int n = mRemoteListeners.beginBroadcast();
- for (int i = 0; i < n; i++) {
- IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
- try {
- if (listener != null)
- listener.processMessage(ChatAdapter.this, msg);
- } catch (RemoteException e) {
- Log.w(TAG, "Error while diffusing message to listener", e);
- }
- }
- mRemoteListeners.finishBroadcast();
- }
-
- /**
- * {@inheritDoc}
- */
- @Override
- public void stateChanged(Chat chat, ChatState state) {
- mState = state.name();
- final int n = mRemoteListeners.beginBroadcast();
-
- for (int i = 0; i < n; i++) {
- IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
- try {
- listener.stateChanged(ChatAdapter.this);
- } catch (RemoteException e) {
- Log.w(TAG, e.getMessage());
- }
- }
- mRemoteListeners.finishBroadcast();
- }
-
- }
-
- /**
* This method is executed when the otr session status change.
* @param otrState the new state of otr session.
*/
@@ -462,6 +407,9 @@
return true;
}
+ /**
+ * Start listenning to an OTR session.
+ */
public void listenOtrSession() {
if (mOtrSessionId != null)
return;
@@ -504,4 +452,71 @@
return null;
return BeemOtrManager.getInstance().getOtrManager().getSessionStatus(mOtrSessionId).toString();
}
+
+ @Override
+ public int getUnreadMessageCount() throws RemoteException {
+ return mUnreadMsgCount;
+ }
+
+ /**
+ * Listener.
+ */
+ private class MsgListener implements ChatStateListener {
+ /**
+ * Constructor.
+ */
+ public MsgListener() {
+ }
+
+ @Override
+ public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
+ Message msg = new Message(message);
+ Log.d(TAG, "new msg " + msg.getBody());
+ String body;
+
+ if (mOtrSessionId != null) {
+ try {
+ body = BeemOtrManager.getInstance().getOtrManager()
+ .transformReceiving(mOtrSessionId, msg.getBody());
+ msg.setBody(body);
+ } catch (OtrException e) {
+ Log.w(TAG, "Unable to decrypt OTR message", e);
+ }
+ }
+ //TODO add que les message pas de type errors
+ ChatAdapter.this.addMessage(msg);
+ final int n = mRemoteListeners.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
+ try {
+ if (listener != null)
+ listener.processMessage(ChatAdapter.this, msg);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Error while diffusing message to listener", e);
+ }
+ }
+ mRemoteListeners.finishBroadcast();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void stateChanged(Chat chat, ChatState state) {
+ mState = state.name();
+ final int n = mRemoteListeners.beginBroadcast();
+
+ for (int i = 0; i < n; i++) {
+ IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
+ try {
+ listener.stateChanged(ChatAdapter.this);
+ } catch (RemoteException e) {
+ Log.w(TAG, e.getMessage());
+ }
+ }
+ mRemoteListeners.finishBroadcast();
+ }
+
+ }
+
}
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java Tue Jul 24 18:30:07 2012 +0200
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java Fri Aug 10 05:38:39 2012 +0200
@@ -53,6 +53,7 @@
import android.content.SharedPreferences;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
+import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.beem.project.beem.BeemApplication;
@@ -119,7 +120,8 @@
private BeemAvatarManager mAvatarManager;
private PepSubManager mPepManager;
private SharedPreferences mPref;
- private final RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners = new RemoteCallbackList<IBeemConnectionListener>();
+ private final RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners =
+ new RemoteCallbackList<IBeemConnectionListener>();
private final SubscribePacketListener mSubscribePacketListener = new SubscribePacketListener();
private final PingListener mPingListener = new PingListener();
@@ -665,25 +667,7 @@
}
};
- mAdaptee.addPacketListener(new PacketListener() {
-
- @Override
- public void processPacket(Packet packet) {
- String from = packet.getFrom();
- Notification notif = new Notification(android.R.drawable.stat_notify_more, mService.getString(
- R.string.AcceptContactRequest, from), System.currentTimeMillis());
- notif.flags = Notification.FLAG_AUTO_CANCEL;
- Intent intent = new Intent(mService, Subscription.class);
- intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtra("from", from);
- notif.setLatestEventInfo(mService, from,
- mService.getString(R.string.AcceptContactRequestFrom, from),
- PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
- int id = packet.hashCode();
- mService.sendNotification(id, notif);
- Presence p = (Presence) packet;
- updateNotification(Status.getStatusFromPresence(p), p.getStatus());
- }
- }, filter);
+ mAdaptee.addPacketListener(mSubscribePacketListener, filter);
final int n = mRemoteConnListeners.beginBroadcast();
@@ -716,22 +700,24 @@
@Override
public void processPacket(Packet packet) {
- if (!(packet instanceof Presence))
- return;
- Presence p = (Presence) packet;
- if (p.getType() != Presence.Type.subscribe)
- return;
- String from = p.getFrom();
- Notification notification = new Notification(android.R.drawable.stat_notify_more, mService.getString(
- R.string.AcceptContactRequest, from), System.currentTimeMillis());
- notification.flags = Notification.FLAG_AUTO_CANCEL;
+ String from = packet.getFrom();
+
+ NotificationCompat.Builder notif = new NotificationCompat.Builder(mService);
+ String title = mService.getString(R.string.AcceptContactRequest, from);
+ String text = mService.getString(R.string.AcceptContactRequestFrom, from);
+ notif.setTicker(title).setContentTitle(title);
+ notif.setContentText(text);
+ notif.setSmallIcon(R.drawable.beem_status_icon_gray);
+ notif.setAutoCancel(true).setWhen(System.currentTimeMillis());
+
Intent intent = new Intent(mService, Subscription.class);
intent.setData(Contact.makeXmppUri(from));
- notification.setLatestEventInfo(mService, from,
- mService.getString(R.string.AcceptContactRequestFrom, from),
- PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
- int id = p.hashCode();
- mService.sendNotification(id, notification);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ PendingIntent notifIntent = PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT);
+ notif.setContentIntent(notifIntent);
+
+ int id = packet.hashCode();
+ mService.sendNotification(id, notif.getNotification());
}
}
--- a/src/com/beem/project/beem/service/aidl/IChat.aidl Tue Jul 24 18:30:07 2012 +0200
+++ b/src/com/beem/project/beem/service/aidl/IChat.aidl Fri Aug 10 05:38:39 2012 +0200
@@ -82,38 +82,40 @@
boolean isOpen();
+ int getUnreadMessageCount();
+
void setState(in String state);
List<Message> getMessages();
-
+
/**
* Try to start an OTR session.
*/
void startOtrSession();
-
+
/**
* Stop the OTR session.
*/
void endOtrSession();
-
+
/**
* get local OTR key fingerprints.
*/
String getLocalOtrFingerprint();
-
-
+
+
/**
* get remote OTR key fingerprints.
*/
String getRemoteOtrFingerprint();
-
+
void verifyRemoteFingerprint(in boolean ok);
-
-
+
+
/**
* get current OTR status.
*/
String getOtrStatus();
-
+
}