merge avec barbi
authorDa Risk <darisk972@gmail.com>
Wed, 22 Apr 2009 19:39:39 +0200
changeset 140 f36049828552
parent 135 efdae5f9289f (diff)
parent 116 dded6cd76f8c (current diff)
child 141 70ceaba725d4
merge avec barbi
AndroidManifest.xml
default.properties
res/values/strings.xml
src/com/beem/project/beem/BeemService.java
src/com/beem/project/beem/ui/ChangeStatus.java
src/com/beem/project/beem/ui/ContactListSettings.java
--- a/AndroidManifest.xml	Wed Apr 22 15:19:42 2009 +0200
+++ b/AndroidManifest.xml	Wed Apr 22 19:39:39 2009 +0200
@@ -2,18 +2,20 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
 	package="com.beem.project.beem" android:versionCode="1"
 	android:versionName="1.0">
-	<application android:label="@string/app_name" android:name="BeemApplication"
-		android:theme="@style/customtheme.contactList">
+	<application android:label="@string/app_name" android:name="BeemApplication" android:theme="@style/customtheme.contactList" android:icon="@drawable/signal">
 		<activity android:name=".ui.ContactList" android:label="@string/app_name">
 			<intent-filter>
 				<action android:name="android.intent.action.MAIN" />
 				<category android:name="android.intent.category.LAUNCHER" />
+				<category android:name="android.intent.category.ACCOUNT_CREATE" />
 			</intent-filter>
 		</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.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" />
 		<service android:name="BeemService" android:enabled="true"
 			android:label="Beem Service" android:permission="com.beem.project.beem.BEEM_SERVICE">
 			<intent-filter>
--- a/project.aidl	Wed Apr 22 15:19:42 2009 +0200
+++ b/project.aidl	Wed Apr 22 19:39:39 2009 +0200
@@ -4,5 +4,5 @@
 
 parcelable com.beem.project.beem.BeemException
 parcelable com.beem.project.beem.service.Message
+parcelable com.beem.project.beem.service.PresenceAdapter
 parcelable com.beem.project.beem.service.Contact
-parcelable com.beem.project.beem.service.PresenceAdapter
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/layout/accountcreation.xml	Wed Apr 22 19:39:39 2009 +0200
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+        >
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+            >
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Login:"
+                android:minWidth="70dp"
+                />
+                
+        <EditText android:id="@+id/login"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:textSize="16sp"
+                  android:autoText="false"
+                  android:capitalize="none"
+                  android:minWidth="150dp"
+                  android:scrollHorizontally="true"/>
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+            >
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Email:"
+                android:minWidth="70dp"
+                />
+        <EditText android:id="@+id/email"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:textSize="16sp"
+                  android:autoText="false"
+                  android:minWidth="250dp"
+                  android:capitalize="none"
+                  android:scrollHorizontally="true"/>
+    </LinearLayout>
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+            >
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Password:"
+                android:minWidth="70dp"
+                />
+        <EditText android:id="@+id/password"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:password="true"
+                  android:textSize="16sp"
+                  android:autoText="false"
+                  android:minWidth="250dp"
+                  android:capitalize="none"
+                  android:scrollHorizontally="true"/>
+    </LinearLayout>
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+            >
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Repeat:"
+                android:minWidth="70dp"
+                />
+        <EditText android:id="@+id/password2"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:password="true"
+                  android:textSize="16sp"
+                  android:autoText="false"
+                  android:minWidth="250dp"
+                  android:capitalize="none"
+                  android:scrollHorizontally="true"/>
+    </LinearLayout>
+
+    <Button android:id="@+id/ok"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:text="OK">
+        <requestFocus/>
+    </Button>
+</LinearLayout>
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/layout/addcontact.xml	Wed Apr 22 19:39:39 2009 +0200
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+              android:orientation="vertical"
+              android:layout_width="fill_parent"
+              android:layout_height="fill_parent"
+        >
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+            >
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Login:"
+                android:minWidth="70dp"
+                />
+                
+        <EditText android:id="@+id/login"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:textSize="16sp"
+                  android:autoText="false"
+                  android:capitalize="none"
+                  android:minWidth="250dp"
+                  android:scrollHorizontally="true"/>
+    </LinearLayout>
+
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+            >
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Alias:"
+                android:minWidth="70dp"
+                />
+        <EditText android:id="@+id/alias"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:textSize="16sp"
+                  android:autoText="false"
+                  android:minWidth="250dp"
+                  android:capitalize="none"
+                  android:scrollHorizontally="true"/>
+    </LinearLayout>
+    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                  android:orientation="horizontal"
+                  android:layout_width="fill_parent"
+                  android:layout_height="wrap_content"
+            >
+        <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:text="Group:"
+                android:minWidth="70dp"
+                />
+        <EditText android:id="@+id/group"
+                  android:layout_width="wrap_content"
+                  android:layout_height="wrap_content"
+                  android:singleLine="true"
+                  android:password="true"
+                  android:textSize="16sp"
+                  android:autoText="false"
+                  android:minWidth="250dp"
+                  android:capitalize="none"
+                  android:scrollHorizontally="true"/>
+    </LinearLayout>
+    <Button android:id="@+id/ok"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_alignParentRight="true"
+            android:text="OK">
+        <requestFocus/>
+    </Button>
+</LinearLayout>
\ No newline at end of file
--- a/res/menu/contactlistmenu.xml	Wed Apr 22 15:19:42 2009 +0200
+++ b/res/menu/contactlistmenu.xml	Wed Apr 22 19:39:39 2009 +0200
@@ -1,4 +1,6 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
 	<item android:title="Creer ou Editer un compte" android:id="@+id/account_edit" android:icon="@drawable/xmpp"/>
+	<item android:title="@string/MenuAddContact" android:id="@+id/add_contact" />
 	<item android:title="L'equipe Beem" android:id="@+id/account_about"/>
+	<item android:title="TEMP/createAccount" android:id="@+id/account_create"/>
 </menu>
--- a/res/values/strings.xml	Wed Apr 22 15:19:42 2009 +0200
+++ b/res/values/strings.xml	Wed Apr 22 19:39:39 2009 +0200
@@ -53,6 +53,9 @@
 	<!--  ChangeStatus class -->
 
 	<string name="ChangeStatusText">Type here your status message :</string>
+
+	<string name="MenuAddContact">Add new contact</string>
+
 	<string name="ChangeStatusOk">Updating status</string>
 	<string name="ChangeStatusNoChange">Nothing to change</string>
 
--- a/src/com/beem/project/beem/BeemApplication.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/BeemApplication.java	Wed Apr 22 19:39:39 2009 +0200
@@ -5,7 +5,6 @@
 
 import java.util.LinkedList;
 import java.util.List;
-
 import android.app.Activity;
 import android.app.Application;
 import android.app.ProgressDialog;
@@ -13,15 +12,12 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.RemoteException;
 import android.util.Log;
-import android.widget.Toast;
-
 import com.beem.project.beem.service.aidl.IBeemConnectionListener;
 import com.beem.project.beem.service.aidl.IXmppConnection;
 import com.beem.project.beem.service.aidl.IXmppFacade;
@@ -68,6 +64,13 @@
 		    mProgressDialog.show();
 		    mConnection.addConnectionListener(mConnectionListener);
 		    mApplicationContext.startService(BeemApplication.SERVICE_INTENT);
+		}else {
+		    synchronized (mQueue) {
+			for (Message msg : mQueue) {
+			    msg.sendToTarget();
+			}
+			mQueue.clear();
+		    }
 		}
 	    } catch (RemoteException e) {
 		// TODO Auto-generated catch block
@@ -126,6 +129,13 @@
 	}
     }
 
+    public synchronized void unbindBeemService() {
+	if (mIsConnected) {
+	    mApplicationContext.unbindService(mServConn);
+	    mIsConnected = false;
+	}
+     }
+
     /**
      * Get the facade to use to access the Beem service.
      * @return the facade or null if the application is not connected to the beem service.
@@ -160,15 +170,15 @@
     }
 
     private class ConnectionRunnable implements Runnable {
-	private String mErrorMsg;	
-	
+	private String mErrorMsg;
+
 	public ConnectionRunnable(String string) {
 	    this.mErrorMsg = string;
 	}
 
 	@Override
 	public void run() {
-	    mBeemApp.mProgressDialog.setMessage(mErrorMsg);	    
+	    mBeemApp.mProgressDialog.setMessage(mErrorMsg);
 	}
 
 	/**
@@ -206,7 +216,7 @@
 	@Override
 	public void connectionClosed() throws RemoteException {
 	    // TODO Auto-generated method stub
-	    Log.e("BeemApp","test1");
+	    Log.e("BeemApp", "test1");
 
 	}
 
@@ -216,7 +226,7 @@
 	@Override
 	public void connectionClosedOnError() throws RemoteException {
 	    mBeemApp.mProgressDialog.setMessage("Connection closed on error");
-	    Log.e(TAG,"ConnectionClosedOnError");
+	    Log.e(TAG, "ConnectionClosedOnError");
 	    // TODO afficher une notification et reafficher le progress dialog
 	}
 
@@ -252,7 +262,7 @@
 	@Override
 	public void reconnectionFailed() throws RemoteException {
 	    // TODO Auto-generated method stub
-	    Log.e("BeemApp","test3");
+	    Log.e("BeemApp", "test3");
 
 	}
 
--- a/src/com/beem/project/beem/BeemService.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Wed Apr 22 19:39:39 2009 +0200
@@ -38,7 +38,7 @@
     /**
      * The id to use for status notification.
      */
-    public static final int NOTIFICATION_STATUS_ID = 1;
+    public static final int NOTIFICATION_STATUS_ID = 100;
 
     private NotificationManager mNotificationManager;
     private XmppConnectionAdapter mConnection;
@@ -72,15 +72,17 @@
      */
     @Override
     public void onCreate() {
+	
 	super.onCreate();
 	mSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
 	mLogin = mSettings.getString(getString(R.string.PreferenceLoginKey), "");
 	mPassword = mSettings.getString(getString(R.string.PreferencePasswordKey), "");
 	mHost = mSettings.getString(getString(R.string.PreferenceHostKey), "");
-	//mHost = "10.0.2.2";
+	// TODO penser a commenter
+	mHost = "10.0.2.2";
 	initConnectionConfig();
 	mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-	mConnection = new XmppConnectionAdapter(mConnectionConfiguration, mLogin, mPassword);
+	mConnection = new XmppConnectionAdapter(mConnectionConfiguration, mLogin, mPassword, this);
 	initRosterRequestListener();
 	mBind = new XmppFacade(mConnection, this);
     }
@@ -115,7 +117,7 @@
     public void sendNotification(int id, Notification notif) {
 	mNotificationManager.notify(id, notif);
     }
-
+    
     /**
      * Initialise la configuration de la connexion.
      */
@@ -135,6 +137,7 @@
 	} else {
 	    mConnectionConfiguration = new ConnectionConfiguration(mHost);
 	}
+	mConnectionConfiguration.setDebuggerEnabled(false);
 	mConnectionConfiguration.setSendPresence(true);
     }
 
@@ -182,6 +185,7 @@
 
 		}
 
+		
 		@Override
 		public void onConnect() throws RemoteException {
 		    // TODO Auto-generated method stub
@@ -231,7 +235,6 @@
 	    // TODO Auto-generated catch block
 	    e.printStackTrace();
 	}
-
     }
 
     /**
@@ -242,4 +245,5 @@
 	    mConnection.disconnect();
     }
 
+    
 }
--- a/src/com/beem/project/beem/service/BeemChatManager.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/BeemChatManager.java	Wed Apr 22 19:39:39 2009 +0200
@@ -11,17 +11,24 @@
 import org.jivesoftware.smack.ChatManagerListener;
 import org.jivesoftware.smack.MessageListener;
 import org.jivesoftware.smack.packet.Message;
+import org.jivesoftware.smack.util.StringUtils;
 import org.jivesoftware.smackx.ChatState;
 import org.jivesoftware.smackx.ChatStateListener;
 
+import android.R;
+import android.app.Notification;
+import android.app.PendingIntent;
+import android.content.Intent;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.util.Log;
 
+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.ui.SendIM;
 
 /**
  * An adapter for smack's ChatManager. This class provides functionnality to handle chats.
@@ -36,16 +43,16 @@
     private ChatManager mAdaptee;
     private Map<String, IChat> mChats = new HashMap<String, IChat>();
     private ChatListener mChatListener = new ChatListener();
-    private RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners =
-	new RemoteCallbackList<IChatManagerListener>();
+    private RemoteCallbackList<IChatManagerListener> mRemoteChatCreationListeners = new RemoteCallbackList<IChatManagerListener>();
     private RemoteCallbackList<IMessageListener> mRemoteMessageListeners = new RemoteCallbackList<IMessageListener>();
+    private BeemService mService;
 
     /**
      * Constructor.
      * @param chatManager the smack ChatManager to adapt
      */
-    public BeemChatManager(final ChatManager chatManager) {
-	// TODO Auto-generated constructor stub
+    public BeemChatManager(final ChatManager chatManager, BeemService service) {
+	mService = service;
 	mAdaptee = chatManager;
 	mAdaptee.addChatListener(mChatListener);
     }
@@ -58,10 +65,13 @@
      */
     public IChat createChat(String jid, IMessageListener listener) {
 	mRemoteMessageListeners.register(listener);
-	if (mChats.containsKey(jid)) {
-	    return mChats.get(jid);
+	String key = StringUtils.parseBareAddress(jid);
+	if (mChats.containsKey(key)) {
+	    return mChats.get(key);
 	}
-	return new ChatAdapter( mAdaptee.createChat(jid, mChatListener));
+	// create the chat. the adaptee will be add automatically in the map
+	mAdaptee.createChat(key, mChatListener);
+	return mChats.get(key);
     }
 
     /**
@@ -91,12 +101,24 @@
 	mRemoteChatCreationListeners.unregister(listener);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public void destroyChat(IChat chat) throws RemoteException {
+	// TODO gerer les resources egalement
+	IChat c = mChats.remove(chat.getParticipant().getJID());
+	if (c == null)
+	    Log.w(TAG, "CA devrait pas 1!!");
+    }
+
     private IChat getChat(Chat chat) {
-	if (mChats.containsKey(chat.getParticipant())) {
-	    return mChats.get(chat.getParticipant());
+	String key = StringUtils.parseBareAddress(chat.getParticipant());
+	if (mChats.containsKey(key)) {
+	    return mChats.get(key);
 	}
 	IChat res = new ChatAdapter(chat);
-	mChats.put(chat.getParticipant(), res);
+	mChats.put(key, res);
 	return res;
     }
 
@@ -119,9 +141,10 @@
 	public void chatCreated(Chat chat, boolean locally) {
 	    IChat newchat = getChat(chat);
 	    if (!locally) {
-		mChats.put(chat.getParticipant(), newchat);
-		// TODO startActivity 
+		//	chat.addMessageListener(mChatListener);
+		notifyNewChat(newchat);
 	    }
+	    chat.addMessageListener(mChatListener);
 	    final int n = mRemoteChatCreationListeners.beginBroadcast();
 
 	    for (int i = 0; i < n; i++) {
@@ -137,27 +160,49 @@
 	    mRemoteChatCreationListeners.finishBroadcast();
 	}
 
+	private void notifyNewChat(IChat chat) {
+	    try {
+		String text = chat.getParticipant().getJID();
+		Notification notif = new Notification(com.beem.project.beem.R.drawable.signal, text, System
+		    .currentTimeMillis());
+		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());
+		notif.setLatestEventInfo(mService, text, "nouveau message", PendingIntent.getActivity(mService, 0,
+		    intent, PendingIntent.FLAG_ONE_SHOT));
+		int id = chat.hashCode();
+		mService.sendNotification(id, notif);
+	    } catch (RemoteException e) {
+		// TODO Auto-generated catch block
+		e.printStackTrace();
+	    }
+	}
+
 	@Override
 	public void processMessage(Chat chat, Message message) {
 	    IChat newchat = getChat(chat);
-	    final int n = mRemoteMessageListeners.beginBroadcast();
-	    for (int i = 0; i < n; i++) {
-		IMessageListener listener = mRemoteMessageListeners.getBroadcastItem(i);
-		try {
+	    try {
+		if (message.getBody() != null)
+		    newchat.addToLastMessages(message.getBody());
+		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));
-		    //listener.chatCreated(newchat, locally);
-		} catch (RemoteException e) {
-		    // The RemoteCallbackList will take care of removing the
-		    // dead listeners.
-		    Log.w(TAG, "Error while triggering remote connection listeners", e);
 		}
+		mRemoteMessageListeners.finishBroadcast();
+	    } catch (RemoteException e) {
+		// The RemoteCallbackList will take care of removing the
+		// dead listeners.
+		Log.w(TAG, "Error while triggering remote connection listeners", e);
 	    }
-	    mRemoteMessageListeners.finishBroadcast();
 	}
 
 	@Override
 	public void stateChanged(Chat chat, ChatState state) {
 	    try {
+		Log.d(TAG, "state changed");
 		mChats.get(chat.getParticipant()).setState(state.name());
 	    } catch (RemoteException e) {
 		e.printStackTrace();
--- a/src/com/beem/project/beem/service/ChatAdapter.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/ChatAdapter.java	Wed Apr 22 19:39:39 2009 +0200
@@ -4,11 +4,16 @@
 package com.beem.project.beem.service;
 
 import org.jivesoftware.smack.Chat;
+import org.jivesoftware.smack.MessageListener;
 import org.jivesoftware.smack.XMPPException;
+import org.jivesoftware.smack.packet.Message;
 
+import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.util.Log;
 
 import com.beem.project.beem.service.aidl.IChat;
+import com.beem.project.beem.service.aidl.IMessageListener;
 
 /**
  * An adapter for smack's Chat class.
@@ -18,12 +23,14 @@
     private Chat mAdaptee;
     private Contact mParticipant;
     private String mState;
-
+    private StringBuffer mLastMessages;
+ 
     /**
      * Constructor.
      * @param chat The chat to adapt
      */
     public ChatAdapter(final Chat chat) {
+	mLastMessages = new StringBuffer();
 	mAdaptee = chat;
 	mParticipant = new Contact(chat.getParticipant());
     }
@@ -40,7 +47,7 @@
      * {@inheritDoc}
      */
     @Override
-    public void sendMessage(Message message) throws RemoteException {
+    public void sendMessage(com.beem.project.beem.service.Message message) throws RemoteException {
 	org.jivesoftware.smack.packet.Message send = new org.jivesoftware.smack.packet.Message();
 	send.setTo(message.getTo());
 	send.setBody(message.getBody());
@@ -67,4 +74,23 @@
 	mState = state;
     }
 
+    public Chat getAdaptee() {
+	return mAdaptee;
+    }
+
+    @Override
+    public String getLastMessages() throws RemoteException {
+	return mLastMessages.toString();
+    }
+
+    @Override
+    public void addToLastMessages(String msg) throws RemoteException {
+	mLastMessages.append(msg).append('\n');
+    }
+
+    @Override
+    public void clearLastMessages() throws RemoteException {
+	mLastMessages.delete(0, mLastMessages.length());
+    }
+
 }
--- a/src/com/beem/project/beem/service/Contact.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/Contact.java	Wed Apr 22 19:39:39 2009 +0200
@@ -200,4 +200,11 @@
     public List<String> getMRes() {
 	return mRes;
     }
+    
+    @Override
+    public String toString() {
+	if (mJID != null)
+	    return mJID;
+	return super.toString();
+    }
 }
--- a/src/com/beem/project/beem/service/PresenceAdapter.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/PresenceAdapter.java	Wed Apr 22 19:39:39 2009 +0200
@@ -46,9 +46,4 @@
 		// TODO Auto-generated method stub
 		
 	}
-
-	public IBinder asBinder() {
-		// TODO Auto-generated method stub
-		return null;
-	}
 }
--- a/src/com/beem/project/beem/service/RosterAdapter.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/RosterAdapter.java	Wed Apr 22 19:39:39 2009 +0200
@@ -42,13 +42,15 @@
      * @param roster the roster to adapt
      */
     public RosterAdapter(final Roster roster) {
-	Log.d(TAG, "CTOR");
 	mAdaptee = roster;
 	roster.addRosterListener(mRosterListener);
 	for (RosterEntry entry : roster.getEntries()) {
 	    String user = StringUtils.parseBareAddress(entry.getUser());
-	    if (!mContacts.containsKey(user))
-		mContacts.put(user, new Contact(user));
+	    if (!mContacts.containsKey(user)) {
+		Contact c = new Contact(user);
+		c.setStatus(roster.getPresence(user));
+		mContacts.put(user, c);		
+	    }
 	}
     }
 
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Wed Apr 22 19:39:39 2009 +0200
@@ -10,12 +10,14 @@
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException;
 import org.jivesoftware.smack.packet.XMPPError;
+import org.jivesoftware.smackx.ChatStateManager;
 import org.jivesoftware.smackx.ServiceDiscoveryManager;
 import org.jivesoftware.smackx.jingle.JingleManager;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.util.Log;
 import com.beem.project.beem.BeemException;
+import com.beem.project.beem.BeemService;
 import com.beem.project.beem.service.aidl.IBeemConnectionListener;
 import com.beem.project.beem.service.aidl.IChatManager;
 import com.beem.project.beem.service.aidl.IRoster;
@@ -34,6 +36,7 @@
     private String mPassword;
     private RosterAdapter mRoster;
     private Object mLastException;
+    private BeemService mService;
 
     private RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners = new RemoteCallbackList<IBeemConnectionListener>();
     private ConnexionListenerAdapter mConListener = new ConnexionListenerAdapter();
@@ -44,10 +47,11 @@
      * @param login The login to use
      * @param password The password to use
      */
-    public XmppConnectionAdapter(final XMPPConnection con, final String login, final String password) {
+    public XmppConnectionAdapter(final XMPPConnection con, final String login, final String password, BeemService service) {
 	mAdaptee = con;
 	mLogin = login;
 	mPassword = password;
+	mService = service;
     }
 
     /**
@@ -56,8 +60,8 @@
      * @param login login to use on connect
      * @param password password to use on connect
      */
-    public XmppConnectionAdapter(final String serviceName, final String login, final String password) {
-	this(new XMPPConnection(serviceName), login, password);
+    public XmppConnectionAdapter(final String serviceName, final String login, final String password, BeemService service) {
+	this(new XMPPConnection(serviceName), login, password, service);
     }
 
     /**
@@ -66,8 +70,8 @@
      * @param login login to use on connect
      * @param password password to use on connect
      */
-    public XmppConnectionAdapter(final ConnectionConfiguration config, final String login, final String password) {
-	this(new XMPPConnection(config), login, password);
+    public XmppConnectionAdapter(final ConnectionConfiguration config, final String login, final String password, BeemService service) {
+	this(new XMPPConnection(config), login, password, service);
     }
 
     /**
@@ -79,9 +83,11 @@
 	    mAdaptee.connect();
 	    mAdaptee.addConnectionListener(mConListener);
 	    mAdaptee.login(mLogin, mPassword, "BEEM");
-	    mChatManager = new BeemChatManager(mAdaptee.getChatManager());
+	    
+	    mChatManager = new BeemChatManager(mAdaptee.getChatManager(), mService);
 	    // TODO find why this cause a null pointer exception
-	    // this.initFeatures(); // pour declarer les features xmpp qu'on supporte
+	    this.initFeatures(); // pour declarer les features xmpp qu'on supporte
+	    ChatStateManager.getInstance(mAdaptee);
 	    mLastException = null;
 	    triggerAsynchronousConnectEvent();
 	    return true;
@@ -172,9 +178,11 @@
      * enregistre les features dispo dans notre version Liste de features que Telepathy supporte.
      */
     private void initFeatures() {
+	ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mAdaptee);
+	if (sdm == null)
+	    sdm = new ServiceDiscoveryManager(mAdaptee);
+	sdm.addFeature("http://jabber.org/protocol/disco#info");
 	JingleManager.setJingleServiceEnabled();
-	ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(mAdaptee);
-	sdm.addFeature("http://jabber.org/protocol/disco#info");
 	// sdm.addFeature("http://jabber.org/protocol/nick");
 
     }
@@ -343,4 +351,8 @@
 	return mAdaptee;
     }
     
+    public BeemService getContext() {
+	return mService;
+    }
+    
 }
--- a/src/com/beem/project/beem/service/XmppFacade.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/XmppFacade.java	Wed Apr 22 19:39:39 2009 +0200
@@ -13,6 +13,7 @@
 import com.beem.project.beem.service.aidl.IRoster;
 import com.beem.project.beem.service.aidl.IXmppConnection;
 import com.beem.project.beem.service.aidl.IXmppFacade;
+import com.beem.project.beem.ui.ChangeStatus;
 
 /**
  * This class is a facade for the Beem Service.
@@ -96,14 +97,14 @@
 	
 	Notification mStatusNotification;
 	String text = (msg == null ? "" : msg);
-	mStatusNotification = new Notification(com.beem.project.beem.R.drawable.logo, text, System.currentTimeMillis());
+	mStatusNotification = new Notification(com.beem.project.beem.R.drawable.signal, text, System.currentTimeMillis());
 	mStatusNotification.defaults = Notification.DEFAULT_ALL;
 	mStatusNotification.flags = Notification.FLAG_NO_CLEAR;
 
 	// TODO
 	// mStatusNotification.contentView = ;
 	mStatusNotification.setLatestEventInfo(mBeemService, "Beem Status", text, PendingIntent.getActivity(
-	    mBeemService, 0, new Intent(), 0));
+	    mBeemService, 0, new Intent(mBeemService,ChangeStatus.class), 0));
 	mBeemService.sendNotification(BeemService.NOTIFICATION_STATUS_ID, mStatusNotification);
     }
 }
--- a/src/com/beem/project/beem/service/aidl/IChat.aidl	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/aidl/IChat.aidl	Wed Apr 22 19:39:39 2009 +0200
@@ -2,6 +2,7 @@
 
 import  com.beem.project.beem.service.Contact;
 import  com.beem.project.beem.service.Message;
+import  com.beem.project.beem.service.aidl.IMessageListener;
 
 /**
  * An aidl interface for Chat session.
@@ -22,5 +23,16 @@
 	
 	String getState();
 	
-	void setState(String state);
+	void setState(in String state);
+	
+	String getLastMessages();
+	
+	void addToLastMessages(in String msg);
+	
+	void clearLastMessages();
+/*	
+	void addMessageListener(in IMessageListener listener);
+	
+	void removeMessageListener(in IMessageListener listener);
+*/	
 }
\ No newline at end of file
--- a/src/com/beem/project/beem/service/aidl/IChatManager.aidl	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/aidl/IChatManager.aidl	Wed Apr 22 19:39:39 2009 +0200
@@ -22,6 +22,12 @@
 	IChat createChat(in Contact contact, in IMessageListener listener);
 	
 	/**
+    	 * Destroy a chat session with a contact.
+    	 * @param chat	the chat session
+    	 */
+	void destroyChat(in IChat chat);
+	
+	/**
 	 * Register a callback to call when a new chat session is created.
 	 * @param listener	the callback to add
 	 */
--- a/src/com/beem/project/beem/service/aidl/IMessageListener.aidl	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/service/aidl/IMessageListener.aidl	Wed Apr 22 19:39:39 2009 +0200
@@ -5,5 +5,5 @@
 
 interface IMessageListener {
 
-	void processMessage(in IChat chat, in Message msg); 
+	void processMessage(in IChat chat, in Message msg);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/AccountCreation.java	Wed Apr 22 19:39:39 2009 +0200
@@ -0,0 +1,110 @@
+/**
+ * 
+ */
+package com.beem.project.beem.ui;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jivesoftware.smack.AccountManager;
+import org.jivesoftware.smack.ConnectionConfiguration;
+import org.jivesoftware.smack.XMPPConnection;
+import org.jivesoftware.smack.XMPPException;
+
+import com.beem.project.beem.R;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+/**
+ * @author nikita
+ *
+ */
+public class AccountCreation extends Activity {    
+
+    protected static final String TAG = "AccountCreation";
+    private SharedPreferences mSettings;
+    Map<String, String> mAttributes = new HashMap<String, String>();
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.accountcreation);
+	Button ok = (Button) findViewById(R.id.ok);
+	mSettings = getSharedPreferences(
+		getString(R.string.PreferenceFileName), MODE_PRIVATE);
+	ok.setOnClickListener(mOkListener);
+    }
+
+    private OnClickListener mOkListener = new OnClickListener() {
+	
+	@Override
+	public void onClick(View v) {
+	    boolean valid = true;
+	    if (getWidgetText(R.id.login).length() == 0) {
+		Log.d(TAG, "login pas ok");
+		valid = false;
+	    } else {
+		mAttributes.put("login", getWidgetText(R.id.login));
+		mAttributes.put("name", getWidgetText(R.id.login));
+	    }
+	    if (getWidgetText(R.id.password).length() == 0 || !getWidgetText(R.id.password).contains(getWidgetText(R.id.password2))) {
+		valid = false;
+		
+	    } else {
+		mAttributes.put("password", getWidgetText(R.id.password));
+	    }
+	    if (getWidgetText(R.id.email).length() == 0) {
+		valid = false;
+	    } else {
+		mAttributes.put("email", getWidgetText(R.id.email));
+	    }
+	    
+	    if (valid) {
+		setResult(RESULT_OK);
+		try {
+		    createAccount();
+		    Toast.makeText(AccountCreation.this, "Account created",
+	                    Toast.LENGTH_SHORT).show();
+		    finish();
+		} catch (XMPPException e) {
+		    Log.e(TAG, "Account creation failed", e);
+		    Toast.makeText(AccountCreation.this, e.getMessage(),
+	                    Toast.LENGTH_SHORT).show();
+		    e.printStackTrace();
+		}
+	    } else {
+		Toast.makeText(AccountCreation.this, "Form error",
+                    Toast.LENGTH_SHORT).show();
+		setResult(RESULT_CANCELED);
+	    }
+	    
+	}
+    };
+
+    protected void createAccount() throws XMPPException {
+	String mHost = mSettings.getString(getString(R.string.PreferenceHostKey), "");
+	XMPPConnection xmmpCo = new XMPPConnection(new ConnectionConfiguration(mHost));
+	xmmpCo.connect();
+	AccountManager accM = new AccountManager(xmmpCo);
+	accM.createAccount(mAttributes.get("login"), mAttributes.get("password"), mAttributes);
+	xmmpCo.disconnect();
+	SharedPreferences.Editor editor = mSettings.edit();
+	
+	editor.putString(getString(R.string.PreferenceLoginKey), mAttributes.get("login"));
+	editor.putString(getString(R.string.PreferencePasswordKey), mAttributes.get("password"));
+	editor.commit();	
+    }
+    
+    private String getWidgetText(int id) {
+	EditText widget = (EditText) this.findViewById(id);
+	return widget.getText().toString();
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/ui/AddContact.java	Wed Apr 22 19:39:39 2009 +0200
@@ -0,0 +1,90 @@
+/**
+ * 
+ */
+package com.beem.project.beem.ui;
+
+import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.R;
+import com.beem.project.beem.service.aidl.IXmppFacade;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+/**
+ * @author nikita
+ *
+ */
+public class AddContact extends Activity {
+    
+    protected static final String TAG = "AddContact";
+    private String mLogin;
+    private String mAlias;
+    private String[] mGroup;
+    private IXmppFacade mService;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.addcontact);
+	Button ok = (Button) findViewById(R.id.ok);
+	//mAccountManager = new AccountManager();
+	ok.setOnClickListener(mOkListener);
+	mService = BeemApplication.getApplication(this).getXmppFacade();
+    }
+    
+    private OnClickListener mOkListener = new OnClickListener() {
+
+	@Override
+	public void onClick(View v) {
+	    boolean valid = true;
+	    if (getWidgetText(R.id.login).length() != 0) {
+		Log.d(TAG, "login pas ok");
+		valid = false;
+	    } else {
+		mLogin = getWidgetText(R.id.login);
+	    }
+	    if (getWidgetText(R.id.alias).length() != 0) {
+		Log.d(TAG, "alias pas ok");
+		valid = false;
+	    } else {
+		mAlias = getWidgetText(R.id.alias);
+	    }
+	    if (getWidgetText(R.id.group).length() != 0) {
+		Log.d(TAG, "group pas ok");
+		valid = false;
+	    } else {
+		mGroup[0] = getWidgetText(R.id.group);
+	    }
+	    if (valid) {
+		try {
+		    mService.getRoster().addContact(mLogin, mAlias, mGroup);
+		    Toast.makeText(AddContact.this, "Contact added",
+	                    Toast.LENGTH_SHORT).show();
+		    finish();
+		} catch (RemoteException e) {
+		    Toast.makeText(AddContact.this, e.getMessage(),
+	                    Toast.LENGTH_SHORT).show();
+		    e.printStackTrace();
+		}
+		setResult(RESULT_OK);
+	    } else {
+		Toast.makeText(AddContact.this, "Bad form",
+                    Toast.LENGTH_SHORT).show();
+		setResult(RESULT_CANCELED);
+	    }
+	    
+	}
+    };
+    
+    private String getWidgetText(int id) {
+	EditText widget = (EditText) this.findViewById(id);
+	return widget.getText().toString();
+    }
+}
--- a/src/com/beem/project/beem/ui/ChangeStatus.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/ui/ChangeStatus.java	Wed Apr 22 19:39:39 2009 +0200
@@ -1,11 +1,16 @@
 package com.beem.project.beem.ui;
 
 import android.app.Activity;
+
+import android.content.Intent;
+
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
+
 import android.os.Bundle;
-import android.util.Log;
+import android.os.Handler;
+import android.os.RemoteException;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.AdapterView;
@@ -16,138 +21,159 @@
 import android.widget.Toast;
 import android.widget.AdapterView.OnItemSelectedListener;
 
+import com.beem.project.beem.BeemApplication;
+import com.beem.project.beem.BeemService;
 import com.beem.project.beem.R;
+
+import com.beem.project.beem.service.aidl.IXmppFacade;
 import com.beem.project.beem.utils.Status;
 
 public class ChangeStatus extends Activity {
-    
     private TextView mStatusText;
     private Button mOk;
     private Button mClear;
-    private Spinner mSpin;
-    private String mSelectedStatus;
+    private Handler mHandler;
+    private BeemApplication mBeemApplication;
+    private IXmppFacade mService = null;
+    private Spinner mSpinner;
+    private static final String[] STATUS = { "Available for chat", "Available", "Busy", "Away", "Unavailable",
+	"Disconnected" };
+    private static final int DISCONNECTED_IDX = 5;
+    private static final int AVAILABLE_FOR_CHAT_IDX = 0;
+    private static final int AVAILABLE_IDX = 1;
+    private static final int BUSY_IDX = 2;
+    private static final int AWAY_IDX = 3;
+    private static final int UNAVAILABLE_IDX = 4;
     private SharedPreferences mSettings;
     private ArrayAdapter<String> mAdapter;
     private Context mContext = this;
     private Toast mToast;
-    private static final String[] mStatus = {"Available", "Available for chat",
-	"Busy", "Away", "Unavailable", "Disconnected"};
-    
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
-        // TODO Auto-generated method stub
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.changestatus);
-        
-        mStatusText = (TextView) findViewById(R.id.ChangeStatusText);
-        mOk = (Button) findViewById(R.id.ChangeStatusOk);
-        mClear = (Button) findViewById(R.id.ChangeStatusClear);
-        mOk.setOnClickListener(mOnClickOk);
-        mClear.setOnClickListener(mOnClickClear);
-        mSettings = getSharedPreferences(getString(R.string.PreferenceFileName),
-        	MODE_PRIVATE);
-        
-        mSpin = (Spinner) findViewById(R.id.ChangeStatusSpinner);
-        mAdapter = new ArrayAdapter<String>(this,
-                android.R.layout.simple_spinner_item, mStatus);
-        mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-        mSpin.setAdapter(mAdapter);
-        mSpin.setOnItemSelectedListener(mStatusItem);
-        showSettings();
+	super.onCreate(savedInstanceState);
+	setContentView(R.layout.changestatus);
+
+	// Beem Application specific
+	mHandler = new Handler();
+	mBeemApplication = BeemApplication.getApplication(this);
+
+	mStatusText = (TextView) findViewById(R.id.ChangeStatusText);
+	mOk = (Button) findViewById(R.id.ChangeStatusOk);
+	mClear = (Button) findViewById(R.id.ChangeStatusClear);
+	mOk.setOnClickListener(mOnClickOk);
+	mClear.setOnClickListener(mOnClickOk);
+	mSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
+
+	mSpinner = (Spinner) findViewById(R.id.ChangeStatusSpinner);
+	mAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, STATUS);
+	mAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+	mSpinner.setAdapter(mAdapter);
+	mToast = Toast.makeText(mContext, R.string.ChangeStatusOk, Toast.LENGTH_LONG);
+	showSettings();
     }
-    
-    private OnItemSelectedListener mStatusItem = new OnItemSelectedListener () {
-	@Override
-	public void onNothingSelected(AdapterView<?> arg0) {
-	}
+
+    @Override
+    protected void onStart() {
+	super.onStart();
+	mBeemApplication.startBeemService();
+    }
 
-	@Override
-	public void onItemSelected(AdapterView<?> sp, View v, int i,
-		long arg3) {
-	    mSelectedStatus = (String) sp.getSelectedItem();
-	}
-    };
-    
-    private OnClickListener mOnClickOk = new OnClickListener() {
-	public void onClick(View v) {
-	    if (textHasChanged() || statusHasChanged()) {
-		Editor edit = mSettings.edit();
-		edit.putString(getString(R.string.PreferenceStatusText),
-			mStatusText.getText().toString());
-		edit.putInt(getString(R.string.PreferenceStatus),
-			getStatusId(mSelectedStatus));
-		Log.i("Selected item --->", mSelectedStatus);
-		edit.commit();
-		mToast = Toast.makeText(mContext, R.string.ChangeStatusOk,
-			Toast.LENGTH_LONG);
-		mToast.show();
+    @Override
+    protected void onResume() {
+	super.onResume();
+	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {
+	    @Override
+	    public void run() {
+		mService = mBeemApplication.getXmppFacade();
 	    }
-	    else {
-		mToast = Toast.makeText(mContext, R.string.ChangeStatusNoChange,
-			Toast.LENGTH_LONG);
-		mToast.show();
+	});
+    }
+
+    @Override
+    protected void onDestroy() {
+	super.onDestroy();
+	mBeemApplication.unbindBeemService();
+    }
+
+    private void showSettings() {
+	mStatusText.setText(getPreferenceString(R.string.PreferenceStatusText));
+	mSpinner.setSelection(getPreferenceStatusIndex());
+    }
+
+    private int getStatusForService(String item) {
+	int res = Status.CONTACT_STATUS_AVAILABLE;
+	for (int i = 0; i < ChangeStatus.STATUS.length; i++) {
+	    String str = ChangeStatus.STATUS[i];
+	    if (str.equals(item)) {
+		switch (i) {
+		    case ChangeStatus.DISCONNECTED_IDX:
+			return Status.CONTACT_STATUS_DISCONNECT;
+		    case ChangeStatus.AVAILABLE_FOR_CHAT_IDX:
+			return Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT;
+		    case ChangeStatus.AVAILABLE_IDX:
+			return Status.CONTACT_STATUS_AVAILABLE;
+		    case ChangeStatus.AWAY_IDX:
+			return Status.CONTACT_STATUS_AWAY;
+		    case ChangeStatus.BUSY_IDX:
+			return Status.CONTACT_STATUS_BUSY;
+		    case ChangeStatus.UNAVAILABLE_IDX:
+			return Status.CONTACT_STATUS_UNAVAILABLE;
+		    default:
+			res = Status.CONTACT_STATUS_AVAILABLE;
+			break;
+		}
 	    }
 	}
-    };
-    
-    private OnClickListener mOnClickClear = new OnClickListener() {
-	public void onClick(View v) {
-	    mStatusText.setText(null);
-	}
-    };
-    
-    private boolean textHasChanged() {
-	return (!mStatusText.getText().toString().equals(
-		getPreferenceString(R.string.PreferenceStatusText)));
+	return res;
     }
-    
-    private boolean statusHasChanged() {
-	return (mSettings.getInt(getString(R.string.PreferenceStatus),
-		Status.CONTACT_STATUS_AVAILABLE) != getStatusId(mSelectedStatus));
-    }
-    
-    private void showSettings() {
-	mStatusText.setText(getPreferenceString(R.string.PreferenceStatusText));
-	mSpin.setSelection(getPreferenceStatusId());
-    }
-    
+
     private String getPreferenceString(int id) {
 	return mSettings.getString(getString(id), "");
     }
-    
-    private int getStatusId(String status) {
-	if (status.equals(mStatus[0]))
-	    return Status.CONTACT_STATUS_AVAILABLE; // 500
-	if (status.equals(mStatus[1]))
-	    return Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT; // 600
-	if (status.equals(mStatus[2]))
-	    return Status.CONTACT_STATUS_BUSY; // 400
-	if (status.equals(mStatus[3]))
-	    return Status.CONTACT_STATUS_AWAY; // 300
-	if (status.equals(mStatus[4]))
-	    return Status.CONTACT_STATUS_UNAVAILABLE; // 200
-	if (status.equals(mStatus[5]))
-	    return Status.CONTACT_STATUS_DISCONNECT; // 100
-	return Status.CONTACT_STATUS_AVAILABLE;
+
+    private int getPreferenceStatusIndex() {
+	return mSettings.getInt(getString(R.string.PreferenceStatus), 0);
     }
+
     
-    private int getPreferenceStatusId() {
-	switch (mSettings.getInt(getString(R.string.PreferenceStatus),
-		Status.CONTACT_STATUS_AVAILABLE)) {
-	    case Status.CONTACT_STATUS_DISCONNECT:
-		return 5;
-	    case Status.CONTACT_STATUS_UNAVAILABLE:
-		return 4;
-	    case Status.CONTACT_STATUS_AWAY:
-		return 3;
-	    case Status.CONTACT_STATUS_BUSY:
-		return 2;
-	    case Status.CONTACT_STATUS_AVAILABLE:
-		return 0;
-	    case Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT:
-		return 1;
-	    default:
-		return 0;
+    private OnClickListener mOnClickOk = new OnClickListener() {
+
+	private boolean textHasChanged() {
+	    return (!mStatusText.getText().toString().equals(getPreferenceString(R.string.PreferenceStatusText)));
+	}
+
+	private boolean statusHasChanged() {
+	    return (mSettings.getInt(getString(R.string.PreferenceStatus), 0) != mSpinner.getSelectedItemPosition());
 	}
-    }
+
+	public void onClick(View v) {
+	    if (v == mOk) {
+		if (textHasChanged() || statusHasChanged()) {
+		    String msg = mStatusText.getText().toString();
+		    int status = getStatusForService( (String) mSpinner.getSelectedItem());
+		    Editor edit = mSettings.edit();
+		    edit.putString(getString(R.string.PreferenceStatusText), msg);
+		    edit.putInt(getString(R.string.PreferenceStatus), mSpinner.getSelectedItemPosition());
+		    edit.commit();
+		    if (status == Status.CONTACT_STATUS_DISCONNECT) {
+			stopService(new Intent(ChangeStatus.this, BeemService.class));
+		    } else {
+			try {
+			    mService.changeStatus(status, msg.toString());
+			} catch (RemoteException e) {
+			    // TODO Auto-generated catch block
+			    e.printStackTrace();
+			}
+			mToast.show();
+		    }
+		}
+		ChangeStatus.this.finish();
+	    } else if (v == mClear) {
+		mStatusText.setText(null);
+	    }
+
+	}
+    };
+
 }
--- a/src/com/beem/project/beem/ui/ContactList.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/ui/ContactList.java	Wed Apr 22 19:39:39 2009 +0200
@@ -37,7 +37,8 @@
 public class ContactList extends ExpandableListActivity {
 
     private static final String TAG = "CONTACTLIST_ACT";
-    private static final int PREFERENCECHANGED = 0; 
+    private static final int PREFERENCECHANGED = 0;
+    private static final int CREATEACCOUNT = 1;
     private IXmppFacade mService = null;
     private SharedPreferences mSettings;
     private Handler mHandler;
@@ -48,11 +49,11 @@
     @SuppressWarnings("unchecked")
     @Override
     public boolean onChildClick(ExpandableListView parent, View v,
-	    int groupPosition, int childPosition, long id) {
+	int groupPosition, int childPosition, long id) {
 	Intent i = new Intent(this, SendIM.class);
 	Map<String, Contact> child = (HashMap<String, Contact>) parent
-		.getExpandableListAdapter().getChild(groupPosition,
-			childPosition);
+	.getExpandableListAdapter().getChild(groupPosition,
+	    childPosition);
 	i.putExtra("contact", child.get("CHILD"));
 	startActivity(i);
 	return true;
@@ -65,19 +66,26 @@
 	mHandler = new Handler();
 	mBeemApplication = BeemApplication.getApplication(this);
 	mSettings = getSharedPreferences(
-		getString(R.string.PreferenceFileName), MODE_PRIVATE);
+	    getString(R.string.PreferenceFileName), MODE_PRIVATE);
 	mRosterListener = new BeemRosterListener();
     }
 
     @Override
     protected void onStart() {
 	super.onStart();
-	mBeemApplication.startBeemService();
+    }
+
+    @Override
+    protected void onDestroy() {
+        // TODO Auto-generated method stub
+        super.onDestroy();
+        mBeemApplication.unbindBeemService();
     }
 
     @Override
     protected void onResume() {
 	super.onResume();
+	mBeemApplication.startBeemService();
 	/*
 	 * @TODO: A ameliorer apres listener de nikita
 	 */
@@ -110,7 +118,7 @@
 	if (mRoster != null)
 	    try {
 		showContactList(mRoster.getGroupsNames(), mRoster
-			.getContactList());
+		    .getContactList());
 	    } catch (RemoteException e) {
 		e.printStackTrace();
 	    }
@@ -146,24 +154,30 @@
 		return true;
 	    case R.id.account_about:
 		return true;
+	    case R.id.account_create:
+		startActivity(new Intent(this, AccountCreation.class));
+		return true;
+	    case R.id.add_contact:
+		startActivity(new Intent(this, AddContact.class));
+		return true;
 	    default:
 		return false;
 	}
     }
-    
+
     protected void onActivityResult(int requestCode, int resultCode,
-            Intent data) {
-        if (requestCode == PREFERENCECHANGED) {
-            if (resultCode == RESULT_OK) {
-                mBeemApplication.stopBeemService();
-                mBeemApplication.startBeemService();
-            }            
-        }
+	Intent data) {
+	if (requestCode == PREFERENCECHANGED) {
+	    if (resultCode == RESULT_OK) {
+		mBeemApplication.stopBeemService();
+		mBeemApplication.startBeemService();
+	    }            
+	}
     }
 
 
     private void showContactList(List<String> listGroup,
-	    List<Contact> listContact) {
+	List<Contact> listContact) {
 	ExpandableListAdapter Adapter;
 	List<Map<String, String>> groupData = new ArrayList<Map<String, String>>();
 	List<List<Map<String, Contact>>> childData = new ArrayList<List<Map<String, Contact>>>();
@@ -188,11 +202,11 @@
 	}
 
 	Adapter = new ContactExpandableListAdapter(this, groupData,
-		R.layout.contactlistgroup, new String[] { "GROUP" },
-		new int[] { R.id.textgroup }, childData,
-		R.layout.contactlistcontact, new String[] { "CHILD" },
-		new int[] { R.id.contactliststatus, R.id.contactlistpseudo,
-			R.id.contactlistmsgperso, R.id.contactlistavatar });
+	    R.layout.contactlistgroup, new String[] { "GROUP" },
+	    new int[] { R.id.textgroup }, childData,
+	    R.layout.contactlistcontact, new String[] { "CHILD" },
+	    new int[] { R.id.contactliststatus, R.id.contactlistpseudo,
+	    R.id.contactlistmsgperso, R.id.contactlistavatar });
 	setListAdapter(Adapter);
     }
 
@@ -202,19 +216,19 @@
      * getGroupView() to define the layout of parents)
      */
     private class ContactExpandableListAdapter extends
-	    SimpleExpandableListAdapter {
+    SimpleExpandableListAdapter {
 
 	private List<? extends List<? extends Map<String, ?>>> mChildData;
 	private String[] mChildFrom;
 	private int[] mChildTo;
 
 	public ContactExpandableListAdapter(Context context,
-		List<? extends Map<String, ?>> groupData, int groupLayout,
+	    List<? extends Map<String, ?>> groupData, int groupLayout,
 		String[] groupFrom, int[] groupTo,
 		List<? extends List<? extends Map<String, ?>>> childData,
-		int childLayout, String[] childFrom, int[] childTo) {
+		    int childLayout, String[] childFrom, int[] childTo) {
 	    super(context, groupData, groupLayout, groupFrom, groupTo,
-		    childData, childLayout, childFrom, childTo);
+		childData, childLayout, childFrom, childTo);
 
 	    mChildData = childData;
 	    mChildFrom = childFrom;
@@ -224,7 +238,7 @@
 
 	@Override
 	public View getChildView(int groupPosition, int childPosition,
-		boolean isLastChild, View convertView, ViewGroup parent) {
+	    boolean isLastChild, View convertView, ViewGroup parent) {
 
 	    View v;
 	    if (convertView == null) {
@@ -233,12 +247,12 @@
 		v = convertView;
 	    }
 	    bindView(v, mChildData.get(groupPosition).get(childPosition),
-		    mChildFrom, mChildTo, groupPosition, childPosition);
+		mChildFrom, mChildTo, groupPosition, childPosition);
 	    return v;
 	}
 
 	private void bindView(View view, Map<String, ?> data, String[] from,
-		int[] to, int groupPosition, int childPosition) {
+	    int[] to, int groupPosition, int childPosition) {
 	    Contact c = (Contact) data.get(from[0]);
 
 	    if (c != null) {
@@ -248,32 +262,32 @@
 		switch (c.getStatus()) {
 		    case Status.CONTACT_STATUS_AVAILABLE:
 			imageDrawable = (Drawable) getResources().getDrawable(
-				R.drawable.online);
+			    R.drawable.online);
 			break;
 		    case Status.CONTACT_STATUS_AVAILABLE_FOR_CHAT:
 			imageDrawable = (Drawable) getResources().getDrawable(
-				R.drawable.chat);
+			    R.drawable.chat);
 			break;
 		    case Status.CONTACT_STATUS_AWAY:
 			imageDrawable = (Drawable) getResources().getDrawable(
-				R.drawable.away);
+			    R.drawable.away);
 			break;
 		    case Status.CONTACT_STATUS_BUSY:
 			imageDrawable = (Drawable) getResources().getDrawable(
-				R.drawable.dnd);
+			    R.drawable.dnd);
 			break;
 		    case Status.CONTACT_STATUS_DISCONNECT:
 			imageDrawable = (Drawable) getResources().getDrawable(
-				R.drawable.offline);
+			    R.drawable.offline);
 			break;
 		    case Status.CONTACT_STATUS_UNAVAILABLE:
 			imageDrawable = (Drawable) getResources().getDrawable(
-				R.drawable.requested);
+			    R.drawable.requested);
 			break;
 		    default:
 			imageDrawable = (Drawable) getResources().getDrawable(
-				R.drawable.error);
-			break;
+			    R.drawable.error);
+		    break;
 		}
 		imgV.setImageDrawable(imageDrawable);
 
@@ -286,7 +300,7 @@
 		if (v != null) {
 		    v.setText(c.getMsgState());
 		}
-		
+
 		/*
 		 * TODO: Rajouter l'avatar du contact getAvatar() dans la
 		 * classe
@@ -294,7 +308,7 @@
 		imgV = (ImageView) view.findViewById(to[3]);
 		if (imgV != null) {
 		    imageDrawable = (Drawable) getResources().getDrawable(
-			    R.drawable.avatar);
+			R.drawable.avatar);
 		    imgV.setImageDrawable(imageDrawable);
 		}
 	    }
@@ -305,28 +319,28 @@
 
 	@Override
 	public void onEntriesAdded(List<String> addresses)
-		throws RemoteException {
+	throws RemoteException {
 	    Log.i(TAG, "ENTRIES ADDED");
 
 	}
 
 	@Override
 	public void onEntriesDeleted(List<String> addresses)
-		throws RemoteException {
+	throws RemoteException {
 	    Log.i(TAG, "ENTRIES DEL");
 
 	}
 
 	@Override
 	public void onEntriesUpdated(List<String> addresses)
-		throws RemoteException {
+	throws RemoteException {
 	    Log.i(TAG, "ENTRIES UPD");
 
 	}
 
 	@Override
 	public void onPresenceChanged(PresenceAdapter presence)
-		throws RemoteException {
+	throws RemoteException {
 	    Log.i(TAG, "PRESENCE CHANGED");
 
 	}
--- a/src/com/beem/project/beem/ui/SendIM.java	Wed Apr 22 15:19:42 2009 +0200
+++ b/src/com/beem/project/beem/ui/SendIM.java	Wed Apr 22 19:39:39 2009 +0200
@@ -29,15 +29,14 @@
 import com.beem.project.beem.service.aidl.IXmppFacade;
 
 /**
- * @author barbu This activity class provides the view for instant messaging
- *         after selecting a correspondant.
+ * This activity class provides the view for instant messaging after selecting a correspondant.
+ * @author barbu
  */
 
-public class SendIM extends Activity implements OnClickListener,
-	OnKeyListener {
+public class SendIM extends Activity implements OnClickListener, OnKeyListener {
     private EditText mToSend;
-    //private ArrayList<String> mMessages = new ArrayList<String>();
-    //private ArrayAdapter<String> mAdapter;
+    // private ArrayList<String> mMessages = new ArrayList<String>();
+    // private ArrayAdapter<String> mAdapter;
     private SendIMDialogSmiley mSmyDialog;
     private SharedPreferences mSet;
     private SharedPreferences mGlobalSettings;
@@ -53,7 +52,7 @@
     private TextView mText;
     private TextView mLogin;
     private ScrollView mScrolling;
-    private Boolean mSpeak;
+    private boolean mSpeak;
 
     /**
      * Constructor.
@@ -77,24 +76,19 @@
 	mToSend = (EditText) findViewById(R.id.userText);
 	mSet = getSharedPreferences("lol", MODE_PRIVATE);
 	mSmyDialog = new SendIMDialogSmiley(this, mSet);
-	mGlobalSettings = getSharedPreferences(
-		getString(R.string.PreferenceFileName), MODE_PRIVATE);
-	/*mAdapter = new ArrayAdapter<String>(this, R.layout.messagelist,
-		mMessages);
-	setListAdapter(mAdapter);*/
+	mGlobalSettings = getSharedPreferences(getString(R.string.PreferenceFileName), MODE_PRIVATE);
+	/*
+	 * mAdapter = new ArrayAdapter<String>(this, R.layout.messagelist, mMessages); setListAdapter(mAdapter);
+	 */
 
 	mToSend.setOnClickListener(this);
 	mToSend.setOnKeyListener(this);
-	
-	mContact = getIntent().getParcelableExtra("contact");
-	setViewHeader();
+	mLogin = (TextView) findViewById(R.id.sendimlogin);
 	mText = (TextView) findViewById(R.id.sendimlist);
 	mScrolling = (ScrollView) findViewById(R.id.sendimscroll);
     }
-    
-    private void setViewHeader()
-    {
-	mLogin = (TextView) findViewById(R.id.sendimlogin);
+
+    private void setViewHeader() {
 	String status = mContact.getMsgState();
 	if (status == null)
 	    status = getString(R.string.SendIMNoStatusSet);
@@ -106,15 +100,59 @@
     @Override
     public void onStart() {
 	super.onStart();
-	mBeemApplication.startBeemService();
+	// TODO cancel the notification if any
+	if (mContact == null)
+	    mContact = getIntent().getParcelableExtra("contact");
+	setViewHeader();
 	mService = mBeemApplication.getXmppFacade();
-	try {
-	    mChatManager = mService.getChatManager();
-	    mChatManager.addChatCreationListener(mChatManagerListener);
-	    mChat = mChatManager.createChat(mContact, mMessageListener);
-	} catch (RemoteException e) {
-	    // TODO Auto-generated catch block
-	    e.printStackTrace();
+
+    }
+
+    @Override
+    protected void onResume() {
+	super.onResume();
+	mBeemApplication.startBeemService();
+	mBeemApplication.callWhenConnectedToServer(mHandler, new Runnable() {
+
+	    @Override
+	    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(text);
+			mChat.clearLastMessages();
+		    }
+		} catch (RemoteException e) {
+		    // TODO Auto-generated catch block
+		    e.printStackTrace();
+		}
+	    }
+	});
+
+    }
+
+    @Override
+    protected void onStop() {
+        // TODO Auto-generated method stub
+        super.onStop();
+        mBeemApplication.unbindBeemService();
+    }
+    
+    @Override
+    protected void onDestroy() {
+	super.onDestroy();
+	if (mChatManager != null) {
+	    try {
+		mChatManager.removeChatCreationListener(mChatManagerListener);
+		mChatManager.destroyChat(mChat);
+	    } catch (RemoteException e) {
+		// TODO Auto-generated catch block
+		e.printStackTrace();
+	    }
 	}
     }
 
@@ -126,12 +164,11 @@
     }
 
     /**
-     * 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
+     * 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
      */
     private void sendText() {
-	if (mSpeak == null)
+	if (mSpeak)
 	    mSpeak = false;
 	String text = mToSend.getText().toString();
 	if (!text.equals("")) {
@@ -171,9 +208,7 @@
 
     /**
      * Callback for menu creation.
-     * 
-     * @param menu
-     *            the menu created
+     * @param menu the menu created
      * @return true on success, false otherwise
      */
     @Override
@@ -198,8 +233,7 @@
     private class OnChatListener extends IChatManagerListener.Stub {
 
 	@Override
-	public void chatCreated(IChat chat, boolean locally)
-		throws RemoteException {
+	public void chatCreated(IChat chat, boolean locally) throws RemoteException {
 	    Log.i("LOG", "chatCreated");
 
 	}
@@ -209,29 +243,29 @@
     private class OnMessageListener extends IMessageListener.Stub {
 
 	@Override
-	public void processMessage(IChat chat, Message msg)
-		throws RemoteException {
+	public void processMessage(IChat chat, Message msg) throws RemoteException {
 	    Log.i("LOG", "processMessage");
-	    /*mAdapter.add(mContact.getJID() + " "
-		    + getString(R.string.SendIMSays) + msg.getBody());*/
-	    
+	    /*
+	     * mAdapter.add(mContact.getJID() + " " + getString(R.string.SendIMSays) + msg.getBody());
+	     */
+	    if (chat != mChat)
+		return;
+
 	    final Message m = msg;
 	    mHandler.post(new Runnable() {
-	    
-	        @Override
-	        public void run() {
-	            if (m.getBody() != null)
-	            {
-	        	if (!mSpeak)
-	        	    mText.append(m.getBody() + "\n");
-	        	else
-	        	    mText.append(mContact.getJID() + " "
-				    + getString(R.string.SendIMSays) + m.getBody() + "\n");
-	        	mSpeak = false;
-	        	mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
-	        	mToSend.requestFocus();
-	            }
-	        }
+
+		@Override
+		public void run() {
+		    if (m.getBody() != null) {
+			if (!mSpeak)
+			    mText.append(m.getBody() + "\n");
+			else
+			    mText.append(mContact.getJID() + " " + getString(R.string.SendIMSays) + m.getBody() + "\n");
+			mSpeak = false;
+			mScrolling.fullScroll(ScrollView.FOCUS_DOWN);
+			mToSend.requestFocus();
+		    }
+		}
 	    });
 	}
     }