Fix many bugs and memory leak
authorDa Risk <darisk972@gmail.com>
Fri, 18 Dec 2009 20:32:43 +0100
changeset 584 72d9d76900af
parent 583 ca7bec1b5754
child 585 ce60e3c1347d
Fix many bugs and memory leak
src/com/beem/project/beem/service/BeemChatManager.java
src/com/beem/project/beem/service/ChatAdapter.java
src/com/beem/project/beem/ui/AddContact.java
src/com/beem/project/beem/ui/ChangeStatus.java
src/com/beem/project/beem/ui/Chat.java
src/com/beem/project/beem/ui/ContactList.java
src/com/beem/project/beem/ui/GroupList.java
src/com/beem/project/beem/ui/PrivacyList.java
src/com/beem/project/beem/ui/Subscription.java
src/com/beem/project/beem/utils/BeemBroadcastReceiver.java
--- a/src/com/beem/project/beem/service/BeemChatManager.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/service/BeemChatManager.java	Fri Dec 18 20:32:43 2009 +0100
@@ -52,10 +52,7 @@
 import org.jivesoftware.smack.ChatManager;
 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.app.Notification;
 import android.app.PendingIntent;
@@ -71,6 +68,7 @@
 import com.beem.project.beem.service.aidl.IChatManagerListener;
 import com.beem.project.beem.service.aidl.IMessageListener;
 import com.beem.project.beem.service.aidl.IRoster;
+import com.beem.project.beem.service.Message;
 
 // TODO: Auto-generated Javadoc
 /**
@@ -83,7 +81,7 @@
      * A listener for all the chat creation event that happens on the connection.
      * @author darisk
      */
-    private class ChatListener implements ChatStateListener, ChatManagerListener, MessageListener {
+    private class ChatListener extends IMessageListener.Stub implements ChatManagerListener {
 
 	/**
 	 * Constructor.
@@ -97,20 +95,20 @@
 	@Override
 	public void chatCreated(Chat chat, boolean locally) {
 	    IChat newchat = getChat(chat);
-	    chat.addMessageListener(mChatListener);
-	    final int n = mRemoteChatCreationListeners.beginBroadcast();
+	    try {
+		newchat.addMessageListener(mChatListener);
+		final int n = mRemoteChatCreationListeners.beginBroadcast();
 
-	    for (int i = 0; i < n; i++) {
-		IChatManagerListener listener = mRemoteChatCreationListeners.getBroadcastItem(i);
-		try {
+		for (int i = 0; i < n; i++) {
+		    IChatManagerListener listener = mRemoteChatCreationListeners.getBroadcastItem(i);
 		    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 in chat creation", e);
 		}
+		mRemoteChatCreationListeners.finishBroadcast();
+	    } catch (RemoteException e) {
+		// The RemoteCallbackList will take care of removing the
+		// dead listeners.
+		Log.w(TAG, " Error while triggering remote connection listeners in chat creation", e);
 	    }
-	    mRemoteChatCreationListeners.finishBroadcast();
 	}
 
 	/**
@@ -127,7 +125,7 @@
 		Log.e(TAG, e.getMessage());
 	    }
 	    PendingIntent contentIntent = PendingIntent.getActivity(mService, 0, chatIntent,
-		PendingIntent.FLAG_UPDATE_CURRENT);
+		    PendingIntent.FLAG_UPDATE_CURRENT);
 	    return contentIntent;
 	}
 
@@ -140,11 +138,11 @@
 		CharSequence tickerText = mService.getBind().getRoster().getContact(chat.getParticipant().getJID())
 		    .getName();
 		Notification notification = new Notification(android.R.drawable.stat_notify_chat, tickerText, System
-		    .currentTimeMillis());
+			.currentTimeMillis());
 		notification.defaults = Notification.DEFAULT_ALL;
 		notification.flags = Notification.FLAG_AUTO_CANCEL;
 		notification.setLatestEventInfo(mService, tickerText, mService
-		    .getString(R.string.BeemChatManagerNewMessage), makeChatIntent(chat));
+			.getString(R.string.BeemChatManagerNewMessage), makeChatIntent(chat));
 		mService.sendNotification(chat.hashCode(), notification);
 	    } catch (RemoteException e) {
 		Log.e(TAG, e.getMessage());
@@ -155,48 +153,18 @@
 	 * {@inheritDoc}
 	 */
 	@Override
-	public void processMessage(Chat chat, Message message) {
-	    ChatAdapter newchat = getChat(chat);
-	    try {
-		if (message.getBody() != null)
-		    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() && message.getBody() != null) {
-		    notifyNewChat(newchat);
-		}
-	    } catch (RemoteException e) {
-		Log.w(TAG, e.getMessage());
-	    }
-	}
-
-	/**
-	 * {@inheritDoc}
-	 */
-	@Override
-	public void stateChanged(Chat chat, ChatState state) {
-	    IChat newchat = getChat(chat);
-	    try {
-		newchat.setState(state.name());
-	    } catch (RemoteException e) {
-		e.printStackTrace();
-	    }
-	    final int n = mRemoteMessageListeners.beginBroadcast();
-
-	    for (int i = 0; i < n; i++) {
-		IMessageListener listener = mRemoteMessageListeners.getBroadcastItem(i);
+	    public void processMessage(IChat chat, Message message) {
 		try {
-		    listener.stateChanged(newchat);
+		    if (!chat.isOpen() && message.getBody() != null) {
+			notifyNewChat(chat);
+		    }
 		} catch (RemoteException e) {
 		    Log.w(TAG, e.getMessage());
 		}
 	    }
-	    mRemoteMessageListeners.finishBroadcast();
-	}
+
+	@Override
+	    public void stateChanged(IChat chat) {}
     }
 
     /** Tag to use with log methods. */
@@ -205,7 +173,6 @@
     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 final BeemService mService;
 
     /**
@@ -224,7 +191,8 @@
      */
     @Override
     public void addChatCreationListener(IChatManagerListener listener) throws RemoteException {
-	mRemoteChatCreationListeners.register(listener);
+	if (listener != null)
+	    mRemoteChatCreationListeners.register(listener);
     }
 
     /**
@@ -233,6 +201,7 @@
      * @param listener listener to use for chat events on this chat session
      * @return the chat session
      */
+    @Override
     public IChat createChat(Contact contact, IMessageListener listener) {
 	String jid = contact.getJID();
 	return createChat(jid, listener);
@@ -245,13 +214,18 @@
      * @return the chat session
      */
     public IChat createChat(String jid, IMessageListener listener) {
-	mRemoteMessageListeners.register(listener);
 	String key = StringUtils.parseBareAddress(jid);
+	ChatAdapter result;
 	if (mChats.containsKey(key)) {
-	    return mChats.get(key);
+	    result = mChats.get(key);
+	    result.addMessageListener(listener);
+	    return result;
 	}
-	mAdaptee.createChat(key, mChatListener);
-	return mChats.get(key);
+	Chat c = mAdaptee.createChat(key, null);
+	result = new ChatAdapter(c);
+	result.addMessageListener(listener);
+	mChats.put(key, result);
+	return result;
     }
 
     /**
@@ -259,11 +233,7 @@
      */
     @Override
     public void destroyChat(IChat chat) throws RemoteException {
-	Log.d(TAG, "BEGIN destroyChat - jid = " + chat.getParticipant().getJID());
-	IChat c = mChats.remove(chat.getParticipant().getJID());
-	if (c == null)
-	    Log.w(TAG, "destroyChat - chat = null, jid = " + chat.getParticipant().getJID());
-	Log.d(TAG, "END destroyChat - jid = " + chat.getParticipant().getJID());
+	mChats.remove(chat.getParticipant().getJID());
     }
 
     /* (non-Javadoc)
@@ -299,7 +269,7 @@
 	IRoster mRoster = mService.getBind().getRoster();
 
 	for (ChatAdapter chat : mChats.values()) {
-	    if (chat.getMessages().size() > 0) // TODO check plutot le nombre de messages dans l'historique
+	    if (chat.getMessages().size() > 0) // TODO Verifier si le contact n'est pas dans le Roster
 		openedChats.add(mRoster.getContact(chat.getParticipant().getJID()));
 	}
 	return openedChats;
@@ -310,7 +280,8 @@
      */
     @Override
     public void removeChatCreationListener(IChatManagerListener listener) throws RemoteException {
-	mRemoteChatCreationListeners.unregister(listener);
+	if (listener != null)
+	    mRemoteChatCreationListeners.unregister(listener);
     }
 
 }
--- a/src/com/beem/project/beem/service/ChatAdapter.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/service/ChatAdapter.java	Fri Dec 18 20:32:43 2009 +0100
@@ -50,6 +50,8 @@
 import org.jivesoftware.smack.Chat;
 import org.jivesoftware.smack.XMPPException;
 import org.jivesoftware.smack.MessageListener;
+import org.jivesoftware.smackx.ChatStateListener;
+import org.jivesoftware.smackx.ChatState;
 
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
@@ -130,8 +132,9 @@
      */
     @Override
     public void removeMessageListener(IMessageListener listen) {
-	if (listen != null)
+	if (listen != null) {
 	    mRemoteListeners.unregister(listen);
+	}
     }
 
     /**
@@ -192,21 +195,42 @@
 	mMessages.add(msg);
     }
 
-    private class MsgListener implements MessageListener {
+    private class MsgListener implements MessageListener, ChatStateListener {
 	@Override
 	public void processMessage(Chat chat, org.jivesoftware.smack.packet.Message message) {
+	    Message  msg = new Message(message);
+	    ChatAdapter.this.addMessage(msg);
 	    final int n = mRemoteListeners.beginBroadcast();
 	    for (int i = 0; i < n; i++) {
 		IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
 		try {
 		    if (listener != null)
-			listener.processMessage(ChatAdapter.this, new Message(message));
+			listener.processMessage(ChatAdapter.this, msg);
 		} catch (RemoteException e) {
 		    Log.w(TAG, "Error while diffusing message to listener", e);
 		}
 	    }
 	    mRemoteListeners.finishBroadcast();
 	}
+
+	/**
+	 * {@inheritDoc}
+	 */
+	@Override
+	public void stateChanged(Chat chat, ChatState state) {
+	    mState = state.name();
+	    final int n = mRemoteListeners.beginBroadcast();
+
+	    for (int i = 0; i < n; i++) {
+		IMessageListener listener = mRemoteListeners.getBroadcastItem(i);
+		try {
+		    listener.stateChanged(ChatAdapter.this);
+		} catch (RemoteException e) {
+		    Log.w(TAG, e.getMessage());
+		}
+	    }
+	    mRemoteListeners.finishBroadcast();
+	}
     }
 }
 
--- a/src/com/beem/project/beem/ui/AddContact.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/ui/AddContact.java	Fri Dec 18 20:32:43 2009 +0100
@@ -79,7 +79,7 @@
     private final List<String> mGroup = new ArrayList<String>();
     private IXmppFacade mXmppFacade;
     private final ServiceConnection mServConn = new BeemServiceConnection();
-    private BeemBroadcastReceiver mReceiver;
+    private final BeemBroadcastReceiver mReceiver = new BeemBroadcastReceiver();
 
     static {
 	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
@@ -100,7 +100,7 @@
 	setContentView(R.layout.addcontact);
 	Button ok = (Button) findViewById(R.id.addc_ok);
 	ok.setOnClickListener(mOkListener);
-	mReceiver = new BeemBroadcastReceiver(mServConn);
+	this.registerReceiver(mReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
     }
 
     /* (non-Javadoc)
@@ -109,7 +109,6 @@
     @Override
     protected void onStart() {
 	super.onStart();
-	this.registerReceiver(mReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
     }
 
     /**
@@ -118,9 +117,7 @@
     @Override
     protected void onResume() {
 	super.onResume();
-	this.registerReceiver(mReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
 	bindService(new Intent(this, BeemService.class), mServConn, BIND_AUTO_CREATE);
-	mReceiver.setBinded(true);
     }
 
     /**
@@ -129,10 +126,7 @@
     @Override
     protected void onPause() {
 	super.onPause();
-	if (mReceiver.isBinded()) {
-	    unbindService(mServConn);
-	    mReceiver.setBinded(false);
-	}
+	unbindService(mServConn);
     }
 
     /* (non-Javadoc)
@@ -158,7 +152,6 @@
 	@Override
 	public void onServiceConnected(ComponentName name, IBinder service) {
 	    mXmppFacade = IXmppFacade.Stub.asInterface(service);
-	    mReceiver.setBinded(true);
 	}
 
 	@Override
--- a/src/com/beem/project/beem/ui/ChangeStatus.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/ui/ChangeStatus.java	Fri Dec 18 20:32:43 2009 +0100
@@ -100,7 +100,7 @@
     private IXmppFacade mXmppFacade;
     private final ServiceConnection mServConn = new BeemServiceConnection();
     private final OnClickListener mOnClickOk = new MyOnClickListener();
-    private BeemBroadcastReceiver mReceiver;
+    private final BeemBroadcastReceiver mReceiver = new BeemBroadcastReceiver();
 
     /**
      * Constructor.
@@ -138,7 +138,6 @@
 	mToast = Toast.makeText(this, R.string.ChangeStatusOk, Toast.LENGTH_LONG);
 	mSpinner.setSelection(getPreferenceStatusIndex());
 
-	mReceiver = new BeemBroadcastReceiver(mServConn);
 	this.registerReceiver(mReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
     }
 
@@ -149,7 +148,6 @@
     protected void onResume() {
 	super.onResume();
 	bindService(new Intent(this, BeemService.class), mServConn, BIND_AUTO_CREATE);
-	mReceiver.setBinded(true);
     }
 
     /**
@@ -159,10 +157,7 @@
     protected void onPause() {
 	super.onPause();
 	Log.d("TAG", "pause");
-	if (mReceiver.isBinded()) {
-	    unbindService(mServConn);
-	    mReceiver.setBinded(false);
-	}
+	unbindService(mServConn);
     }
 
     /* (non-Javadoc)
--- a/src/com/beem/project/beem/ui/Chat.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/ui/Chat.java	Fri Dec 18 20:32:43 2009 +0100
@@ -111,7 +111,7 @@
     static {
 	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
     }
-    private Handler mHandler;
+    private Handler mHandler = new Handler();
 
     private IRoster mRoster;
     private Contact mContact;
@@ -128,12 +128,13 @@
 
     private IChat mChat;
     private IChatManager mChatManager;
-    private IChatManagerListener mChatManagerListener;
-    private IMessageListener mMessageListener;
-    private MessagesListAdapter mMessagesListAdapter;
+    private final IMessageListener mMessageListener = new OnMessageListener();
+    private MessagesListAdapter mMessagesListAdapter = new MessagesListAdapter();
 
     private final ServiceConnection mConn = new BeemServiceConnection();
-    private BeemBroadcastReceiver mBroadcastReceiver;
+    private final BeemBroadcastReceiver mBroadcastReceiver = new BeemBroadcastReceiver();
+    private final BeemRosterListener mBeemRosterListener = new BeemRosterListener();
+    private IXmppFacade mXmppFacade;
 
     /**
      * Constructor.
@@ -148,21 +149,7 @@
     @Override
     protected void onCreate(Bundle savedBundle) {
 	super.onCreate(savedBundle);
-
-	Log.v(TAG, "BEGIN onCreate.");
 	setContentView(R.layout.chat);
-	mMessagesListAdapter = new MessagesListAdapter(this);
-
-	mHandler = new Handler();
-
-	// SVC Bind
-	bindService(SERVICE_INTENT, mConn, BIND_AUTO_CREATE);
-	
-	// Listeners
-	mMessageListener = new OnMessageListener();
-	mChatManagerListener = new OnChatManagerListener();
-
-	mBroadcastReceiver = new BeemBroadcastReceiver(mConn);
 	this.registerReceiver(mBroadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
 	
 	// UI
@@ -182,8 +169,13 @@
 	});
 
 	prepareIconsStatus();
+    }
 
-	Log.v(TAG, "END onCreate.");
+    @Override
+    protected void onStart() {
+	super.onStart();
+	if (mXmppFacade == null)
+	    bindService(SERVICE_INTENT, mConn, BIND_AUTO_CREATE);
     }
 
     /**
@@ -192,32 +184,7 @@
     @Override
     protected void onDestroy() {
 	super.onDestroy();
-
-	Log.v(TAG, "BEGIN onDestroy.");
-	
-	if (mChatManager != null) {
-	    try {
-		mChatManager.removeChatCreationListener(mChatManagerListener);
-	    } catch (RemoteException e) {
-		Log.e(TAG, e.getMessage());
-	    }
-	}
-	
 	this.unregisterReceiver(mBroadcastReceiver);
-	unbindService(mConn);
-	
-	Log.v(TAG, "END onDestroy.");
-    }
-
-    /**
-     * {@inheritDoc}.
-     */
-    @Override
-    protected void onStart() {
-	super.onStart();
-
-	Log.v(TAG, "BEGIN onStart.");
-	Log.v(TAG, "END onStart.");
     }
 
     /**
@@ -227,23 +194,21 @@
     protected void onStop() {
 	super.onStop();
 
-	Log.v(TAG, "BEGIN onStop.");
-	if (mChat != null) {
-	    try {
+	try {
+	    if (mChat != null) {
 		mChat.setOpen(false);
-	    } catch (RemoteException e) {
-		Log.e(TAG, e.getMessage());
+		mChat.removeMessageListener(mMessageListener);
 	    }
+	    if (mRoster != null)
+		mRoster.removeRosterListener(mBeemRosterListener);
+	} catch (RemoteException e) {
+	    Log.e(TAG, e.getMessage());
 	}
-	Log.v(TAG, "END onStop.");
-    }
-
-    /**
-     * {@inheritDoc}.
-     */
-    @Override
-    protected void onResume() {
-	super.onResume();
+	unbindService(mConn);
+	mXmppFacade = null;
+	mRoster = null;
+	mChat = null;
+	mChatManager = null;
     }
 
     /**
@@ -260,15 +225,12 @@
     @Override
     protected void onNewIntent(Intent intent) {
 	super.onNewIntent(intent);
-
-	Log.v(TAG, "BEGIN onNewIntent.");
 	try {
 	    mContact = new Contact(intent.getData());
 	    changeCurrentChat(mContact);
 	} catch (RemoteException e) {
 	    Log.e(TAG, e.getMessage());
 	}
-	Log.v(TAG, "END onNewIntent.");
     }
 
     /**
@@ -295,7 +257,6 @@
     @Override
     public final boolean onCreateOptionsMenu(Menu menu) {
 	super.onCreateOptionsMenu(menu);
-
 	MenuInflater inflater = getMenuInflater();
 	inflater.inflate(R.menu.chat, menu);
 	return true;
@@ -315,7 +276,6 @@
 	    case R.id.chat_menu_change_chat:
 		try {
 		    final List<Contact> openedChats = mChatManager.getOpenedChatList();
-
 		    if (openedChats.size() > 0)
 			createChatSwitcherDialog(openedChats);
 		    else
@@ -378,20 +338,21 @@
      * @throws RemoteException If a Binder remote-invocation error occurred.
      */
     private void changeCurrentChat(Contact contact) throws RemoteException {
-	Log.v(TAG, "BEGIN changeCurrentChat.");
-	if (mChat != null)
+	if (mChat != null) {
 	    mChat.setOpen(false);
+	    mChat.removeMessageListener(mMessageListener);
+	}
 	mChat = mChatManager.createChat(contact, mMessageListener);
 	mChat.setOpen(true);
-
 	mChatManager.deleteChatNotification(mChat);
 
+	// TODO thecontact isnotnecesarrely ubn the roseter.
+	// this can leadtoa null exception
 	mContact = mRoster.getContact(contact.getJID());
 	updateContactInformations();
 	updateContactStatusIcon();
 
 	playRegisteredTranscript();
-	Log.v(TAG, "END changeCurrentChat.");
     }
 
     /**
@@ -402,35 +363,26 @@
 	String fromBareJid = null;
 	String fromName = null;
 	List<Message> chatMessages = mChat.getMessages();
+	mListMessages.clear();
+	MessageText lastMessage = null;
 
-	Log.v(TAG, "BEGIN playRegisteredTranscript.");
-	mListMessages.clear();
-	if (chatMessages.size() > 0) {
-	    MessageText lastMessage = null;
-	    for (Message m : chatMessages) {
-		fromBareJid = StringUtils.parseBareAddress(m.getFrom());
-		fromName = mContact.getName();
-
-		if (fromBareJid == null) {
-		    fromBareJid = getString(R.string.chat_self);
-		    fromName = getString(R.string.chat_self);
+	for (Message m : chatMessages) {
+	    fromBareJid = StringUtils.parseBareAddress(m.getFrom());
+	    fromName = mContact.getName();
+	    if (fromBareJid == null) {
+		fromBareJid = getString(R.string.chat_self);
+		fromName = getString(R.string.chat_self);
+	    }
+	    if (m.getBody() != null) {
+		if (lastMessage == null || !lastMessage.getBareJid().equals(fromBareJid)) {
+		    lastMessage = new MessageText(fromBareJid, fromName, m.getBody());
+		    mListMessages.add(lastMessage);
+		} else {
+		    lastMessage.setMessage(lastMessage.getMessage().concat("\n" + m.getBody()));
 		}
-
-		if (lastMessage == null) {
-		    lastMessage = new MessageText(fromBareJid, fromName, m.getBody());
-		    continue;
-		}
-
-		if (!lastMessage.getBareJid().equals(fromBareJid)) {
-		    mListMessages.add(lastMessage);
-		    lastMessage = new MessageText(fromBareJid, fromName, m.getBody());
-		} else
-		    lastMessage.setMessage(lastMessage.getMessage().concat("\n" + m.getBody()));
 	    }
-	    mListMessages.add(lastMessage);
 	}
 	mMessagesListAdapter.notifyDataSetChanged();
-	Log.v(TAG, "END playRegisteredTranscript.");
     }
 
     /**
@@ -438,44 +390,36 @@
      */
     private final class BeemServiceConnection implements ServiceConnection {
 
-	private IXmppFacade mXmppFacade;
-	private final BeemRosterListener mBeemRosterListener = new BeemRosterListener();
 
 	/**
 	 * {@inheritDoc}.
 	 */
 	@Override
-	public void onServiceConnected(ComponentName name, IBinder service) {
-	    Log.v(TAG, "BEGIN onServiceConnected.");
-	    mXmppFacade = IXmppFacade.Stub.asInterface(service);
-	    mBroadcastReceiver.setBinded(true);
-	    try {
-		mChatManager = mXmppFacade.getChatManager();
-		mRoster = mXmppFacade.getRoster();
-		mRoster.addRosterListener(mBeemRosterListener);
-		mContact = new Contact(getIntent().getData());
-		changeCurrentChat(mContact);
-	    } catch (RemoteException e) {
-		Log.e(TAG, e.getMessage());
+	    public void onServiceConnected(ComponentName name, IBinder service) {
+		mXmppFacade = IXmppFacade.Stub.asInterface(service);
+		try {
+		    mChatManager = mXmppFacade.getChatManager();
+		    mRoster = mXmppFacade.getRoster();
+		    mRoster.addRosterListener(mBeemRosterListener);
+		    mContact = new Contact(getIntent().getData());
+		    changeCurrentChat(mContact);
+		} catch (RemoteException e) {
+		    Log.e(TAG, e.getMessage());
+		}
 	    }
-	    Log.v(TAG, "END onServiceConnected.");
-	}
 
 	/**
 	 * {@inheritDoc}.
 	 */
 	@Override
-	public void onServiceDisconnected(ComponentName name) {
-	    Log.v(TAG, "BEGIN onServiceDisconnected.");
-	    mXmppFacade = null;
-	    mBroadcastReceiver.setBinded(false);
-	    try {
-		mRoster.removeRosterListener(mBeemRosterListener);
-	    } catch (RemoteException e) {
-		Log.e(TAG, e.getMessage());
+	    public void onServiceDisconnected(ComponentName name) {
+		mXmppFacade = null;
+		try {
+		    mRoster.removeRosterListener(mBeemRosterListener);
+		} catch (RemoteException e) {
+		    Log.e(TAG, e.getMessage());
+		}
 	    }
-	    Log.v(TAG, "END onServiceDisconnected.");
-	}
     }
 
     /**
@@ -488,8 +432,6 @@
 	 */
 	@Override
 	public void onEntriesAdded(List<String> addresses) throws RemoteException {
-	    Log.v(TAG, "BEGIN onEntriesAdded.");
-	    Log.v(TAG, "END onEntriesAdded.");
 	}
 
 	/**
@@ -497,8 +439,6 @@
 	 */
 	@Override
 	public void onEntriesDeleted(List<String> addresses) throws RemoteException {
-	    Log.v(TAG, "BEGIN onEntriesDeleted.");
-	    Log.v(TAG, "END onEntriesDeleted.");
 	}
 
 	/**
@@ -506,8 +446,6 @@
 	 */
 	@Override
 	public void onEntriesUpdated(List<String> addresses) throws RemoteException {
-	    Log.v(TAG, "BEGIN onEntriesUpdated.");
-	    Log.v(TAG, "END onEntriesUpdated.");
 	}
 
 	/**
@@ -515,8 +453,6 @@
 	 */
 	@Override
 	public void onEntryDeleteFromGroup(String group, String jid) throws RemoteException {
-	    Log.v(TAG, "BEGIN onEntryDeleteFromGroup.");
-	    Log.v(TAG, "END onEntryDeleteFromGroup.");
 	}
 
 	/**
@@ -524,20 +460,17 @@
 	 */
 	@Override
 	public void onPresenceChanged(final PresenceAdapter presence) throws RemoteException {
-	    Log.v(TAG, "BEGIN onPresenceChanged.");
 	    if (mContact.getJID().equals(StringUtils.parseBareAddress(presence.getFrom()))) {
 		mHandler.post(new Runnable() {
 		    @Override
 		    public void run() {
 			mContact.setStatus(presence.getStatus());
 			mContact.setMsgState(presence.getStatusText());
-
 			updateContactInformations();
 			updateContactStatusIcon();
 		    }
 		});
 	    }
-	    Log.v(TAG, "END onPresenceChanged.");
 	}
     }
 
@@ -551,16 +484,11 @@
 	 */
 	@Override
 	public void processMessage(IChat chat, final Message msg) throws RemoteException {
-	    Log.v(TAG, "BEGIN processMessage.");
-
 	    final String fromBareJid = StringUtils.parseBareAddress(msg.getFrom());
 
 	    if (mContact.getJID().equals(fromBareJid)) {
 		mHandler.post(new Runnable() {
 
-		    /**
-		     * {@inheritDoc}.
-		     */
 		    @Override
 		    public void run() {
 			if (msg.getBody() != null && msg.getType() != Message.MSG_TYPE_ERROR) {
@@ -570,14 +498,13 @@
 			    if (lastMessage != null && lastMessage.getBareJid().equals(fromBareJid)) {
 				lastMessage.setMessage(lastMessage.getMessage().concat("\n" + msg.getBody()));
 				mListMessages.set(mListMessages.size() - 1, lastMessage);
-			    } else
+			    } else if (msg.getBody() != null)
 				mListMessages.add(new MessageText(fromBareJid, mContact.getName(), msg.getBody()));
 			    mMessagesListAdapter.notifyDataSetChanged();
 			}
 		    }
 		});
 	    }
-	    Log.v(TAG, "END processMessage.");
 	}
 
 	/**
@@ -585,38 +512,7 @@
 	 */
 	@Override
 	public void stateChanged(IChat chat) throws RemoteException {
-	    Log.v(TAG, "BEGIN stateChanged.");
-	    mHandler.post(new Runnable() {
-
-		/**
-		 * {@inheritDoc}.
-		 */
-		@Override
-		public void run() {
-		}
-	    });
-	    Log.v(TAG, "END stateChanged.");
-	}
-    }
-
-    /**
-     * This class serve to listen on ChatManager events.
-     * @author Jean-Manuel Da Silva <dasilvj at beem-project dot com>
-     */
-    private class OnChatManagerListener extends IChatManagerListener.Stub {
-	/**
-	 * Constructor.
-	 */
-	public OnChatManagerListener() {
-	    Log.v(TAG, "OnChatManagerListener constructor.");
-	}
-
-	/**
-	 * {@inheritDoc}.
-	 */
-	@Override
-	public void chatCreated(IChat chat, boolean locally) throws RemoteException {
-	    Log.i(TAG, "Chat has been created.");
+	    //TODO
 	}
     }
 
@@ -624,7 +520,6 @@
      * Update the contact informations.
      */
     private void updateContactInformations() {
-	Log.v(TAG, "BEGIN updateContactInformations.");
 	// Check for a contact name update
 	if (!(mContactNameTextView.getText().toString().equals(mContact.getName())))
 	    mContactNameTextView.setText(mContact.getName());
@@ -635,16 +530,13 @@
 	    mContactStatusMsgTextView.setText(mContact.getMsgState());
 	    Linkify.addLinks(mContactStatusMsgTextView, Linkify.WEB_URLS);
 	}
-	Log.v(TAG, "END updateContactInformations.");
     }
 
     /**
      * Update the contact status icon.
      */
     private void updateContactStatusIcon() {
-	Log.v(TAG, "BEGIN updateContactStatusIcon.");
 	mContactStatusIcon.setImageBitmap(mStatusIconsMap.get(mContact.getStatus()));
-	Log.v(TAG, "END updateContactStatusIcon.");
     }
 
     /**
@@ -670,14 +562,11 @@
      */
     private class MessagesListAdapter extends BaseAdapter {
 
-	private final Context mContext;
-
 	/**
 	 * Constructor.
 	 * @param context The MessagesListAdapter context.
 	 */
-	public MessagesListAdapter(final Context context) {
-	    mContext = context;
+	public MessagesListAdapter() {
 	}
 
 	/**
@@ -716,7 +605,7 @@
 	public View getView(int position, View convertView, ViewGroup parent) {
 	    MessageView sv;
 	    if (convertView == null) {
-		sv = new MessageView(mContext, mListMessages.get(position).getName(), mListMessages.get(position)
+		sv = new MessageView(Chat.this, mListMessages.get(position).getName(), mListMessages.get(position)
 		    .getMessage());
 	    } else {
 		sv = (MessageView) convertView;
@@ -724,6 +613,7 @@
 		sv.setMessage(mListMessages.get(position).getMessage());
 	    }
 
+	    //TODO Put this un the xml layout
 	    sv.setPadding(2, 2, 2, 4);
 
 	    sv.mName.setTextSize(16);
@@ -859,7 +749,6 @@
      */
     @Override
     public boolean onKey(View v, int keyCode, KeyEvent event) {
-	Log.d(TAG, "KeyEvent = " + event.getAction());
 	if (event.getAction() == KeyEvent.ACTION_DOWN) {
 	    switch (keyCode) {
 		case KeyEvent.KEYCODE_ENTER:
@@ -878,7 +767,6 @@
     private void sendMessage() {
 	final String inputContent = mInputField.getText().toString();
 
-	Log.v(TAG, "BEGIN sendMessage.");
 	if (!"".equals(inputContent)) {
 	    Message msgToSend = new Message(mContact.getJID(), Message.MSG_TYPE_CHAT);
 	    msgToSend.setBody(inputContent);
@@ -900,6 +788,9 @@
 	    mMessagesListAdapter.notifyDataSetChanged();
 	    mInputField.setText(null);
 	}
-	Log.v(TAG, "END sendMessage.");
+    }
+
+    protected void finalize() {
+	Log.e("CHATFIN", "FINALIZE");
     }
 }
--- a/src/com/beem/project/beem/ui/ContactList.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/ui/ContactList.java	Fri Dec 18 20:32:43 2009 +0100
@@ -120,7 +120,7 @@
     private IXmppFacade mXmppFacade;
     private SharedPreferences mSettings;
     private final ServiceConnection mServConn = new BeemServiceConnection();
-    private BeemBroadcastReceiver mReceiver;
+    private final BeemBroadcastReceiver mReceiver = new BeemBroadcastReceiver();
     private final Map<Integer, BitmapDrawable> mIconsMap = new HashMap<Integer, BitmapDrawable>();
     private LayoutInflater mInflater;
     private ComparatorContactListByStatusAndName<Contact> mComparator = new ComparatorContactListByStatusAndName<Contact>();
@@ -145,8 +145,6 @@
 	mAdapterBanner = new BeemBanner(this);
 	mHandler = new Handler();
 
-	bindService(SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
-	mReceiver = new BeemBroadcastReceiver(mServConn);
 	this.registerReceiver(mReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
 
 	mInflater = getLayoutInflater();
@@ -275,6 +273,8 @@
     @Override
     protected void onStart() {
 	super.onStart();
+	if (mXmppFacade == null)
+	    bindService(SERVICE_INTENT, mServConn, BIND_AUTO_CREATE);
     }
 
     /**
@@ -283,9 +283,8 @@
     @Override
     protected void onStop() {
 	super.onStop();
-	if (mReceiver.isBinded()) {
-	    mReceiver.setBinded(false);
-	}
+	unbindService(mServConn);
+	mXmppFacade = null;
     }
 
     /*
@@ -302,12 +301,7 @@
 	    Log.d("ContactList", "Remode exception", e);
 	}
 	this.unregisterReceiver(mReceiver);
-        unbindService(mServConn);
 	mRoster = null;
-	/*
-	for (BitmapDrawable d : mIconsMap.values()) {
-	    d.setCallback(null);
-	}*/
 	Log.e("CONTACTLIST", "onDestroy activity");
     }
 
@@ -770,7 +764,6 @@
 	@Override
 	public void onServiceConnected(ComponentName name, IBinder service) {
 	    mXmppFacade = IXmppFacade.Stub.asInterface(service);
-	    mReceiver.setBinded(true);
 	    try {
 		mRoster = mXmppFacade.getRoster();
 		if (mRoster != null) {
@@ -822,7 +815,6 @@
 	    mListContact.clear();
 	    mListGroup.clear();
 	    mContactOnGroup.clear();
-	    mReceiver.setBinded(false);
 	}
     }
 }
--- a/src/com/beem/project/beem/ui/GroupList.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/ui/GroupList.java	Fri Dec 18 20:32:43 2009 +0100
@@ -81,7 +81,7 @@
     private static final Intent SERVICE_INTENT = new Intent();
 
     private final ServiceConnection mServConn = new BeemServiceConnection();
-    private BeemBroadcastReceiver mReceiver;
+    private final BeemBroadcastReceiver mReceiver =  new BeemBroadcastReceiver();
     private IXmppFacade mXmppFacade;
     private IRoster mRoster;
     private String mJID;
@@ -107,7 +107,6 @@
     public void onCreate(Bundle savedInstanceState) {
 	super.onCreate(savedInstanceState);
 	setContentView(R.layout.group_list);
-	mReceiver = new BeemBroadcastReceiver(mServConn);
 	mContact = getIntent().getParcelableExtra("contact");
 	mJID = mContact.getJID();
 	final ListView listView = getListView();
@@ -128,7 +127,6 @@
     protected void onResume() {
 	super.onResume();
 	bindService(new Intent(this, BeemService.class), mServConn, BIND_AUTO_CREATE);
-	mReceiver.setBinded(true);
     }
 
     /**
@@ -137,10 +135,7 @@
     @Override
     protected void onPause() {
 	super.onPause();
-	if (mReceiver.isBinded()) {
-	    unbindService(mServConn);
-	    mReceiver.setBinded(false);
-	}
+	unbindService(mServConn);
     }
 
     /* (non-Javadoc)
@@ -251,7 +246,6 @@
 	@Override
 	public void onServiceConnected(ComponentName name, IBinder service) {
 	    mXmppFacade = IXmppFacade.Stub.asInterface(service);
-	    mReceiver.setBinded(true);
 	    try {
 		mRoster = mXmppFacade.getRoster();
 		setAdapter();
--- a/src/com/beem/project/beem/ui/PrivacyList.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/ui/PrivacyList.java	Fri Dec 18 20:32:43 2009 +0100
@@ -102,7 +102,7 @@
     private String mCurrPrivacyListName;
 
     private final ServiceConnection mConn = new BeemServiceConnection();
-    private BeemBroadcastReceiver mBroadcastReceiver;
+    private final BeemBroadcastReceiver mBroadcastReceiver = new BeemBroadcastReceiver();
 
     private IPrivacyListManager mPrivacyListManager;
     private IPrivacyListListener mPrivacyListListener;
@@ -148,7 +148,6 @@
 	bindService(SERVICE_INTENT, mConn, BIND_AUTO_CREATE);
 
 	mPrivacyListListener = new PrivacyListListener();
-	mBroadcastReceiver = new BeemBroadcastReceiver(mConn);
 	this.registerReceiver(mBroadcastReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
 
 	Log.d(TAG, "END onCreate.");
@@ -297,7 +296,6 @@
 	public void onServiceConnected(ComponentName name, IBinder service) {
 	    Log.v(TAG, "BEGIN onServiceConnected.");
 	    mXmppFacade = IXmppFacade.Stub.asInterface(service);
-	    mBroadcastReceiver.setBinded(true);
 	    try {
 		mPrivacyListManager = mXmppFacade.getPrivacyListManager();
 		mPrivacyListManager.addPrivacyListListener(mPrivacyListListener);
@@ -314,7 +312,6 @@
 	public void onServiceDisconnected(ComponentName name) {
 	    Log.v(TAG, "BEGIN onServiceDisconnected.");
 	    mXmppFacade = null;
-	    mBroadcastReceiver.setBinded(false);
 	    try {
 		mPrivacyListManager.removePrivacyListListener(mPrivacyListListener);
 	    } catch (RemoteException e) {
--- a/src/com/beem/project/beem/ui/Subscription.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/ui/Subscription.java	Fri Dec 18 20:32:43 2009 +0100
@@ -76,7 +76,7 @@
     private IXmppFacade mService;
     private String mContact;
     private ServiceConnection mServConn = new BeemServiceConnection();
-    private BeemBroadcastReceiver mReceiver;
+    private final BeemBroadcastReceiver mReceiver= new BeemBroadcastReceiver();
     private MyOnClickListener mClickListener = new MyOnClickListener();
 
     static {
@@ -96,7 +96,6 @@
     protected void onCreate(Bundle savedInstanceState) {
 	super.onCreate(savedInstanceState);
 	setContentView(R.layout.subscription);
-	mReceiver = new BeemBroadcastReceiver(mServConn);
 	findViewById(R.id.SubscriptionAccept).setOnClickListener(mClickListener);
 	findViewById(R.id.SubscriptionRefuse).setOnClickListener(mClickListener);
 	mContact = getIntent().getStringExtra("from");
@@ -113,7 +112,6 @@
     protected void onResume() {
 	super.onResume();
 	bindService(new Intent(this, BeemService.class), mServConn, BIND_AUTO_CREATE);
-	mReceiver.setBinded(true);
     }
 
     /* (non-Javadoc)
@@ -122,10 +120,7 @@
     @Override
     protected void onPause() {
 	super.onPause();
-	if (mReceiver.isBinded()) {
-	    unbindService(mServConn);
-	    mReceiver.setBinded(false);
-	}
+	unbindService(mServConn);
     }
 
     /* (non-Javadoc)
@@ -190,7 +185,6 @@
 	@Override
 	public void onServiceConnected(ComponentName name, IBinder service) {
 	    mService = IXmppFacade.Stub.asInterface(service);
-	    mReceiver.setBinded(true);
 	}
 
 	@Override
--- a/src/com/beem/project/beem/utils/BeemBroadcastReceiver.java	Thu Dec 17 16:15:02 2009 +0100
+++ b/src/com/beem/project/beem/utils/BeemBroadcastReceiver.java	Fri Dec 18 20:32:43 2009 +0100
@@ -60,16 +60,12 @@
 
     /** Broadcast intent type. */
     public static final String BEEM_CONNECTION_CLOSED = "BeemConnectionClosed";
-    private ServiceConnection mService;
-    private boolean mIsBinded;
 
     /**
      * constructor.
      * @param service service observed
      */
-    public BeemBroadcastReceiver(final ServiceConnection service) {
-	mService = service;
-	mIsBinded = false;
+    public BeemBroadcastReceiver() {
     }
 
     /**
@@ -78,9 +74,6 @@
     @Override
     public void onReceive(Context context, Intent intent) {
 	Log.d("Broadcast", "onReceive");
-	if (mIsBinded)
-	    context.unbindService(mService);
-	setBinded(false);
 	// TODO ce code est comment car il empeche de gerer un cancel sur une connexion
 	// start activity if unexpected disconnection
 	// if (!intent.getBooleanExtra("normally", false))
@@ -90,22 +83,7 @@
 	if (context instanceof Activity) {
 	    Activity act = (Activity) context;
 	    act.finish();
+	    // The service will be unbinded in the destroy of the activity.
 	}
     }
-
-    /**
-     * service is binded.
-     * @param binded the state of the bind.
-     */
-    public void setBinded(boolean binded) {
-	mIsBinded = binded;
-    }
-
-    /**
-     * return service bind status.
-     * @return service bind status.
-     */
-    public boolean isBinded() {
-	return mIsBinded;
-    }
 }