Login UI - new login UI to connect multi account
author"Vincent Veronis"
Mon, 13 Jun 2011 15:00:23 +0200
changeset 896 c2c6ee3d3c71
parent 895 e43d5abca8b0
child 897 07de7eb304b6
Login UI - new login UI to connect multi account
res/anim/rotate_and_scale.xml
res/layout/login_row_account.xml
res/values/strings.xml
src/com/beem/project/beem/BeemService.java
src/com/beem/project/beem/account/SyncAdapterService.java
src/com/beem/project/beem/service/LoginAsyncTask.java
src/com/beem/project/beem/ui/ContactList.java
src/com/beem/project/beem/ui/Login.java
--- a/res/anim/rotate_and_scale.xml	Fri Jun 10 21:04:07 2011 +0200
+++ b/res/anim/rotate_and_scale.xml	Mon Jun 13 15:00:23 2011 +0200
@@ -1,9 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
-
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-    <rotate android:fromDegrees="0" android:toDegrees="360"
-	android:pivotX="50%" android:pivotY="50%"
-	android:duration="5000"
-	android:repeatMode="restart"
-	android:repeatCount="infinite" />
-</set>
+<set
+	xmlns:android="http://schemas.android.com/apk/res/android">
+	<rotate
+		android:fromDegrees="0"
+		android:toDegrees="360"
+		android:pivotX="50%"
+		android:pivotY="50%"
+		android:duration="5000"
+		android:repeatMode="restart"
+		android:repeatCount="infinite" />
+</set>
\ No newline at end of file
--- a/res/layout/login_row_account.xml	Fri Jun 10 21:04:07 2011 +0200
+++ b/res/layout/login_row_account.xml	Mon Jun 13 15:00:23 2011 +0200
@@ -1,5 +1,45 @@
 <?xml version="1.0" encoding="utf-8"?>
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-	android:textColor="@color/white" android:textColorHighlight="@color/red"
-	android:textSize="25sp" android:typeface="normal" android:textStyle="bold"
-	android:gravity="center" android:id="@+id/accountname"></TextView>
\ No newline at end of file
+<RelativeLayout
+	xmlns:android="http://schemas.android.com/apk/res/android"
+	android:layout_width="fill_parent"
+	android:layout_height="wrap_content"
+	android:paddingLeft="10px"
+	android:paddingRight="10px"
+	android:paddingTop="8dip"
+	android:paddingBottom="8dip">
+	<ImageButton
+		android:id="@+id/loginanim_logo_anim"
+		android:layout_width="48dip"
+		android:layout_height="48dip"
+		android:layout_gravity="center_vertical|center_horizontal|center"
+		android:layout_weight="1"
+		android:background="@drawable/beem_launcher_icon_silver"
+		android:onClick="BeemConnectionOnClick" />
+	<TextView
+		android:id="@+id/accountname"
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:layout_alignParentTop="true"
+		android:layout_toRightOf="@id/loginanim_logo_anim"
+		android:singleLine="true"
+		android:maxLines="1"
+		android:textColor="@color/white"
+		android:drawablePadding="12px"
+		android:paddingLeft="10dip"
+		android:textSize="18sp"
+		android:textStyle="bold" />
+	<TextView
+		android:id="@+id/accountstatus"
+		android:layout_width="fill_parent"
+		android:layout_height="wrap_content"
+		android:layout_below="@+id/accountname"
+		android:layout_toRightOf="@id/loginanim_logo_anim"
+		android:paddingLeft="30px"
+		android:singleLine="true"
+		android:maxLines="1"
+		android:linksClickable="false"
+		android:autoLink="all"
+		android:scrollHorizontally="true"
+		android:textColorLink="@color/white"
+		android:textSize="12sp" />
+</RelativeLayout>
\ No newline at end of file
--- a/res/values/strings.xml	Fri Jun 10 21:04:07 2011 +0200
+++ b/res/values/strings.xml	Mon Jun 13 15:00:23 2011 +0200
@@ -184,6 +184,7 @@
 	<string name="login_menu_login">Login</string>
 	<string name="login_no_connectivity">No internet connection found</string>
 	<string name="login_start_msg">Settings configuration in menu</string>
+	<string name="login_pending">Pending ...</string>
 
 	<!-- LoginAnim activity -->
 	<string name="loganim_connecting">Connecting ...</string>
--- a/src/com/beem/project/beem/BeemService.java	Fri Jun 10 21:04:07 2011 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Mon Jun 13 15:00:23 2011 +0200
@@ -125,12 +125,12 @@
 	Log.d(TAG, "ONBIND()");
 	String accountName = intent.getStringExtra("account_name");
 	Log.e(TAG, accountName);
-	try {
-	    for (XmppConnectionAdapter connection : mConnection.values())
-		connection.connect();
-	} catch (RemoteException e) {
-	    Log.w(TAG, "Error while connecting", e);
-	}
+//	try {
+//	    for (XmppConnectionAdapter connection : mConnection.values())
+//		connection.connect();
+//	} catch (RemoteException e) {
+//	    Log.w(TAG, "Error while connecting", e);
+//	}
 	return (IBinder) mBind.get(accountName);
     }
 
@@ -204,12 +204,16 @@
     public void onStart(Intent intent, int startId) {
 	super.onStart(intent, startId);
 	Log.d(TAG, "onStart");
-	try {
-	    for (XmppConnectionAdapter connection : mConnection.values())
-		connection.connectAsync();
-	} catch (RemoteException e) {
-	    e.printStackTrace();
-	}
+//	try {
+//	    for (XmppConnectionAdapter connection : mConnection.values())
+//		connection.connectAsync();
+//	} catch (RemoteException e) {
+//	    e.printStackTrace();
+//	}
+    }
+    
+    public XmppConnectionAdapter getConnection(String accountName) {
+	return mConnection.get(accountName);
     }
 
     /**
--- a/src/com/beem/project/beem/account/SyncAdapterService.java	Fri Jun 10 21:04:07 2011 +0200
+++ b/src/com/beem/project/beem/account/SyncAdapterService.java	Mon Jun 13 15:00:23 2011 +0200
@@ -44,6 +44,7 @@
 
 package com.beem.project.beem.account;
 
+import java.io.IOException;
 import java.util.ArrayList;
 
 import org.jivesoftware.smack.Roster;
@@ -75,6 +76,7 @@
 
 import com.beem.project.beem.BeemConnection;
 import com.beem.project.beem.R;
+import com.beem.project.beem.service.BeemAvatarCache;
 import com.beem.project.beem.utils.Status;
 
 /**
@@ -247,6 +249,9 @@
 	} else { // Found, update	   
 	    ContentProviderOperation.Builder builder = addUpdateStructuredName(entry, rawContactID, false);
 	    ops.add(builder.build());
+	    //TODO: ADD AVATAR
+	    //builder = addUpdatePhoto(entry, rawContactID, false);
+	    //ops.add(builder.build());
 	}
 	return rawContactID;
     }
@@ -280,7 +285,42 @@
 	builder.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, displayName);
 	return builder;
     }
+    
+    private static ContentProviderOperation.Builder addUpdatePhoto(RosterEntry entry, long rawContactID,
+	boolean isInsert) {
+	String displayName = entry.getName() != null ? entry.getName() : entry.getUser();
+	ContentProviderOperation.Builder builder;
+	if (isInsert) {
+	    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
+	    builder.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID);
+	    builder.withValue(ContactsContract.Data.MIMETYPE,
+		ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE);
+	    builder.withValue(ContactsContract.CommonDataKinds.Photo.RAW_CONTACT_ID, rawContactID);
+	} else {
+	    builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
+	    builder.withSelection(
+		ContactsContract.CommonDataKinds.Photo.RAW_CONTACT_ID + " =? AND "
+		    + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
+		    + "'", new String[] { String.valueOf(rawContactID) });
+	}
+	BeemAvatarCache bac = new BeemAvatarCache(mContext);
+	try {
+	    builder.withValue(ContactsContract.CommonDataKinds.Photo.PHOTO , bac.get(entry.getUser()));
+	} catch (IOException e) {
+	    Log.e(TAG, "Error cache beem avatar", e);
+	}
+	return builder;
+    }
 
+
+    /**
+     * Method to insert or update group name informations.
+     * @param entry The roster entry to sync
+     * @param rawContactID The contact ID in the android database
+     * @param rawGroupID The group ID in the android database
+     * @param isInsert Insert boolean
+     * @return
+     */
     private static ContentProviderOperation.Builder addUpdateGroup(RosterEntry entry, long rawContactID,
 	long rawGroupID, boolean isInsert) {
 	String displayName = entry.getName() != null ? entry.getName() : entry.getUser();
@@ -367,6 +407,12 @@
 	return authorId;
     }
 
+    /**
+     * Get group ID from android database.
+     * @param account The account related
+     * @param group The group related
+     * @return ID in the database of the jid
+     */
     private static long getRawGroupID(String account, String group) {
 	long authorId = -1;
 	final Cursor c = mContentResolver.query(ContactsContract.Groups.CONTENT_URI,
--- a/src/com/beem/project/beem/service/LoginAsyncTask.java	Fri Jun 10 21:04:07 2011 +0200
+++ b/src/com/beem/project/beem/service/LoginAsyncTask.java	Mon Jun 13 15:00:23 2011 +0200
@@ -43,9 +43,11 @@
 */
 package com.beem.project.beem.service;
 
+import android.content.Context;
 import android.os.AsyncTask;
 import android.os.RemoteException;
 import android.util.Log;
+
 import com.beem.project.beem.service.aidl.IXmppConnection;
 import com.beem.project.beem.service.aidl.IXmppFacade;
 
@@ -77,7 +79,7 @@
 
     private IXmppConnection mConnection;
     private String mErrorMessage;
-
+    
     /**
      * Constructor.
      */
@@ -93,6 +95,7 @@
 	    mConnection = facade.createConnection();
 	    if (!mConnection.connect()) {
 		mErrorMessage = mConnection.getErrorMessage();
+		publishProgress(STATE_LOGIN_FAILED);
 		return false;
 	    }
 	    publishProgress(STATE_LOGIN_RUNNING);
--- a/src/com/beem/project/beem/ui/ContactList.java	Fri Jun 10 21:04:07 2011 +0200
+++ b/src/com/beem/project/beem/ui/ContactList.java	Mon Jun 13 15:00:23 2011 +0200
@@ -42,32 +42,21 @@
  */
 package com.beem.project.beem.ui;
 
-import java.io.IOException;
-import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
-import org.jivesoftware.smack.util.StringUtils;
-
 import android.app.Activity;
 import android.app.Dialog;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
 import android.content.SharedPreferences;
 import android.database.Cursor;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.LayerDrawable;
-import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.IBinder;
 import android.os.RemoteException;
 import android.preference.PreferenceManager;
 import android.provider.ContactsContract;
@@ -81,12 +70,8 @@
 import android.view.ViewGroup;
 import android.view.ViewStub;
 import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.CursorAdapter;
-import android.widget.Filter;
 import android.widget.Filterable;
 import android.widget.Gallery;
-import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.ListView;
 import android.widget.SimpleCursorAdapter;
@@ -95,10 +80,7 @@
 import android.widget.AdapterView.OnItemClickListener;
 
 import com.beem.project.beem.R;
-import com.beem.project.beem.providers.AvatarProvider;
 import com.beem.project.beem.service.Contact;
-import com.beem.project.beem.service.PresenceAdapter;
-import com.beem.project.beem.service.aidl.IBeemRosterListener;
 import com.beem.project.beem.service.aidl.IChatManager;
 import com.beem.project.beem.service.aidl.IRoster;
 import com.beem.project.beem.service.aidl.IXmppFacade;
@@ -107,8 +89,6 @@
 import com.beem.project.beem.ui.dialogs.builders.DeleteContact;
 import com.beem.project.beem.ui.dialogs.builders.ResendSubscription;
 import com.beem.project.beem.utils.BeemBroadcastReceiver;
-import com.beem.project.beem.utils.SortedList;
-import com.beem.project.beem.utils.Status;
 
 /**
  * The contact list activity displays the roster of the user.
@@ -122,19 +102,15 @@
 
     private static final String SETTINGS_HIDDEN_CONTACT = "settings_key_hidden_contact";
     private static final String TAG = "ContactList";
-    private final List<String> mListGroup = new ArrayList<String>();
 
     /**
      * Map containing a list of the different contacts of a given group. Each list is a @{link SortedList} so there is
      * no need to sort it again.
      */
-    private final Map<String, List<Contact>> mContactOnGroup = new HashMap<String, List<Contact>>();
+
     private final BeemContactListOnClick mOnContactClick = new BeemContactListOnClick();
-    private final Handler mHandler = new Handler();
-    private final ServiceConnection mServConn = new BeemServiceConnection();
-    private final BeemBroadcastReceiver mReceiver = new BeemBroadcastReceiver();
+
     private final ComparatorContactListByStatusAndName<Contact> mComparator = new ComparatorContactListByStatusAndName<Contact>();
-    private final BeemRosterListener mBeemRosterListener = new BeemRosterListener();
     private List<Contact> mListContact;
     private String mSelectedGroup;
     private IRoster mRoster;
@@ -155,11 +131,47 @@
     public ContactList() {
     }
 
-    /**
-     * Callback for menu creation.
-     * @param menu the menu created
-     * @return true on success, false otherwise
-     */
+    @Override
+    protected void onCreate(Bundle saveBundle) {
+	super.onCreate(saveBundle);
+	mSettings = PreferenceManager.getDefaultSharedPreferences(this);
+	setContentView(R.layout.contactlist);
+
+	mInflater = getLayoutInflater();
+
+	//Get Groups list 
+	final Cursor cursorGroup = getContentResolver().query(ContactsContract.Groups.CONTENT_URI,
+	    new String[] { ContactsContract.Groups._ID, ContactsContract.Groups.TITLE }, null, null, null);
+	mAdapterBanner = new BeemBanner(this, R.layout.contactlist_group, cursorGroup,
+	    new String[] { ContactsContract.Groups.TITLE }, new int[] { R.id.contactlist_group });
+
+	//Get Contacts list
+	final Cursor cursorContact = getContentResolver().query(
+	    ContactsContract.Contacts.CONTENT_URI,
+	    new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME,
+		ContactsContract.Contacts.CONTACT_STATUS }, null, null, null);
+	//TODO: GetAvatar + Presence
+	mAdapterContactList = new BeemContactList(this, R.layout.contactlistcontact, cursorContact, new String[] {
+	    ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME,
+	    ContactsContract.Contacts.CONTACT_STATUS }, new int[] { R.id.avatar, R.id.contactlistpseudo,
+	    R.id.contactlistmsgperso });
+
+	ListView listView = (ListView) findViewById(R.id.contactlist);
+	listView.setOnItemClickListener(mOnContactClick);
+	registerForContextMenu(listView);
+	listView.setAdapter(mAdapterContactList);
+	Log.e(TAG, "ONCREATE");
+    }
+
+    @Override
+    protected void onResume() {
+	super.onResume();
+	if (!mSettings.getBoolean("settings_key_hide_groups", false))
+	    showGroups();
+	else
+	    hideGroups();
+    }
+
     @Override
     public final boolean onCreateOptionsMenu(Menu menu) {
 	super.onCreateOptionsMenu(menu);
@@ -282,86 +294,12 @@
 	return super.onContextItemSelected(item);
     }
 
-    @Override
-    protected void onCreate(Bundle saveBundle) {
-	super.onCreate(saveBundle);
-	mSettings = PreferenceManager.getDefaultSharedPreferences(this);
-	setContentView(R.layout.contactlist);
-
-	this.registerReceiver(mReceiver, new IntentFilter(BeemBroadcastReceiver.BEEM_CONNECTION_CLOSED));
-
-	mInflater = getLayoutInflater();
-
-	final Cursor cursorGroup = getContentResolver().query(ContactsContract.Groups.CONTENT_URI,
-	    new String[] { ContactsContract.Groups._ID, ContactsContract.Groups.TITLE }, null, null, null);
-	mAdapterBanner = new BeemBanner(this, R.layout.contactlist_group, cursorGroup,
-	    new String[] { ContactsContract.Groups.TITLE }, new int[] { R.id.contactlist_group });
-
-	final Cursor cursorContact = getContentResolver().query(
-	    ContactsContract.Contacts.CONTENT_URI,
-	    new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME}, null, null, null);
-	mAdapterContactList = new BeemContactList(this, R.layout.contactlistcontact, cursorContact, new String[] {
-	    ContactsContract.Contacts.DISPLAY_NAME}, new int[] { R.id.avatar,
-	    R.id.contactlistpseudo, R.id.contactlistmsgperso });
-
-	mListContact = new ArrayList<Contact>();
-	ListView listView = (ListView) findViewById(R.id.contactlist);
-	listView.setOnItemClickListener(mOnContactClick);
-	registerForContextMenu(listView);
-	listView.setAdapter(mAdapterContactList);
-	Log.e(TAG, "ONCREATE");
-    }
-
-    @Override
-    protected void onResume() {
-	super.onResume();
-	if (!mBinded) {
-	    Log.e(TAG, "ON RESUME");
-	    Intent i = new Intent(SERVICE_INTENT);
-	    i.putExtras(getIntent());
-	    mAccountName = i.getStringExtra("account_name");
-	    Log.e(TAG, i.getStringExtra("account_name"));
-	    mBinded = bindService(i, mServConn, BIND_AUTO_CREATE);
-	}
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    protected void onPause() {
-	super.onPause();
-	try {
-	    if (mRoster != null) {
-		mRoster.removeRosterListener(mBeemRosterListener);
-		mRoster = null;
-	    }
-	} catch (RemoteException e) {
-	    Log.d("ContactList", "Remote exception", e);
-	}
-	if (mBinded) {
-	    unbindService(mServConn);
-	    mBinded = false;
-	}
-	mXmppFacade = null;
-    }
-
-    @Override
-    protected void onDestroy() {
-	super.onDestroy();
-	this.unregisterReceiver(mReceiver);
-	Log.e(TAG, "onDestroy activity");
-    }
-
     /**
      * Build and display the contact list.
      * @param group name of the contact list.
      */
     private void buildContactList(String group) {
-	mListContact = mContactOnGroup.get(group);
-	mSelectedGroup = group;
-	Log.d(TAG, "buildContactList for group " + group);
-	mAdapterContactList.notifyDataSetChanged();
+
     }
 
     /**
@@ -393,217 +331,6 @@
     }
 
     /**
-     * Listener on service event.
-     */
-    private class BeemRosterListener extends IBeemRosterListener.Stub {
-	/**
-	 * Constructor.
-	 */
-	public BeemRosterListener() {
-	}
-
-	/**
-	 * {@inheritDoc} Simple stategy to handle the onEntriesAdded event. if contact has to be shown :
-	 * <ul>
-	 * <li>add him to his groups</li>
-	 * <li>add him to the specials groups</>
-	 * </ul>
-	 */
-	@Override
-	public void onEntriesAdded(final List<String> addresses) throws RemoteException {
-	    final boolean hideDisconnected = mSettings.getBoolean(SETTINGS_HIDDEN_CONTACT, false);
-	    for (String newName : addresses) {
-		Contact contact = mRoster.getContact(newName);
-		boolean visible = !hideDisconnected || Status.statusOnline(contact.getStatus());
-		List<String> groups = contact.getGroups();
-		if (visible) {
-		    for (String group : groups) {
-			if (!mListGroup.contains(group)) {
-			    mListGroup.add(mListGroup.size() - 1, group);
-			    List<Contact> tmplist = new SortedList<Contact>(new LinkedList<Contact>(), mComparator);
-			    mContactOnGroup.put(group, tmplist);
-			}
-			List<Contact> contactByGroups = mContactOnGroup.get(group);
-			if (mSelectedGroup.equals(group)) {
-			    updateCurrentList(group, contact);
-			    continue;
-			}
-			contactByGroups.add(contact);
-		    }
-
-		    // add the contact to all and no groups
-		    addToSpecialList(contact);
-		}
-	    }
-	}
-
-	/**
-	 * {@inheritDoc} Simple stategy to handle the onEntriesDeleted event.
-	 * <ul>
-	 * <li>Remove the contact from all groups</li>
-	 * </ul>
-	 */
-	@Override
-	public void onEntriesDeleted(final List<String> addresses) throws RemoteException {
-	    Log.d(TAG, "onEntries deleted " + addresses);
-	    for (String cToDelete : addresses) {
-		Contact contact = new Contact(cToDelete);
-		for (Map.Entry<String, List<Contact>> entry : mContactOnGroup.entrySet()) {
-		    List<Contact> contactByGroups = entry.getValue();
-		    if (mSelectedGroup.equals(entry.getKey())) {
-			updateCurrentList(entry.getKey(), contact);
-			continue;
-		    }
-		    contactByGroups.remove(contact);
-		}
-		cleanBannerGroup();
-	    }
-
-	    mHandler.post(new Runnable() {
-		public void run() {
-		    mSelectedGroup = getString(R.string.contact_list_all_contact);
-		    mListContact = mContactOnGroup.get(mSelectedGroup);
-
-		    mAdapterContactList.notifyDataSetChanged();
-		}
-	    });
-
-	}
-
-	/**
-	 * {@inheritDoc} Simple stategy to handle the onEntriesUpdated event.
-	 * <ul>
-	 * <li>Remove the contact from all groups</li>
-	 * <li>if contact has to be shown add it to his groups</li>
-	 * <li>if contact has to be shown add it to the specials groups</li>
-	 * </ul>
-	 */
-	@Override
-	public void onEntriesUpdated(final List<String> addresses) throws RemoteException {
-	    final boolean hideDisconnected = mSettings.getBoolean(SETTINGS_HIDDEN_CONTACT, false);
-	    for (String adr : addresses) {
-		Contact contact = mRoster.getContact(adr);
-		boolean visible = !hideDisconnected || Status.statusOnline(contact.getStatus());
-		List<String> groups = contact.getGroups();
-		for (Map.Entry<String, List<Contact>> entry : mContactOnGroup.entrySet()) {
-		    List<Contact> contactByGroups = entry.getValue();
-		    if (mSelectedGroup.equals(entry.getKey())) {
-			updateCurrentList(entry.getKey(), contact);
-			continue;
-		    }
-		    contactByGroups.remove(contact);
-		    if (visible) {
-			for (String group : groups) {
-			    if (!mListGroup.contains(group)) {
-				mListGroup.add(mListGroup.size() - 1, group);
-				List<Contact> tmplist = new SortedList<Contact>(new LinkedList<Contact>(), mComparator);
-				mContactOnGroup.put(group, tmplist);
-			    }
-			    mContactOnGroup.get(group).remove(contact);
-			}
-		    }
-
-		}
-
-		// add the contact to all and no groups
-		if (visible) {
-		    addToSpecialList(contact);
-		}
-	    }
-	    cleanBannerGroup();
-	}
-
-	/**
-	 * {@inheritDoc} Simple stategy to handle the onPresenceChanged event.
-	 * <ul>
-	 * <li>Remove the contact from all groups</li>
-	 * <li>if contact has to be shown add it to his groups</li>
-	 * <li>if contact has to be shown add it to the specials groups</li>
-	 * </ul>
-	 */
-	@Override
-	public void onPresenceChanged(PresenceAdapter presence) throws RemoteException {
-	    Log.d(TAG, "presence");
-	    String from = presence.getFrom();
-	    final boolean hideDisconnected = mSettings.getBoolean(SETTINGS_HIDDEN_CONTACT, false);
-	    final Contact contact = mRoster.getContact(StringUtils.parseBareAddress(from));
-	    boolean visible = !hideDisconnected || Status.statusOnline(contact.getStatus());
-	    List<String> groups = contact.getGroups();
-	    for (Map.Entry<String, List<Contact>> entry : mContactOnGroup.entrySet()) {
-		List<Contact> contactByGroups = entry.getValue();
-		if (mSelectedGroup.equals(entry.getKey())) {
-		    updateCurrentList(entry.getKey(), contact);
-		    continue;
-		}
-		contactByGroups.remove(contact);
-		if (visible) {
-		    if (groups.contains(entry.getKey())) {
-			contactByGroups.add(contact);
-		    }
-		}
-	    }
-	    if (visible) {
-		addToSpecialList(contact);
-	    }
-	}
-
-	/**
-	 * Add a contact to the special list No Group and All contacts. The contact will be added if the list is not the
-	 * current list otherwise the list must be modified in a Handler.
-	 * @param contact the contact to add.
-	 */
-	private void addToSpecialList(Contact contact) {
-	    List<String> groups = contact.getGroups();
-	    List<Contact> list = mContactOnGroup.get(getString(R.string.contact_list_all_contact));
-	    if (list != mListContact) {
-		list.add(contact);
-	    }
-	    list = mContactOnGroup.get(getString(R.string.contact_list_no_group));
-	    if (list != mListContact && groups.isEmpty()) {
-		list.add(contact);
-	    }
-	}
-
-	/**
-	 * Update the current list with the status of contact.
-	 * @param listName name of the current list
-	 * @param contact contact to update
-	 */
-	private void updateCurrentList(String listName, final Contact contact) {
-	    final boolean hideDisconnected = mSettings.getBoolean(SETTINGS_HIDDEN_CONTACT, false);
-	    final List<String> groups = contact.getGroups();
-	    String noGroup = getString(R.string.contact_list_no_group);
-	    String allGroup = getString(R.string.contact_list_all_contact);
-	    final boolean add = ((!hideDisconnected || Status.statusOnline(contact.getStatus())) && // must show and
-	    ((listName.equals(noGroup) && groups.isEmpty()) || // in no group
-		groups.contains(listName) || // or in current
-	    listName.equals(allGroup) // or in all
-	    ));
-	    mHandler.post(new Runnable() {
-		public void run() {
-		    mListContact.remove(contact);
-		    if (add) {
-			mListContact.add(contact);
-		    }
-		    mAdapterContactList.notifyDataSetChanged();
-		}
-	    });
-
-	}
-
-	/**
-	 * Remove old groups on the banner.
-	 * @throws RemoteException if an error occur when communicating with the service
-	 */
-	private void cleanBannerGroup() throws RemoteException {
-	    List<String> rosterGroups = mRoster.getGroupsNames();
-	    List<String> realGroups = mListGroup.subList(1, mListContact.size() - 1);
-	    realGroups.retainAll(rosterGroups);
-	}
-
-    }
-
-    /**
      * Adapter contact list.
      */
     private static class BeemContactList extends SimpleCursorAdapter implements Filterable {
@@ -619,25 +346,8 @@
 
 	@Override
 	public View newView(Context context, Cursor cursor, ViewGroup parent) {
-	    Cursor c = getCursor();
-
 	    final LayoutInflater inflater = LayoutInflater.from(mContext);
-	    View v = inflater.inflate(mLayout, parent, false);
-	    String name = c.getString(c.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
-
-	    TextView nameText = (TextView) v.findViewById(R.id.contactlistpseudo);
-	    if (nameText != null) {
-		nameText.setText(name);
-	    }
-
-//	    String msgStatus = c.getString(c.getColumnIndex(ContactsContract.StatusUpdates.STATUS));
-//
-//	    TextView msgStatusText = (TextView) v.findViewById(R.id.contactlistmsgperso);
-//	    if (msgStatusText != null) {
-//		msgStatusText.setText(msgStatus);
-//	    }
-
-	    return v;
+	    return inflater.inflate(mLayout, parent, false);
 	}
 
 	@Override
@@ -648,56 +358,25 @@
 		nameText.setText(name);
 	    }
 
-//	    String msgStatus = cursor.getString(cursor.getColumnIndex(ContactsContract.StatusUpdates.STATUS));
-//
-//	    TextView msgStatusText = (TextView) view.findViewById(R.id.contactlistmsgperso);
-//	    if (msgStatusText != null) {
-//		msgStatusText.setText(msgStatus);
-//	    }
-	}
+	    String msgStatus = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.CONTACT_STATUS));
+	    TextView msgStatusText = (TextView) view.findViewById(R.id.contactlistmsgperso);
+	    if (msgStatusText != null) {
+		msgStatusText.setText(msgStatus);
+	    }
 
-	//	public View getView(int position, View convertView, ViewGroup parent) {
-	//	    View v = convertView;
-	//	    if (convertView == null) {
-	//		v = mInflater.inflate(R.layout.contactlistcontact, null);
-	//	    }
-	//	    Contact c = mListContact.get(position);
-	//	    if (mRoster != null) {
-	//		try {
-	//		    c = mRoster.getContact(c.getJID());
-	//		} catch (RemoteException e) {
-	//		    e.printStackTrace();
-	//		}
-	//	    }
-	//	    bindView(v, c);
-	//	    return v;
-	//	}
+	    //		ImageView img = (ImageView) view.findViewById(R.id.avatar);
+	    //		String avatarId = curContact.getAvatarId();
+	    //		int contactStatus = curContact.getStatus();
+	    //		Drawable avatar = getAvatarStatusDrawable(avatarId);
+	    //		img.setImageDrawable(avatar);
+	    //		img.setImageLevel(contactStatus);
+	}
 
 	//	@Override
 	//	public Filter getFilter() {
 	//	    return mFilter;
 	//	}
 
-	//	/**
-	//	 * Adapte curContact to the view.
-	//	 * @param view the row view.
-	//	 * @param curContact the current contact.
-	//	 */
-	//	private void bindView(View view, Contact curContact) {
-	//	    if (curContact != null) {
-	//		TextView v = (TextView) view.findViewById(R.id.contactlistpseudo);
-	//		v.setText(curContact.getName());
-	//		v = (TextView) view.findViewById(R.id.contactlistmsgperso);
-	//		v.setText(curContact.getMsgState());
-	//		ImageView img = (ImageView) view.findViewById(R.id.avatar);
-	//		String avatarId = curContact.getAvatarId();
-	//		int contactStatus = curContact.getStatus();
-	//		Drawable avatar = getAvatarStatusDrawable(avatarId);
-	//		img.setImageDrawable(avatar);
-	//		img.setImageLevel(contactStatus);
-	//	    }
-	//	}
-
 	/**
 	 * Get a LayerDrawable containing the avatar and the status icon. The status icon will change with the level of
 	 * the drawable.
@@ -768,7 +447,7 @@
     }
 
     /**
-     * Adapter banner list.
+     * Adapter banner group list.
      */
     private static class BeemBanner extends SimpleCursorAdapter {
 
@@ -783,18 +462,8 @@
 
 	@Override
 	public View newView(Context context, Cursor cursor, ViewGroup parent) {
-	    Cursor c = getCursor();
-
 	    final LayoutInflater inflater = LayoutInflater.from(mContext);
-	    View v = inflater.inflate(mLayout, parent, false);
-	    String name = c.getString(c.getColumnIndex(ContactsContract.Groups.TITLE));
-
-	    TextView nameText = (TextView) v.findViewById(R.id.GroupListText);
-	    if (nameText != null) {
-		nameText.setText(name);
-	    }
-
-	    return v;
+	    return inflater.inflate(mLayout, parent, false);
 	}
 
 	@Override
@@ -808,112 +477,6 @@
     }
 
     /**
-     * The service connection used to connect to the Beem service.
-     */
-    private class BeemServiceConnection implements ServiceConnection {
-
-	/**
-	 * Constructor.
-	 */
-	public BeemServiceConnection() {
-	}
-
-	@Override
-	public void onServiceConnected(ComponentName name, IBinder service) {
-	    mXmppFacade = IXmppFacade.Stub.asInterface(service);
-	    try {
-		mRoster = mXmppFacade.getRoster();
-		//if (mRoster != null) {
-		//
-		//		    List<String> tmpGroupList = mRoster.getGroupsNames();
-		//		    for (String string : tmpGroupList) {
-		//			Log.e(TAG, string);
-		//		    }
-		//		    Collections.sort(tmpGroupList);
-		//		    mListGroup.clear();
-		//		    mListGroup.add(getString(R.string.contact_list_all_contact));
-		//		    mListGroup.addAll(tmpGroupList);
-		//		    mListGroup.add(getString(R.string.contact_list_no_group));
-		//		    assignContactToGroups(mRoster.getContactList(), tmpGroupList);
-		//		    makeSortedList(mContactOnGroup);
-		//		    if (!mSettings.getBoolean("settings_key_hide_groups", false))
-		showGroups();
-		//		    else
-		//			hideGroups();
-		//		    String group = getString(R.string.contact_list_all_contact);
-		//		    buildContactList(group);
-		//		    mRoster.addRosterListener(mBeemRosterListener);
-		//		    Log.d(TAG, "add roster listener");
-		//		    mChatManager = mXmppFacade.getChatManager();
-		//}
-	    } catch (RemoteException e) {
-		e.printStackTrace();
-	    }
-	}
-
-	@Override
-	public void onServiceDisconnected(ComponentName name) {
-	    Log.e(TAG, "SERVICE DISCO");
-	    try {
-		mRoster.removeRosterListener(mBeemRosterListener);
-	    } catch (RemoteException e) {
-		e.printStackTrace();
-	    }
-	    mXmppFacade = null;
-	    mChatManager = null;
-	    mRoster = null;
-	    mListContact.clear();
-	    mListGroup.clear();
-	    mContactOnGroup.clear();
-	    mBinded = false;
-	}
-
-	/**
-	 * Assign the differents contact to their groups. This methods will fill the mContactOnGroup map.
-	 * @param contacts list of contacts
-	 * @param groupNames list of existing groups
-	 */
-	private void assignContactToGroups(List<Contact> contacts, List<String> groupNames) {
-	    boolean hideDisconnected = mSettings.getBoolean(SETTINGS_HIDDEN_CONTACT, false);
-	    mContactOnGroup.clear();
-	    List<Contact> all = new LinkedList<Contact>();
-	    List<Contact> noGroups = new LinkedList<Contact>();
-	    for (String group : groupNames) {
-		mContactOnGroup.put(group, new LinkedList<Contact>());
-	    }
-	    for (Contact c : contacts) {
-		if (hideDisconnected && !Status.statusOnline(c.getStatus())) {
-		    continue;
-		}
-		all.add(c);
-		List<String> groups = c.getGroups();
-		if (groups.isEmpty())
-		    noGroups.add(c);
-		else {
-		    for (String currentGroup : groups) {
-			List<Contact> contactsByGroups = mContactOnGroup.get(currentGroup);
-			contactsByGroups.add(c);
-		    }
-		}
-	    }
-	    mContactOnGroup.put(getString(R.string.contact_list_no_group), noGroups);
-	    mContactOnGroup.put(getString(R.string.contact_list_all_contact), all);
-	}
-
-	/**
-	 * Make the List of the map became Insertion sorted list.
-	 * @param map the map to convert.
-	 */
-	private void makeSortedList(Map<String, List<Contact>> map) {
-	    for (Map.Entry<String, List<Contact>> entry : map.entrySet()) {
-		List<Contact> l = entry.getValue();
-		Log.e(TAG, "SORTED LIST" + entry.getValue());
-		entry.setValue(new SortedList<Contact>(l, mComparator));
-	    }
-	}
-    }
-
-    /**
      * Comparator Contact by status and name.
      */
     private static class ComparatorContactListByStatusAndName<T> implements Comparator<T> {
@@ -957,7 +520,7 @@
     }
 
     /**
-     * Event simple click on middle groupe name.
+     * Event simple click on middle group name.
      */
     private class OnItemClickGroupName implements OnItemClickListener {
 
--- a/src/com/beem/project/beem/ui/Login.java	Fri Jun 10 21:04:07 2011 +0200
+++ b/src/com/beem/project/beem/ui/Login.java	Mon Jun 13 15:00:23 2011 +0200
@@ -50,12 +50,15 @@
 import android.accounts.AccountManager;
 import android.app.Activity;
 import android.app.AlertDialog;
-import android.app.Application;
+import android.content.ComponentName;
 import android.content.DialogInterface;
 import android.content.Intent;
+import android.content.ServiceConnection;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.os.AsyncTask;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.Menu;
@@ -63,15 +66,19 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.animation.Animation;
+import android.view.animation.AnimationUtils;
 import android.widget.AdapterView;
 import android.widget.BaseAdapter;
+import android.widget.ImageButton;
 import android.widget.ListView;
 import android.widget.TextView;
-import android.widget.Toast;
 import android.widget.AdapterView.OnItemClickListener;
 
 import com.beem.project.beem.BeemApplication;
 import com.beem.project.beem.R;
+import com.beem.project.beem.service.LoginAsyncTask;
+import com.beem.project.beem.service.aidl.IXmppFacade;
 
 /**
  * This class is the main Activity for the Beem project.
@@ -79,10 +86,18 @@
  */
 public class Login extends Activity {
 
+    private static final Intent SERVICE_INTENT = new Intent();
+    static {
+	SERVICE_INTENT.setComponent(new ComponentName("com.beem.project.beem", "com.beem.project.beem.BeemService"));
+    }
     private static final int LOGIN_REQUEST_CODE = 1;
     private TextView mTextView;
     private BeemApplication mBeemApplication;
     private String mAccountName;
+    private final ServiceConnection mServConn = new LoginServiceConnection();
+    private IXmppFacade mXmppFacade;
+    private AsyncTask<IXmppFacade, Integer, Boolean> mTask;
+    private Animation mAnimationLogo;
 
     List<String> mListAccount = new ArrayList<String>();
     private BeemAccountList mAdapterAccountList;
@@ -97,23 +112,17 @@
     @Override
     protected void onCreate(Bundle savedInstanceState) {
 	super.onCreate(savedInstanceState);
-//	Application app = getApplication();
-//	if (app instanceof BeemApplication) {
-//	    mBeemApplication = (BeemApplication) app;
-//	    if (mBeemApplication.isConnected()) {
-//		startActivity(new Intent(this, ContactList.class));
-//		finish();
-//	    } else if (!mBeemApplication.isAccountConfigured()) {
-//		startActivity(new Intent(this, Account.class));
-//		finish();
-//	    }
-//	}
+
 	setContentView(R.layout.login);
 	mTextView = (TextView) findViewById(R.id.log_as_msg);
 	ListView listView = (ListView) findViewById(R.id.accountlist);
 	mAdapterAccountList = new BeemAccountList(getLayoutInflater());
+	listView.setClickable(true);
 	listView.setOnItemClickListener(mOnAccountClick);
 	listView.setAdapter(mAdapterAccountList);
+	mAnimationLogo = AnimationUtils.loadAnimation(Login.this, R.anim.rotate_and_scale);
+	Intent i = new Intent(Login.SERVICE_INTENT);
+	startService(i);
     }
 
     @Override
@@ -123,31 +132,18 @@
     }
 
     @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-	if (requestCode == LOGIN_REQUEST_CODE) {
-	    if (resultCode == Activity.RESULT_OK) {		
-		Intent i = new Intent(this, ContactList.class);
-		Log.e("LOGIN", "ACCOUNT NAME : " + mAccountName);
-		i.putExtra("account_name", mAccountName);
-		startActivity(i);
-		finish();
-	    } else if (resultCode == Activity.RESULT_CANCELED) {
-		if (data != null) {
-		    String tmp = data.getExtras().getString("message");
-		    Toast.makeText(Login.this, tmp, Toast.LENGTH_SHORT).show();
-		    mTextView.setText(tmp);
-		}
-	    }
-	}
-    }
-
-    @Override
     public boolean onCreateOptionsMenu(Menu menu) {
 	super.onCreateOptionsMenu(menu);
 	MenuInflater inflater = getMenuInflater();
 	inflater.inflate(R.menu.login, menu);
 	return true;
     }
+    
+    @Override
+    protected void onDestroy() {     
+        super.onDestroy();
+        unbindService(mServConn);
+    }
 
     @Override
     public final boolean onOptionsItemSelected(MenuItem item) {
@@ -163,10 +159,6 @@
 		result = true;
 		break;
 	    case R.id.login_menu_login:
-		if (mBeemApplication.isAccountConfigured()) {
-		    Intent i = new Intent(this, LoginAnim.class);
-		    startActivityForResult(i, LOGIN_REQUEST_CODE);
-		}
 		result = true;
 		break;
 	    default:
@@ -235,10 +227,33 @@
 	    if (convertView == null) {
 		v = mInflater.inflate(R.layout.login_row_account, null);
 	    }
-	    TextView tv = (TextView) v.findViewById(R.id.accountname);
-	    tv.setText(mListAccount.get(position));
+	    ImageButton logo = (ImageButton) v.findViewById(R.id.loginanim_logo_anim);
+	    logo.setFocusable(false);
+	    logo.setOnClickListener(new BeemConnectionOnClick());
+	    TextView name = (TextView) v.findViewById(R.id.accountname);
+	    name.setText(mListAccount.get(position));
 	    return v;
 	}
+
+    }
+
+    private class BeemConnectionOnClick implements android.view.View.OnClickListener {
+
+	@Override
+	public void onClick(View v) {
+	    //TODO: Check if already connected -> disconnect
+	    TextView accountStatus = (TextView) findViewById(R.id.accountstatus);
+	    accountStatus.setText(R.string.login_pending);    
+	    ImageButton logo = (ImageButton) findViewById(R.id.loginanim_logo_anim);
+	    logo.startAnimation(mAnimationLogo);
+	    TextView accountName = (TextView) findViewById(R.id.accountname);
+	    Intent i = new Intent(Login.SERVICE_INTENT);
+	    i.putExtra("account_name", accountName.getText());
+	    bindService(i, mServConn, BIND_AUTO_CREATE);
+	    mTask = new LoginTask(v.getRootView());
+
+	}
+
     }
 
     /**
@@ -256,10 +271,74 @@
 	 */
 	@Override
 	public void onItemClick(AdapterView<?> arg0, View v, int pos, long lpos) {
-	    Intent i = new Intent(Login.this, LoginAnim.class);
-	    mAccountName =  mListAccount.get(pos);
-	    i.putExtra("account_name", mAccountName);
-	    startActivityForResult(i, LOGIN_REQUEST_CODE);
+	    Intent i = new Intent(Login.this, ContactList.class);
+	    startActivity(i);
 	}
     }
+
+    /**
+     * Asynchronous class for connection.
+     */
+    private class LoginTask extends LoginAsyncTask {
+
+	private View mView;
+
+	/**
+	 * Constructor.
+	 */
+	LoginTask(View v) {
+	    mView = v;
+	}
+
+	@Override
+	protected void onPostExecute(Boolean result) {
+	    ImageButton logo = (ImageButton) mView.findViewById(R.id.loginanim_logo_anim);
+	    if (result == null || !result) { // Task cancelled or exception
+		unbindService(mServConn);
+		logo.setBackgroundResource(R.drawable.beem_launcher_icon_silver);
+	    } else { // Connection OK
+		logo.setBackgroundResource(R.drawable.beem_icon_launcher_color);
+	    }
+	    logo.clearAnimation();
+	}
+
+	@Override
+	protected void onProgressUpdate(Integer... values) {
+	    TextView status = (TextView) mView.findViewById(R.id.accountstatus);
+	    status.setText(getResources().getStringArray(R.array.loganim_state)[values[0]]);
+	}
+
+	@Override
+	protected void onCancelled() {
+	    super.onCancelled();
+	    Login.this.stopService(Login.SERVICE_INTENT);
+	}
+
+    }
+
+    /**
+     * The service connection used to connect to the Beem service.
+     */
+    private class LoginServiceConnection implements ServiceConnection {
+
+	/**
+	 * Constructor.
+	 */
+	public LoginServiceConnection() {
+	}
+
+	@Override
+	public void onServiceConnected(ComponentName name, IBinder service) {
+	    Log.e("BEEMSERVICECONNECTION", "CONNECTED");
+	    mXmppFacade = IXmppFacade.Stub.asInterface(service);	    
+	    mTask.execute(mXmppFacade);
+	}
+
+	@Override
+	public void onServiceDisconnected(ComponentName name) {
+	    Log.e("BEEMSERVICECONNECTION", "DISCONNECTED");
+	    mXmppFacade = null;
+	}
+    }
+
 }