Merge avec la branche xmpp pour obtenir le basculement des conversations
authorDa Risk <darisk972@gmail.com>
Fri, 29 May 2009 20:34:30 +0200
changeset 224 d8e2cb1eb895
parent 215 5db64229be69 (current diff)
parent 223 bb656974bab1 (diff)
child 225 cb15bad7d9ca
Merge avec la branche xmpp pour obtenir le basculement des conversations
AndroidManifest.xml
res/values/strings.xml
src/com/beem/project/beem/service/BeemChatManager.java
src/com/beem/project/beem/service/ChatAdapter.java
src/com/beem/project/beem/service/Contact.java
src/com/beem/project/beem/service/Message.java
src/com/beem/project/beem/ui/ContactDialog.java
src/com/beem/project/beem/ui/ContactList.java
src/com/beem/project/beem/ui/SendIM.java
src/com/beem/project/beem/ui/Subscription.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgtags	Fri May 29 20:34:30 2009 +0200
@@ -0,0 +1,1 @@
+16373c4cd73330fa568960a11a6ee7aea6886a4d sfr-release
--- a/AndroidManifest.xml	Thu May 28 15:01:49 2009 +0200
+++ b/AndroidManifest.xml	Fri May 29 20:34:30 2009 +0200
@@ -14,7 +14,7 @@
 		</activity>
 		<activity android:name=".ui.ContactListSettings"
 			android:label="@string/app_name" />
-		<activity android:name=".ui.SendIM" android:label="@string/app_name" />
+		<activity android:name=".ui.SendIM" android:label="@string/app_name" android:launchMode="singleTop" />
 		<activity android:name=".ui.ChangeStatus" android:label="@string/app_name" />
 		<activity android:name=".ui.AccountCreation" android:label="@string/app_name" />
 		<activity android:name=".ui.AddContact" android:label="@string/app_name" />
--- a/res/layout/subscription.xml	Thu May 28 15:01:49 2009 +0200
+++ b/res/layout/subscription.xml	Fri May 29 20:34:30 2009 +0200
@@ -3,6 +3,10 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 	android:orientation="vertical" android:layout_width="fill_parent"
 	android:layout_height="fill_parent">
+	
+	<TextView android:layout_width="wrap_content" android:layout_height="fill_parent" android:autoLink="none"
+		android:id="@+id/SubscriptionText" android:text="@string/SubscriptText" android:layout_weight="1" />
+	
 	<LinearLayout android:orientation="horizontal"
 		android:layout_width="fill_parent" android:layout_height="wrap_content">
 
@@ -14,4 +18,5 @@
 			android:layout_width="fill_parent" android:layout_height="fill_parent"
 			android:layout_weight="1" android:text="@string/RefuseButton" />
 	</LinearLayout>
+
 </LinearLayout>
\ No newline at end of file
--- a/res/values/strings.xml	Thu May 28 15:01:49 2009 +0200
+++ b/res/values/strings.xml	Fri May 29 20:34:30 2009 +0200
@@ -78,7 +78,7 @@
 	
 	<!--  SendIM class -->
 
-	<string name="SendIMSays"> says :\n</string>
+	<string name="SendIMSays"> %s says :\n</string>
 	<string name="SendIMYouSay">You say :\n</string>
 	<string name="SendIMToSendHint">Tip text here</string>
 	<string name="SendIMState">Is : </string>
@@ -103,6 +103,7 @@
 	<string name="SubscriptAccept">Subscription accepted</string>
 	<string name="SubscriptError">Subscription error</string>
 	<string name="SubscriptRefused">Subscription refused</string>
+	<string name="SubscriptText">You have received a request for add by %s. Do you want to accept it ?</string>
 	
 	<!-- ContactList class -->
 	<string name="ConListNotConnected">Not connected</string>
--- a/src/com/beem/project/beem/service/BeemChatManager.java	Thu May 28 15:01:49 2009 +0200
+++ b/src/com/beem/project/beem/service/BeemChatManager.java	Fri May 29 20:34:30 2009 +0200
@@ -56,10 +56,6 @@
 	@Override
 	public void chatCreated(Chat chat, boolean locally) {
 	    IChat newchat = getChat(chat);
-	    if (!locally) {
-		// chat.addMessageListener(mChatListener);
-		notifyNewChat(newchat);
-	    }
 	    chat.addMessageListener(mChatListener);
 	    final int n = mRemoteChatCreationListeners.beginBroadcast();
 
@@ -76,8 +72,11 @@
 	    mRemoteChatCreationListeners.finishBroadcast();
 	}
 
-	/*
+	/**
+	 * Set a notification of a new chat in android.
 	 * 
+	 * @param chat
+	 *            The chat to access by the notification
 	 */
 	private void notifyNewChat(IChat chat) {
 	    try {
@@ -87,10 +86,10 @@
 		notif.defaults = Notification.DEFAULT_ALL;
 		notif.flags = Notification.FLAG_AUTO_CANCEL;
 		Intent intent = new Intent(mService, SendIM.class);
-		// TODO use prefix for name
-		intent.putExtra("contact", chat.getParticipant());
+		intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
+		intent.setData(chat.getParticipant().toUri());
 		notif.setLatestEventInfo(mService, text, mService.getString(R.string.BeemChatManagerNewMessage),
-		        PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_ONE_SHOT));
+		        PendingIntent.getActivity(mService, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
 		int id = chat.hashCode();
 		mService.sendNotification(id, notif);
 	    } catch (RemoteException e) {
@@ -98,20 +97,23 @@
 	    }
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public void processMessage(Chat chat, Message message) {
-	    IChat newchat = getChat(chat);
+	    ChatAdapter newchat = getChat(chat);
 	    try {
 
 		if (message.getBody() != null)
-		    newchat.addToLastMessages(message.getBody());
+		    newchat.addMessage(new com.beem.project.beem.service.Message(message));
 		final int n = mRemoteMessageListeners.beginBroadcast();
 		for (int i = 0; i < n; i++) {
 		    IMessageListener listener = mRemoteMessageListeners.getBroadcastItem(i);
 		    listener.processMessage(newchat, new com.beem.project.beem.service.Message(message));
 		}
 		mRemoteMessageListeners.finishBroadcast();
-		if (newchat.isOpen() == false) {
+		if (!newchat.isOpen()) {
 		    notifyNewChat(newchat);
 		}
 	    } catch (RemoteException e) {
@@ -121,6 +123,9 @@
 	    }
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public void stateChanged(Chat chat, ChatState state) {
 	    IChat newchat = getChat(chat);
@@ -142,26 +147,27 @@
 	    mRemoteMessageListeners.finishBroadcast();
 	}
     }
-
     /**
      * Tag to use with log methods.
      */
     public static final String                       TAG                          = "BeemChatManager";
-    private ChatManager                              mAdaptee;
-    private Map<String, ChatAdapter>                 mChats                       = new HashMap<String, ChatAdapter>();
-    private ChatListener                             mChatListener                = new ChatListener();
-    private RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners = new RemoteCallbackList<IChatManagerListener>();
-    private RemoteCallbackList<IMessageListener>     mRemoteMessageListeners      = new RemoteCallbackList<IMessageListener>();
+    private final ChatManager                              mAdaptee;
+    private final Map<String, ChatAdapter>                 mChats                       = new HashMap<String, ChatAdapter>();
+    private final ChatListener                             mChatListener                = new ChatListener();
+    private final RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners = new RemoteCallbackList<IChatManagerListener>();
+    private final RemoteCallbackList<IMessageListener>     mRemoteMessageListeners      = new RemoteCallbackList<IMessageListener>();
 
-    private BeemService                              mService;
+    private final BeemService                              mService;
 
     /**
      * Constructor.
      * 
      * @param chatManager
      *            the smack ChatManager to adapt
+     * @param service
+     *            the service which runs the chat manager
      */
-    public BeemChatManager(final ChatManager chatManager, BeemService service) {
+    public BeemChatManager(final ChatManager chatManager, final BeemService service) {
 	mService = service;
 	mAdaptee = chatManager;
 	mAdaptee.addChatListener(mChatListener);
@@ -202,7 +208,7 @@
 	mRemoteMessageListeners.register(listener);
 	String key = StringUtils.parseBareAddress(jid);
 	if (mChats.containsKey(key)) {
-	    return (mChats.get(key));
+	    return mChats.get(key);
 	}
 	// create the chat. the adaptee will be add automatically in the map
 	mAdaptee.createChat(key, mChatListener);
@@ -221,7 +227,14 @@
 	    Log.w(TAG, "CA devrait pas 1!!" + chat.getParticipant().getJID());
     }
 
-    private IChat getChat(Chat chat) {
+    /**
+     * Get an existing ChatAdapter or create it if necessary.
+     * 
+     * @param chat
+     *            The real instance of smack chat
+     * @return a chat adapter register in the manager
+     */
+    private ChatAdapter getChat(Chat chat) {
 	String key = StringUtils.parseBareAddress(chat.getParticipant());
 	if (mChats.containsKey(key)) {
 	    return mChats.get(key);
--- a/src/com/beem/project/beem/service/ChatAdapter.java	Thu May 28 15:01:49 2009 +0200
+++ b/src/com/beem/project/beem/service/ChatAdapter.java	Fri May 29 20:34:30 2009 +0200
@@ -3,6 +3,10 @@
  */
 package com.beem.project.beem.service;
 
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
 import org.jivesoftware.smack.Chat;
 import org.jivesoftware.smack.XMPPException;
 
@@ -12,46 +16,23 @@
 
 /**
  * An adapter for smack's Chat class.
- * 
  * @author darisk
  */
 public class ChatAdapter extends IChat.Stub {
-
-    private Chat         mAdaptee;
-    private Contact      mParticipant;
-    private String       mState;
-    private StringBuffer mLastMessages;
-    private boolean      isOpen;
+    private Chat mAdaptee;
+    private Contact mParticipant;
+    private String mState;
+    private boolean mIsOpen;
+    private List<Message> mMessages;
 
     /**
      * Constructor.
-     * 
-     * @param chat
-     *            The chat to adapt
+     * @param chat The chat to adapt
      */
     public ChatAdapter(final Chat chat) {
-	mLastMessages = new StringBuffer();
 	mAdaptee = chat;
 	mParticipant = new Contact(chat.getParticipant());
-    }
-
-    @Override
-    public void addToLastMessages(String msg) throws RemoteException {
-	mLastMessages.append(msg).append('\n');
-    }
-
-    @Override
-    public void clearLastMessages() throws RemoteException {
-	mLastMessages.delete(0, mLastMessages.length());
-    }
-
-    public Chat getAdaptee() {
-	return mAdaptee;
-    }
-
-    @Override
-    public String getLastMessages() throws RemoteException {
-	return mLastMessages.toString();
+	mMessages = new LinkedList<Message>();
     }
 
     /**
@@ -62,18 +43,6 @@
 	return mParticipant;
     }
 
-    @Override
-    public String getState() throws RemoteException {
-	return mState;
-    }
-
-    /**
-     * @return the isOpen
-     */
-    public boolean isOpen() {
-	return isOpen;
-    }
-
     /**
      * {@inheritDoc}
      */
@@ -89,6 +58,7 @@
 	// send.set
 	try {
 	    mAdaptee.sendMessage(send);
+	    mMessages.add(message);
 	} catch (XMPPException e) {
 	    // TODO Auto-generated catch block
 	    e.printStackTrace();
@@ -96,16 +66,61 @@
     }
 
     /**
-     * @param isOpen
-     *            the isOpen to set
+     * {@inheritDoc}
      */
-    public void setOpen(boolean isOpen) {
-	this.isOpen = isOpen;
+    @Override
+    public String getState() throws RemoteException {
+	return mState;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public void setState(String state) throws RemoteException {
 	mState = state;
     }
 
+    /**
+     * Get the adaptee for the Chat.
+     * @return The real chat object
+     */
+    public Chat getAdaptee() {
+	return mAdaptee;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void setOpen(boolean isOpen) {
+	this.mIsOpen = isOpen;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean isOpen() {
+	return mIsOpen;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public List<Message> getMessages() throws RemoteException {
+	return Collections.unmodifiableList(mMessages);
+    }
+
+    /**
+     * Add a message in the chat history.
+     * @param msg the message to add
+     */
+    void addMessage(Message msg) {
+	if (mMessages.size() == 50)
+	    mMessages.remove(0);
+	mMessages.add(msg);
+    }
+
 }
--- a/src/com/beem/project/beem/service/Contact.java	Thu May 28 15:01:49 2009 +0200
+++ b/src/com/beem/project/beem/service/Contact.java	Fri May 29 20:34:30 2009 +0200
@@ -9,7 +9,9 @@
 
 import org.jivesoftware.smack.RosterGroup;
 import org.jivesoftware.smack.packet.Presence;
+import org.jivesoftware.smack.util.StringUtils;
 
+import android.net.Uri;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -22,17 +24,6 @@
  */
 public class Contact implements Parcelable {
 
-    @SuppressWarnings("unused")
-    private static final String                     TAG     = "Contact";
-
-    private int                                     mID;
-    private int                                     mStatus;
-    private String                                  mJID;
-    private String                                  mName;
-    private String                                  mMsgState;
-    private List<String>                            mRes;
-    private List<String>                            mGroups;
-
     /**
      * Parcelable.Creator needs by Android.
      */
@@ -49,11 +40,18 @@
 	                                                        }
 	                                                    };
 
+    private int                                     mID;
+    private int                                     mStatus;
+    private String                                  mJID;
+    private String                                  mMsgState;
+    private List<String>                            mRes;
+    private List<String>                            mGroups;
+    private String                                  mName;
+
     /**
      * Constructor.
      */
     public Contact() {
-	// TODO Auto-generated constructor stub
     }
 
     /**
@@ -89,12 +87,35 @@
 	mGroups = new ArrayList<String>();
     }
 
+    /**
+     * Create a contact from a Uri.
+     * 
+     * @param uri
+     *            an uri for the contact
+     * @throws IllegalArgumentException
+     *             if it is not a xmpp uri
+     */
+    public Contact(Uri uri) {
+	if (!uri.getScheme().equals("xmpp"))
+	    throw new IllegalArgumentException();
+	mJID = uri.getSchemeSpecificPart();
+    }
+
+    /**
+     * Add a group for the contact.
+     * 
+     * @param group
+     *            the group
+     */
     public void addGroup(String group) {
 	mGroups.add(group);
     }
 
     /**
+     * Add a resource for this contact.
+     * 
      * @param res
+     *            the resource to add
      */
     public void addRes(String res) {
 	if (!mRes.contains(res))
@@ -102,7 +123,10 @@
     }
 
     /**
+     * Delete a resource for this contact.
+     * 
      * @param res
+     *            the resource de delete
      */
     public void delRes(String res) {
 	mRes.remove(res);
@@ -118,6 +142,8 @@
     }
 
     /**
+     * Get the groups the contact is in.
+     * 
      * @return the mGroups
      */
     public List<String> getGroups() {
@@ -143,6 +169,8 @@
     }
 
     /**
+     * Get the list of resource for the contact.
+     * 
      * @return the mRes
      */
     public List<String> getMRes() {
@@ -174,13 +202,22 @@
 	return mStatus;
     }
 
+    /**
+     * Set the groups the contact is in.
+     * 
+     * @param groups
+     *            list of groups
+     */
     public void setGroups(Collection<RosterGroup> groups) {
+	this.mGroups.clear();
 	for (RosterGroup rosterGroup : groups) {
 	    mGroups.add(rosterGroup.getName());
 	}
     }
 
     /**
+     * Set the groups the contact is in.
+     * 
      * @param mGroups
      *            the mGroups to set
      */
@@ -201,14 +238,16 @@
     /**
      * Set the Jabber ID of the contact.
      * 
-     * @param mjid
+     * @param jid
      *            the jabber ID to set
      */
-    public void setJID(String mjid) {
-	mJID = mjid;
+    public void setJID(String jid) {
+	mJID = jid;
     }
 
     /**
+     * Set a list of resource for the contact.
+     * 
      * @param mRes
      *            the mRes to set
      */
@@ -256,12 +295,21 @@
 	mMsgState = presence.getStatus();
     }
 
+    /**
+     * Set status for the contact.
+     * 
+     * @param presence
+     *            The presence packet which contains the status
+     */
     public void setStatus(PresenceAdapter presence) {
 	mStatus = presence.getStatus();
 	mMsgState = presence.getStatusText();
 
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public String toString() {
 	if (mJID != null)
@@ -270,6 +318,18 @@
     }
 
     /**
+     * Get a URI to access the contact.
+     * 
+     * @return the URI
+     */
+    public Uri toUri() {
+	StringBuilder build = new StringBuilder("xmpp:");
+	build.append(StringUtils.parseName(mJID)).append('@').append(StringUtils.parseServer(mJID));
+	Uri u = Uri.parse(build.toString());
+	return u;
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
@@ -282,4 +342,5 @@
 	dest.writeStringList(getMRes());
 	dest.writeStringList(getGroups());
     }
+
 }
--- a/src/com/beem/project/beem/service/Message.java	Thu May 28 15:01:49 2009 +0200
+++ b/src/com/beem/project/beem/service/Message.java	Fri May 29 20:34:30 2009 +0200
@@ -11,7 +11,6 @@
 
 /**
  * This class represents a instant message.
- * 
  * @author darisk
  */
 public class Message implements Parcelable {
@@ -19,68 +18,95 @@
     /**
      * Normal message type. Theese messages are like an email, with subject.
      */
-    public static final int                         MSG_TYPE_NORMAL     = 100;
+    public static final int MSG_TYPE_NORMAL = 100;
 
     /**
      * Chat message type.
      */
-    public static final int                         MSG_TYPE_CHAT       = 200;
+    public static final int MSG_TYPE_CHAT = 200;
 
     /**
      * Group chat message type.
      */
-    public static final int                         MSG_TYPE_GROUP_CHAT = 300;
+    public static final int MSG_TYPE_GROUP_CHAT = 300;
 
     /**
      * Error message type.
      */
-    public static final int                         MSG_TYPE_ERROR      = 400;
+    public static final int MSG_TYPE_ERROR = 400;
 
-    private int                                     mType;
-    private String                                  mBody;
-    private String                                  mSubject;
-    private String                                  mTo;
-    private String                                  mThread;
+    private int mType;
+    private String mBody;
+    private String mSubject;
+    private String mTo;
+    private String mFrom;
+    private String mThread;
     // TODO ajouter l'erreur
 
     /**
      * Parcelable.Creator needs by Android.
      */
-    public static final Parcelable.Creator<Message> CREATOR             = new Parcelable.Creator<Message>() {
+    public static final Parcelable.Creator<Message> CREATOR = new Parcelable.Creator<Message>() {
+
+	@Override
+	public Message createFromParcel(Parcel source) {
+	    return new Message(source);
+	}
+
+	@Override
+	public Message[] newArray(int size) {
+	    return new Message[size];
+	}
+    };
 
-	                                                                    @Override
-	                                                                    public Message createFromParcel(
-	                                                                            Parcel source) {
-		                                                                return new Message(source);
-	                                                                    }
+    /**
+     * Constructor.
+     * @param to the destinataire of the message
+     * @param type the message type
+     */
+    public Message(final String to, final int type) {
+	mTo = to;
+	mType = type;
+	mBody = "";
+	mSubject = "";
+	mThread = "";
+	mFrom = null;
+    }
 
-	                                                                    @Override
-	                                                                    public Message[] newArray(int size) {
-		                                                                return new Message[size];
-	                                                                    }
-	                                                                };
+    /**
+     * Constructor a message of type chat.
+     * @param to the destinataire of the message
+     */
+    public Message(final String to) {
+	this(to, MSG_TYPE_CHAT);
+    }
 
+    /**
+     * Construct a message from a smack message packet.
+     * @param smackMsg Smack message packet
+     */
     public Message(org.jivesoftware.smack.packet.Message smackMsg) {
 	this(smackMsg.getTo());
 	switch (smackMsg.getType()) {
-	case chat:
-	    mType = MSG_TYPE_CHAT;
-	    break;
-	case groupchat:
-	    mType = MSG_TYPE_GROUP_CHAT;
-	    break;
-	case normal:
-	    mType = MSG_TYPE_NORMAL;
-	    break;
-	// TODO gerer les message de type error
-	// this a little work around waiting for a better handling of error messages
-	case error:
-	    mType = MSG_TYPE_ERROR;
-	    break;
-	default:
-	    Log.w("BEEM_MESSAGE", "type de message non gerer" + smackMsg.getType());
-	    break;
+	    case chat:
+		mType = MSG_TYPE_CHAT;
+		break;
+	    case groupchat:
+		mType = MSG_TYPE_GROUP_CHAT;
+		break;
+	    case normal:
+		mType = MSG_TYPE_NORMAL;
+		break;
+	    // TODO gerer les message de type error
+	    // this a little work around waiting for a better handling of error messages
+	    case error:
+		mType = MSG_TYPE_ERROR;
+		break;
+	    default:
+		Log.w("BEEM_MESSAGE", "type de message non gerer" + smackMsg.getType());
+		break;
 	}
+	this.mFrom = smackMsg.getFrom();
 	if (mType == MSG_TYPE_ERROR) {
 	    XMPPError er = smackMsg.getError();
 	    String msg = er.getMessage();
@@ -97,9 +123,7 @@
 
     /**
      * Construct a message from a parcel.
-     * 
-     * @param in
-     *            parcel to use for construction
+     * @param in parcel to use for construction
      */
     private Message(final Parcel in) {
 	mType = in.readInt();
@@ -107,136 +131,7 @@
 	mBody = in.readString();
 	mSubject = in.readString();
 	mThread = in.readString();
-    }
-
-    /**
-     * Constructor a message of type chat.
-     * 
-     * @param to
-     *            the destinataire of the message
-     */
-    public Message(final String to) {
-	this(to, MSG_TYPE_CHAT);
-    }
-
-    /**
-     * Constructor.
-     * 
-     * @param to
-     *            the destinataire of the message
-     * @param type
-     *            the message type
-     */
-    public Message(final String to, final int type) {
-	mTo = to;
-	mType = type;
-	mBody = "";
-	mSubject = "";
-	mThread = "";
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public int describeContents() {
-	// TODO Auto-generated method stub
-	return 0;
-    }
-
-    /**
-     * Get the body of the message.
-     * 
-     * @return the Body of the message
-     */
-    public String getBody() {
-	return mBody;
-    }
-
-    /**
-     * Get the subject of the message.
-     * 
-     * @return the subject
-     */
-    public String getSubject() {
-	return mSubject;
-    }
-
-    /**
-     * Get the thread of the message.
-     * 
-     * @return the thread
-     */
-    public String getThread() {
-	return mThread;
-    }
-
-    /**
-     * Get the destinataire of the message.
-     * 
-     * @return the destinataire of the message
-     */
-    public String getTo() {
-	return mTo;
-    }
-
-    /**
-     * Get the type of the message.
-     * 
-     * @return the type of the message.
-     */
-    public int getType() {
-	return mType;
-    }
-
-    /**
-     * Set the body of the message.
-     * 
-     * @param body
-     *            the body to set
-     */
-    public void setBody(String body) {
-	mBody = body;
-    }
-
-    /**
-     * Set the subject of the message.
-     * 
-     * @param subject
-     *            the subject to set
-     */
-    public void setSubject(String subject) {
-	mSubject = subject;
-    }
-
-    /**
-     * Set the thread of the message.
-     * 
-     * @param thread
-     *            the thread to set
-     */
-    public void setThread(String thread) {
-	mThread = thread;
-    }
-
-    /**
-     * Set the destinataire of the message.
-     * 
-     * @param to
-     *            the destinataire to set
-     */
-    public void setTo(String to) {
-	mTo = to;
-    }
-
-    /**
-     * Set the type of the message.
-     * 
-     * @param type
-     *            the type to set
-     */
-    public void setType(int type) {
-	mType = type;
+	mFrom = in.readString();
     }
 
     /**
@@ -250,6 +145,112 @@
 	dest.writeString(mBody);
 	dest.writeString(mSubject);
 	dest.writeString(mThread);
+	dest.writeString(mFrom);
+    }
+
+    /**
+     * Get the type of the message.
+     * @return the type of the message.
+     */
+    public int getType() {
+	return mType;
+    }
+
+    /**
+     * Set the type of the message.
+     * @param type the type to set
+     */
+    public void setType(int type) {
+	mType = type;
+    }
+
+    /**
+     * Get the body of the message.
+     * @return the Body of the message
+     */
+    public String getBody() {
+	return mBody;
+    }
+
+    /**
+     * Set the body of the message.
+     * @param body the body to set
+     */
+    public void setBody(String body) {
+	mBody = body;
+    }
+
+    /**
+     * Get the subject of the message.
+     * @return the subject
+     */
+    public String getSubject() {
+	return mSubject;
+    }
+
+    /**
+     * Set the subject of the message.
+     * @param subject the subject to set
+     */
+    public void setSubject(String subject) {
+	mSubject = subject;
+    }
+
+    /**
+     * Get the destinataire of the message.
+     * @return the destinataire of the message
+     */
+    public String getTo() {
+	return mTo;
+    }
+
+    /**
+     * Set the destinataire of the message.
+     * @param to the destinataire to set
+     */
+    public void setTo(String to) {
+	mTo = to;
+    }
+
+    /**
+     * Set the from field of the message.
+     * @param mFrom the mFrom to set
+     */
+    public void setFrom(String mFrom) {
+	this.mFrom = mFrom;
+    }
+
+    /**
+     * Get the from field of the message.
+     * @return the mFrom
+     */
+    public String getFrom() {
+	return mFrom;
+    }
+
+    /**
+     * Get the thread of the message.
+     * @return the thread
+     */
+    public String getThread() {
+	return mThread;
+    }
+
+    /**
+     * Set the thread of the message.
+     * @param thread the thread to set
+     */
+    public void setThread(String thread) {
+	mThread = thread;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public int describeContents() {
+	// TODO Auto-generated method stub
+	return 0;
     }
 
 }
--- a/src/com/beem/project/beem/service/aidl/IChat.aidl	Thu May 28 15:01:49 2009 +0200
+++ b/src/com/beem/project/beem/service/aidl/IChat.aidl	Fri May 29 20:34:30 2009 +0200
@@ -29,14 +29,6 @@
 	
 	void setState(in String state);
 	
-	String getLastMessages();
-	
-	void addToLastMessages(in String msg);
-	
-	void clearLastMessages();
-/*	
-	void addMessageListener(in IMessageListener listener);
-	
-	void removeMessageListener(in IMessageListener listener);
-*/	
+	List<Message> getMessages();
+
 }
\ No newline at end of file
--- a/src/com/beem/project/beem/ui/ContactList.java	Thu May 28 15:01:49 2009 +0200
+++ b/src/com/beem/project/beem/ui/ContactList.java	Fri May 29 20:34:30 2009 +0200
@@ -154,7 +154,7 @@
 	    @Override
 	    public void onClick(View v) {
 		Intent i = new Intent(ContactList.this, SendIM.class);
-		i.putExtra("contact", mContact);
+		i.setData(mContact.toUri());
 		startActivity(i);
 	    }
 
--- a/src/com/beem/project/beem/ui/SendIM.java	Thu May 28 15:01:49 2009 +0200
+++ b/src/com/beem/project/beem/ui/SendIM.java	Fri May 29 20:34:30 2009 +0200
@@ -1,6 +1,9 @@
 package com.beem.project.beem.ui;
 
+import java.util.List;
+
 import android.app.Activity;
+import android.content.Intent;
 import android.content.SharedPreferences;
 import android.graphics.drawable.Drawable;
 import android.os.Bundle;
@@ -37,8 +40,16 @@
 
 public class SendIM extends Activity implements OnClickListener, OnKeyListener {
 
+    /**
+     * Listener for chat creation. (maybe not necessary)
+     * 
+     * @author darisk
+     */
     private class OnChatListener extends IChatManagerListener.Stub {
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public void chatCreated(IChat chat, boolean locally) throws RemoteException {
 	    Log.i("LOG", "chatCreated");
@@ -46,8 +57,16 @@
 
     }
 
+    /**
+     * Listener for new chat messages.
+     * 
+     * @author darisk
+     */
     private class OnMessageListener extends IMessageListener.Stub {
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public void processMessage(IChat chat, Message msg) throws RemoteException {
 
@@ -59,18 +78,24 @@
 		@Override
 		public void run() {
 		    if (m.getBody() != null) {
-			if (!mSpeak)
+			if (mSpeak == 2)
 			    mText.append(m.getBody() + "\n");
-			else
-			    mText.append(mContact.getJID() + " " + getString(R.string.SendIMSays) + m.getBody() + "\n");
-			mSpeak = false;
-			mScrolling.fullScroll(View.FOCUS_DOWN);
+			else {
+			    String str = String.format(getString(R.string.SendIMSays), m.getFrom());
+			    mText.append(str);
+			    mText.append(m.getBody() + "\n");
+			}
+			mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
 			mToSend.requestFocus();
+			mSpeak = 2;
 		    }
 		}
 	    });
 	}
 
+	/**
+	 * {@inheritDoc}
+	 */
 	@Override
 	public void stateChanged(IChat chat) throws RemoteException {
 	    // TODO: a integrer dans l'ui
@@ -78,13 +103,13 @@
 	}
     }
 
-    private static final String  TAG      = "SEND_IM";
+    private static final String  TAG = "SEND_IM";
     private EditText             mToSend;
     private SendIMDialogSmiley   mSmyDialog;
     private SharedPreferences    mSet;
     private BeemApplication      mBeemApplication;
     private Handler              mHandler;
-    private IXmppFacade          mService = null;
+    private IXmppFacade          mService;
     private Contact              mContact;
     private IChatManager         mChatManager;
     private IChatManagerListener mChatManagerListener;
@@ -95,7 +120,7 @@
 
     private ScrollView           mScrolling;
 
-    private boolean              mSpeak;
+    private char                 mSpeak;
 
     /**
      * Constructor.
@@ -105,17 +130,18 @@
     }
 
     /**
-     * Abstract method inherited from OnClickListener
+     * {@inheritDoc}
      */
+    @Override
     public void onClick(View view) {
 	sendText();
     }
 
     /**
-     * Overload of onCreate() Activity inherited function
+     * {@inheritDoc}
      */
     @Override
-    public void onCreate(Bundle saveBundle) {
+    protected void onCreate(Bundle saveBundle) {
 	super.onCreate(saveBundle);
 	mHandler = new Handler();
 	mChatManagerListener = new OnChatListener();
@@ -128,18 +154,15 @@
 	mToSend.setOnClickListener(this);
 	mToSend.setOnKeyListener(this);
 	mLogin = (TextView) findViewById(R.id.sendimlogin);
-	mContact = getIntent().getParcelableExtra("contact");
+	// mContact = getIntent().getParcelableExtra("contact");
+	mContact = new Contact(getIntent().getData());
 	setViewHeader();
 	mText = (TextView) findViewById(R.id.sendimlist);
 	mScrolling = (ScrollView) findViewById(R.id.sendimscroll);
     }
 
     /**
-     * Callback for menu creation.
-     * 
-     * @param The
-     *            created menu
-     * @return true on success, false otherwise
+     * {@inheritDoc}
      */
     @Override
     public final boolean onCreateOptionsMenu(Menu menu) {
@@ -149,23 +172,27 @@
 	return true;
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     protected void onDestroy() {
-
+	super.onDestroy();
 	if (mChatManager != null) {
 	    try {
 		mChatManager.removeChatCreationListener(mChatManagerListener);
-		mChatManager.destroyChat(mChat);
+		// TODO trouver quand detruire le chat
+		// mChatManager.destroyChat(mChat);
 	    } catch (RemoteException e) {
 		Log.e(TAG, "mchat manager and SendIM destroy", e);
 	    }
 	}
-	super.onDestroy();
     }
 
     /**
-     * Abstract method inherited from OnKeyListener
+     * {@inheritDoc}
      */
+    @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
 	if (event.getAction() == KeyEvent.ACTION_DOWN) {
 	    switch (keyCode) {
@@ -173,11 +200,26 @@
 	    case KeyEvent.KEYCODE_ENTER:
 		sendText();
 		return true;
+	    default:
+		return false;
 	    }
 	}
 	return false;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected void onNewIntent(Intent intent) {
+	super.onNewIntent(intent);
+	mContact = new Contact(intent.getData());
+	setViewHeader();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     @Override
     public final boolean onOptionsItemSelected(MenuItem item) {
 	switch (item.getItemId()) {
@@ -189,18 +231,22 @@
 	}
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     protected void onPause() {
-	Log.d(TAG, "onPause");
+	super.onPause();
 	try {
 	    mChat.setOpen(false);
 	} catch (RemoteException e) {
-	    Log.d(TAG, "mchat open false", e);
+	    Log.d(TAG, "Error while closing chat", e);
 	}
-	super.onPause();
-	finish();
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     protected void onResume() {
 	super.onResume();
@@ -213,26 +259,23 @@
 	    public void run() {
 		mService = mBeemApplication.getXmppFacade();
 		try {
-		    mChatManager = mService.getChatManager();
-		    mChatManager.addChatCreationListener(mChatManagerListener);
-		    mChat = mChatManager.createChat(mContact, mMessageListener);
-		    String text = mChat.getLastMessages();
-		    if (!"".equals(text)) {
-			mText.append(mContact.getJID() + " " + getString(R.string.SendIMSays));
-			mText.append(text);
-			// mChat.clearLastMessages();
+		    if (mChatManager == null) {
+			mChatManager = mService.getChatManager();
+			mChatManager.addChatCreationListener(mChatManagerListener);
 		    }
-		    mChat.setOpen(true);
+		    switchChat(mContact);
 		} catch (RemoteException e) {
 		    Log.e(TAG, "Error during chat manager creation", e);
 		}
 	    }
 	});
-
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
-    public void onStart() {
+    protected void onStart() {
 	super.onStart();
 	// TODO cancel the notification if any
 	if (mContact == null)
@@ -242,47 +285,49 @@
 
     }
 
+    /**
+     * {@inheritDoc}
+     */
     @Override
     protected void onStop() {
-
-	Log.d(TAG, "onStop");
+	super.onStop();
 	try {
 	    mChat.setOpen(false);
 	} catch (RemoteException e) {
 	    Log.d(TAG, "mchat open false", e);
 	}
 	mBeemApplication.unbindBeemService();
-	super.onStop();
     }
 
     /**
-     * This method send a message to the server over the XMPP connection and display it on activity
-     * view TODO : Exception si la connexion se coupe pendant la conversation
+     * Send a message to the contact over the XMPP connection. Also display it on activity view.
+     * TODO : Gerer l'exception si la connexion se coupe pendant la conversation
      */
     private void sendText() {
-	if (mSpeak)
-	    mSpeak = false;
 	String text = mToSend.getText().toString();
 	if (!text.equals("")) {
 	    Message msg = new Message(mContact.getJID(), Message.MSG_TYPE_CHAT);
 	    msg.setBody(text);
 	    try {
 		mChat.sendMessage(msg);
+		if (mSpeak != 1)
+		    mText.append(getString(R.string.SendIMYouSay) + text + '\n');
+		else
+		    mText.append(text + "\n");
+		mToSend.setText(null);
+		mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
+		mToSend.requestFocus();
+		mSpeak = 1;
 	    } catch (RemoteException e) {
 		// TODO Auto-generated catch block
 		e.printStackTrace();
 	    }
-	    if (!mSpeak)
-		mText.append(getString(R.string.SendIMYouSay) + text + "\n");
-	    else
-		mText.append(text + "\n");
-	    mToSend.setText(null);
-	    mScrolling.fullScroll(View.FOCUS_DOWN);
-	    mToSend.requestFocus();
-	    mSpeak = true;
 	}
     }
 
+    /**
+     * Set the header information in the window.
+     */
     private void setViewHeader() {
 	Drawable avatar = getResources().getDrawable(R.drawable.avatar);
 	ImageView imgV = (ImageView) findViewById(R.id.sendimavatar);
@@ -295,6 +340,50 @@
 	String statmsg = mContact.getMsgState();
 	if (statmsg != null)
 	    status.setText(statmsg);
-	;
+    }
+
+    /**
+     * Show the message history.
+     * 
+     * @param messages
+     *            list of message to display
+     */
+    private void showMessageList(List<Message> messages) {
+	mText.setText("");
+	mSpeak = 0;
+	for (Message message : messages) {
+	    String from = message.getFrom();
+	    if (from == null) {
+		if (mSpeak != 1)
+		    mText.append(getString(R.string.SendIMYouSay));
+		mSpeak = 1;
+	    } else {
+		if (mSpeak != 2) {
+		    String str = String.format(getString(R.string.SendIMSays), from);
+		    mText.append(str);
+		}
+		mSpeak = 2;
+	    }
+	    mText.append(message.getBody() + '\n');
+	}
+	mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
+    }
+
+    /**
+     * Change the correspondant of the chat.
+     * 
+     * @param newContact
+     *            New contact to chat with
+     * @throws RemoteException
+     *             if an errors occurs in the connection with the service
+     */
+    private void switchChat(Contact newContact) throws RemoteException {
+	if (mChat != null)
+	    mChat.setOpen(false);
+	mChat = mChatManager.createChat(newContact, mMessageListener);
+	showMessageList(mChat.getMessages());
+	mChat.setOpen(true);
+	mContact = newContact;
+	mToSend.requestFocus();
     }
 }
--- a/src/com/beem/project/beem/ui/Subscription.java	Thu May 28 15:01:49 2009 +0200
+++ b/src/com/beem/project/beem/ui/Subscription.java	Fri May 29 20:34:30 2009 +0200
@@ -6,65 +6,27 @@
 import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.packet.Presence.Type;
 
-import android.app.Activity;
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.Toast;
-
 import com.beem.project.beem.BeemApplication;
 import com.beem.project.beem.R;
 import com.beem.project.beem.service.PresenceAdapter;
 import com.beem.project.beem.service.aidl.IXmppFacade;
 
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.TextView;
+import android.widget.Toast;
+
 /**
  * @author nikita
+ *
  */
 public class Subscription extends Activity {
 
-    private IXmppFacade     mService;
-    private String          mContact;
-
-    private OnClickListener mClickListener = new OnClickListener() {
-
-	                                       @Override
-	                                       public void onClick(View v) {
-		                                   switch (v.getId()) {
-		                                   case R.id.SubscriptionAccept:
-		                                       Presence presence = new Presence(Type.subscribed);
-		                                       presence.setTo(mContact);
-		                                       PresenceAdapter preAdapt = new PresenceAdapter(presence);
-		                                       try {
-			                                   mService.sendPresencePacket(preAdapt);
-			                                   Toast.makeText(Subscription.this,
-			                                           getString(R.string.SubscriptAccept),
-			                                           Toast.LENGTH_SHORT).show();
-			                                   finish();
-		                                       } catch (RemoteException e) {
-			                                   Toast.makeText(Subscription.this,
-			                                           getString(R.string.SubscriptError),
-			                                           Toast.LENGTH_SHORT).show();
-			                                   e.printStackTrace();
-		                                       }
-		                                       break;
-		                                   case R.id.SubscriptionRefuse:
-		                                       Toast
-		                                               .makeText(Subscription.this,
-		                                                       getString(R.string.SubscriptRefused),
-		                                                       Toast.LENGTH_SHORT).show();
-
-		                                       break;
-		                                   default:
-		                                       Toast.makeText(Subscription.this,
-		                                               getString(R.string.SubscriptError), Toast.LENGTH_SHORT)
-		                                               .show();
-		                                   }
-		                                   ;
-
-	                                       }
-
-	                                   };
+    private IXmppFacade mService;
+    private String mContact;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -73,6 +35,43 @@
 	findViewById(R.id.SubscriptionAccept).setOnClickListener(mClickListener);
 	findViewById(R.id.SubscriptionRefuse).setOnClickListener(mClickListener);
 	mContact = getIntent().getStringExtra("from");
+	TextView tv = (TextView) findViewById(R.id.SubscriptionText);
+	String str = String.format(getString(R.string.SubscriptText), mContact);
+	tv.setText(str);
 	mService = BeemApplication.getApplication(this).getXmppFacade();
     }
+
+    private OnClickListener mClickListener = new OnClickListener() {
+
+	@Override
+	public void onClick(View v) {
+	    switch (v.getId()) {
+		case R.id.SubscriptionAccept:
+		    Presence presence = new Presence(Type.subscribed);
+		    presence.setTo(mContact);
+		    PresenceAdapter preAdapt = new PresenceAdapter(presence);
+		    try {
+			mService.sendPresencePacket(preAdapt);
+			Toast.makeText(Subscription.this, getString(R.string.SubscriptAccept),
+			    Toast.LENGTH_SHORT).show();
+			finish();
+		    } catch (RemoteException e) {
+			Toast.makeText(Subscription.this, getString(R.string.SubscriptError),
+			    Toast.LENGTH_SHORT).show();
+			e.printStackTrace();
+		    }
+		    break ;
+		case R.id.SubscriptionRefuse:
+		    Toast.makeText(Subscription.this, getString(R.string.SubscriptRefused),
+			Toast.LENGTH_SHORT).show();
+
+		    break ;
+		default:
+		    Toast.makeText(Subscription.this, getString(R.string.SubscriptError),
+			Toast.LENGTH_SHORT).show();
+	    };
+
+	}
+
+    };
 }