New Concept service from da_risk but not up to date.
author"Vincent Veronis"
Thu, 21 Jul 2011 23:03:26 +0200
changeset 897 07de7eb304b6
parent 896 c2c6ee3d3c71
child 898 965a9876c37a
New Concept service from da_risk but not up to date. Synchronisation done via new service
AndroidManifest.xml
src/com/beem/project/beem/BeemIntent.java
src/com/beem/project/beem/BeemService.java
src/com/beem/project/beem/account/SyncAdapterService.java
src/com/beem/project/beem/service/XmppConnectionAdapter.java
src/com/beem/project/beem/smack/avatar/AvatarManager.java
src/com/beem/project/beem/ui/Login.java
--- a/AndroidManifest.xml	Mon Jun 13 15:00:23 2011 +0200
+++ b/AndroidManifest.xml	Thu Jul 21 23:03:26 2011 +0200
@@ -158,12 +158,12 @@
 			android:name=".providers.AvatarProvider"
 			android:label="Avatar Provider"
 			android:authorities="com.beem.project.beem.providers.avatarprovider"
-			android:exported="false"  />
+			android:exported="false" />
 		<provider
 			android:name=".providers.MessageProvider"
 			android:label="Message Provider"
 			android:authorities="com.beem.project.beem.providers.messageprovider"
-			android:exported="false"  />
+			android:exported="false" />
 		<service
 			android:name=".account.AuthenticatorService"
 			android:exported="true"
@@ -200,6 +200,18 @@
 				<action
 					android:name="com.beem.project.beem.BeemService"></action>
 			</intent-filter>
+			<intent-filter>
+				<action
+					android:name="com.beem.project.beem.BeemService" />
+				<action
+					android:name="com.beem.project.beem.intent.action.SYNC" />
+				<action
+					android:name="com.beem.project.beem.intent.action.CONNECT" />
+				<action
+					android:name="com.beem.project.beem.intent.action.DISCONNECT" />
+				<action
+					android:name="com.beem.project.beem.intent.action.SEND_MESSAGE" />
+			</intent-filter>
 		</service>
 	</application>
 	<permission
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/com/beem/project/beem/BeemIntent.java	Thu Jul 21 23:03:26 2011 +0200
@@ -0,0 +1,71 @@
+
+/*
+    BEEM is a videoconference application on the Android Platform.
+
+    Copyright (C) 2009 by Frederic-Charles Barthelery,
+                          Jean-Manuel Da Silva,
+                          Nikita Kozlov,
+                          Philippe Lago,
+                          Jean Baptiste Vergely,
+                          Vincent Veronis.
+
+    This file is part of BEEM.
+
+    BEEM is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    BEEM is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with BEEM.  If not, see <http://www.gnu.org/licenses/>.
+
+    Please send bug reports with examples or suggestions to
+    contact@beem-project.com or http://dev.beem-project.com/
+
+    Epitech, hereby disclaims all copyright interest in the program "Beem"
+    written by Frederic-Charles Barthelery,
+               Jean-Manuel Da Silva,
+               Nikita Kozlov,
+               Philippe Lago,
+               Jean Baptiste Vergely,
+               Vincent Veronis.
+
+    Nicolas Sadirac, November 26, 2009
+    President of Epitech.
+
+    Flavien Astraud, November 26, 2009
+    Head of the EIP Laboratory.
+
+*/
+package com.beem.project.beem;
+
+public class BeemIntent {
+
+    public static final String ACTION_CONNECT = "com.beem.project.beem.intent.action.CONNECT";
+
+    public static final String ACTION_DISCONNECT = "com.beem.project.beem.intent.action.DISCONNECT";
+
+    public static final String ACTION_SEND_MESSAGE = "com.beem.project.beem.intent.action.SEND_MESSAGE";
+    
+    public static final String ACTION_SYNC = "com.beem.project.beem.intent.action.SYNC";
+
+    /*Broadcast Receiver's action */
+    public static final String ACTION_CONNECTED = "com.beem.project.beem.intent.action.CONNECTED";
+
+    public static final String ACTION_DISCONNECTED = "com.beem.project.beem.intent.action.DISCONNECTED";
+
+    public static final String ACTION_MESSAGE_RECEIVED = "com.beem.project.beem.intent.action.MESSAGE_RECEIVED";
+
+    public static final String EXTRA_ACCOUNT = "com.beem.project.beem.intent.extra.ACCOUNT";
+
+    public static final String EXTRA_JID = "com.beem.project.beem.intent.extra.JID";
+
+    public static final String EXTRA_MESSAGE = "com.beem.project.beem.intent.extra.MESSAGE";
+
+}
+
--- a/src/com/beem/project/beem/BeemService.java	Mon Jun 13 15:00:23 2011 +0200
+++ b/src/com/beem/project/beem/BeemService.java	Thu Jul 21 23:03:26 2011 +0200
@@ -43,13 +43,20 @@
  */
 package com.beem.project.beem;
 
+import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.jivesoftware.smack.ConnectionConfiguration;
 import org.jivesoftware.smack.Roster;
+import org.jivesoftware.smack.RosterEntry;
+import org.jivesoftware.smack.RosterGroup;
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.Roster.SubscriptionMode;
+import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.provider.ProviderManager;
+import org.jivesoftware.smack.util.StringUtils;
 import org.jivesoftware.smackx.packet.ChatStateExtension;
 import org.jivesoftware.smackx.provider.DelayInfoProvider;
 import org.jivesoftware.smackx.provider.DiscoverInfoProvider;
@@ -65,18 +72,33 @@
 import android.app.NotificationManager;
 import android.app.Service;
 import android.content.BroadcastReceiver;
+import android.content.ContentProviderOperation;
+import android.content.ContentUris;
+import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.OperationApplicationException;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.Editor;
+import android.database.Cursor;
 import android.net.ConnectivityManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
 import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
 import android.os.RemoteException;
+import android.provider.ContactsContract;
 import android.util.Log;
 
+import com.beem.project.beem.service.BeemAvatarCache;
+import com.beem.project.beem.service.RosterAdapter;
 import com.beem.project.beem.service.XmppConnectionAdapter;
 import com.beem.project.beem.service.XmppFacade;
+import com.beem.project.beem.service.aidl.IRoster;
 import com.beem.project.beem.service.aidl.IXmppFacade;
 import com.beem.project.beem.smack.avatar.AvatarMetadataProvider;
 import com.beem.project.beem.smack.avatar.AvatarProvider;
@@ -96,17 +118,19 @@
     public static final int NOTIFICATION_STATUS_ID = 100;
 
     private static final String TAG = "BeemService";
+    private static final int MESSAGE_CONNECT = 0x1;
+    private static final int MESSAGE_SEND_MSG = 0x2;
+    private static final int MESSAGE_SYNC = 0x3;
+    private static final int NB_DB_OPERATION = 50;
 
     private NotificationManager mNotificationManager;
-    //TODO: MAP instead of LIST
     private Map<String, XmppConnectionAdapter> mConnection = new HashMap<String, XmppConnectionAdapter>();
     private Map<String, BeemConnection> mBeemConnection = new HashMap<String, BeemConnection>();
-
-    //TODO: MAp maybe instead of LIST
     private Map<String, IXmppFacade.Stub> mBind = new HashMap<String, IXmppFacade.Stub>();
 
     private boolean mOnOffReceiverIsRegistered;
-
+    private Handler mHandler;
+    private Looper mServiceLooper;
     private BeemBroadcastReceiver mReceiver = new BeemBroadcastReceiver();
     private BeemServicePreferenceListener mPreferenceListener = new BeemServicePreferenceListener();
     private BeemServiceBroadcastReceiver mOnOffReceiver = new BeemServiceBroadcastReceiver();
@@ -117,6 +141,14 @@
     public BeemService() {
     }
 
+    @Override
+    public int onStartCommand(Intent intent, int flags, int startId) {
+	if (intent != null) {
+	    handleIntent(intent);
+	}
+	return Service.START_STICKY;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -125,12 +157,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);
     }
 
@@ -154,23 +186,29 @@
     @Override
     public void onCreate() {
 	super.onCreate();
-	AccountManager am = AccountManager.get(BeemService.this);
-	Account allAccount[] = am.getAccountsByType("com.beem.project.com");
-	for (Account account : allAccount) {
-	    BeemConnection beemco = new BeemConnection(BeemService.this
-		.getSharedPreferences(account.name, MODE_PRIVATE), mPreferenceListener);
-	    if (beemco.getSettings().getBoolean("settings_away_chk", false)) {
-		mOnOffReceiverIsRegistered = true;
-		registerReceiver(mOnOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
-		registerReceiver(mOnOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
-	    }
-	    mBeemConnection.put(account.name, beemco);
-	    XmppConnectionAdapter beemcoAdapter = new XmppConnectionAdapter(beemco.getConnectionConfiguration(), beemco
-		.getJid(), beemco.getPassword(), this);
-	    mConnection.put(account.name, beemcoAdapter);
-	    mBind.put(account.name, new XmppFacade(beemcoAdapter));
-	    Log.e(TAG, "Account configuration : " + account.toString() + " DONE");
-	}
+
+	HandlerThread thread = new HandlerThread("BeemServiceThread");
+	thread.start();
+	mServiceLooper = thread.getLooper();
+	mHandler = new BeemServiceHandler(mServiceLooper);
+
+	//	AccountManager am = AccountManager.get(BeemService.this);
+	//	Account allAccount[] = am.getAccountsByType("com.beem.project.com");
+	//	for (Account account : allAccount) {
+	//	    BeemConnection beemco = new BeemConnection(BeemService.this
+	//		.getSharedPreferences(account.name, MODE_PRIVATE), mPreferenceListener);
+	//	    if (beemco.getSettings().getBoolean("settings_away_chk", false)) {
+	//		mOnOffReceiverIsRegistered = true;
+	//		registerReceiver(mOnOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+	//		registerReceiver(mOnOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
+	//	    }
+	//	    mBeemConnection.put(account.name, beemco);
+	//	    XmppConnectionAdapter beemcoAdapter = new XmppConnectionAdapter(beemco.getConnectionConfiguration(), beemco
+	//		.getJid(), beemco.getPassword(), this);
+	//	    mConnection.put(account.name, beemcoAdapter);
+	//	    mBind.put(account.name, new XmppFacade(beemcoAdapter));
+	//	    Log.e(TAG, "Account configuration : " + account.toString() + " DONE");
+	//	}
 	registerReceiver(mReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
 
 	configure(ProviderManager.getInstance());
@@ -204,14 +242,14 @@
     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);
     }
@@ -433,4 +471,388 @@
 	    }
 	}
     }
+
+    private void handleIntent(Intent intent) {
+	Message msg = null;
+	String action = intent.getAction();
+	if (BeemIntent.ACTION_CONNECT.equals(action)) {
+	    msg = mHandler.obtainMessage(MESSAGE_CONNECT, intent.getExtras());
+	} else if (BeemIntent.ACTION_SEND_MESSAGE.equals(action)) {
+	    msg = mHandler.obtainMessage(MESSAGE_SEND_MSG, intent.getExtras());
+	} else if (BeemIntent.ACTION_SYNC.equals(action)) {
+	    msg = mHandler.obtainMessage(MESSAGE_SYNC, intent.getExtras());
+	} else {
+	    Log.w(TAG, "Unknown intent " + intent);
+	}
+	if (msg != null)
+	    mHandler.sendMessage(msg);
+    }
+
+    private class BeemServiceHandler extends Handler {
+
+	public BeemServiceHandler(Looper looper) {
+	    super(looper);
+	}
+
+	@Override
+	public void handleMessage(Message msg) {
+	    Bundle b = (Bundle) msg.obj;
+	    switch (msg.what) {
+		case MESSAGE_CONNECT:
+		    handleConnect(b);
+		    break;
+		case MESSAGE_SEND_MSG:
+		    String account = b.getString(BeemIntent.EXTRA_ACCOUNT);
+		    XmppConnectionAdapter con = mConnection.get(account);
+		    if (con != null) {
+			con.handleMessage(msg);
+		    }
+		    break;
+		case MESSAGE_SYNC:		 
+		    Account a = b.getParcelable(BeemIntent.EXTRA_ACCOUNT);
+		    Bundle accountName = new Bundle();
+		    accountName.putString(BeemIntent.EXTRA_ACCOUNT, a.name);
+		    handleConnect(accountName);
+		    XmppConnectionAdapter co = mConnection.get(a.name);
+		    if (co != null) {
+		        manageRoster(co.getAdaptee().getRoster(), a);
+		    }
+		    break;
+		default:
+		    Log.w(TAG, "Unknown message " + msg);
+	    }
+	}
+    }
+
+    private void handleConnect(Bundle b) {
+	Intent res = new Intent(BeemIntent.ACTION_DISCONNECTED);
+	String account = null;
+	if (b != null)
+	    account = b.getString(BeemIntent.EXTRA_ACCOUNT);
+	if (account == null) //TODO temporary
+	    account = "dummy";
+	if (account == null) {
+	    //connect all
+	} else {
+
+	    BeemConnection beemco = new BeemConnection(BeemService.this.getSharedPreferences(account, MODE_PRIVATE),
+		mPreferenceListener);
+	    if (beemco.getSettings().getBoolean("settings_away_chk", false)) {
+		mOnOffReceiverIsRegistered = true;
+		registerReceiver(mOnOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+		registerReceiver(mOnOffReceiver, new IntentFilter(Intent.ACTION_SCREEN_ON));
+	    }
+	    mBeemConnection.put(account, beemco);
+	    XmppConnectionAdapter beemcoAdapter = new XmppConnectionAdapter(beemco.getConnectionConfiguration(), beemco
+		.getJid(), beemco.getPassword(), this);
+
+	    try {
+		Log.i(TAG, "Starting connection of " + account);
+		if (beemcoAdapter.connectSync()) {
+		    mConnection.put(account, beemcoAdapter);
+		    mBind.put(account, new XmppFacade(beemcoAdapter));
+
+		    res.setAction(BeemIntent.ACTION_CONNECTED);
+		    Log.e(TAG, "Account configuration : " + account.toString() + " DONE");
+		} else {
+		    Log.w(TAG, "Unable to connect " + account);
+		}
+	    } catch (RemoteException e) {
+		Log.e(TAG, "Unable to connect " + account, e);
+	    }
+
+	    //	    res.putExtra(BeemIntent.EXTRA_ACCOUNT, account);
+	    //	    XmppConnectionAdapter con = mConnections.get(account);
+	    //	    if (con != null && con.isAuthentificated())
+	    //		return;
+	    //	    if (con == null ) {
+	    //		ConnectionConfiguration config = initConnectionConfig(account);
+	    //		String login = StringUtils.parseName(account);
+	    //		String password = mSettings.getString(BeemApplication.ACCOUNT_PASSWORD_KEY, "");
+	    //
+	    //		if (mSettings.getBoolean(BeemApplication.FULL_JID_LOGIN_KEY, false) ||
+	    //			"gmail.com".equals(mService) || "googlemail.com".equals(mService))  {
+	    //		    login = account;
+	    //			}
+	    //		con = new XmppConnectionAdapter(config, login, password, this);
+	    //		try {
+	    //		    Log.i(TAG, "Starting connection of " + account);
+	    //		    if(con.connectSync()){
+	    //			mConnections.put(account, con);
+	    //			mConnection = con;
+	    //			
+	    //			//TODO 
+	    //			mBind = new XmppFacade(con);
+	    //		    } else {
+	    //			Log.w(TAG, "Unable to connect " + account);
+	    //		    }
+	    //		} catch (RemoteException e) {
+	    //		    Log.e(TAG, "Unable to connect " + account, e);
+	    //	    }
+	    //	}
+	    sendBroadcast(res);
+	}
+    }
+
+    /**
+     * Method to execute content provider operation.
+     * @param ops
+     */
+    private void executeOperation(final ArrayList<ContentProviderOperation> ops) {
+	try {
+	    getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
+	} catch (RemoteException e) {
+	    Log.d(TAG, "Error during sync of contact", e);
+	} catch (OperationApplicationException e) {
+	    Log.d(TAG, "Error during sync of contact", e);
+	}
+	ops.clear();
+    }
+
+    /**
+     * Roster sync method.
+     * @param r The roster to sync
+     * @param a The account related
+     */
+    private void manageRoster(final Roster r, final Account a) {
+	Log.e("OOO", "roster" + r + "account" + a);
+	ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
+	for (RosterGroup group : r.getGroups()) {
+	    if (group != null) {
+		manageGroup(ops, a, group);
+	    }
+	    if (ops.size() > NB_DB_OPERATION)
+		executeOperation(ops);
+	}
+	if (ops.size() > 0)
+	    executeOperation(ops);
+	for (RosterEntry entry : r.getEntries()) {
+	    if (entry != null) {
+		long rawContactID = manageEntry(ops, a, entry);
+		addUpdateStatus(ops, entry, r.getPresence(entry.getUser()), rawContactID);
+	    }
+	    if (ops.size() > NB_DB_OPERATION)
+		executeOperation(ops);
+	}
+	if (ops.size() > 0)
+	    executeOperation(ops);
+    }
+
+    private void manageGroup(ArrayList<ContentProviderOperation> ops, Account account, RosterGroup group) {
+	Log.i(TAG, "Sync group : " + group.getName() + " " + group.getEntryCount());
+	long rawGroupID = getRawGroupID(account.name, group.getName());
+	if (rawGroupID == -1) {
+	    ContentProviderOperation.Builder builder = ContentProviderOperation
+		.newInsert(ContactsContract.Groups.CONTENT_URI);
+	    builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
+	    builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
+	    builder.withValue(ContactsContract.Groups.TITLE, group.getName());
+	    ops.add(builder.build());
+	}
+    }
+
+    /**
+     * RosterEntry sync method.
+     * @param ops The content provider operation
+     * @param account The account related
+     * @param entry The roster entry to sync
+     * @return The raw contact ID
+     */
+    private long manageEntry(ArrayList<ContentProviderOperation> ops, Account account, RosterEntry entry) {
+	long rawContactID = getRawContactID(account.name, entry.getUser());
+	Log.i(TAG, "Sync Contact : " + entry.getUser() + " RawContactID : " + rawContactID);
+	if (rawContactID == -1) { // Not found in database, add new
+	    ContentValues values = new ContentValues();
+	    values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type);
+	    values.put(ContactsContract.RawContacts.ACCOUNT_NAME, account.name);
+	    values.put(ContactsContract.RawContacts.SOURCE_ID, entry.getUser());
+	    Uri rawContactUri = getContentResolver().insert(ContactsContract.RawContacts.CONTENT_URI, values);
+	    rawContactID = ContentUris.parseId(rawContactUri);
+	    values.clear();
+	    ContentProviderOperation.Builder builder = addUpdateStructuredName(entry, rawContactID, true);
+	    ops.add(builder.build());
+	    for (RosterGroup group : entry.getGroups()) {
+		builder = addUpdateGroup(entry, rawContactID, getRawGroupID(account.name, group.getName()), true);
+		ops.add(builder.build());
+	    }
+	    builder = createProfile(entry, rawContactID, account);
+	    ops.add(builder.build());
+	} 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;
+    }
+
+    /**
+     * Method to insert or update structured name informations.
+     * @param entry The roster entry to sync
+     * @param rawContactID The contact ID in the android database
+     * @param isInsert Insert boolean
+     * @return
+     */
+    private ContentProviderOperation.Builder addUpdateStructuredName(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.StructuredName.CONTENT_ITEM_TYPE);
+	    builder.withValue(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, rawContactID);
+	} else {
+	    builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
+	    builder.withSelection(
+		ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID + " =? AND "
+		    + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE
+		    + "'", new String[] { String.valueOf(rawContactID) });
+	}
+	builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName);
+	builder.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, displayName);
+	builder.withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, displayName);
+	return builder;
+    }
+
+    private 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(getBaseContext());
+	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 ContentProviderOperation.Builder addUpdateGroup(RosterEntry entry, long rawContactID, long rawGroupID,
+	boolean isInsert) {
+	String displayName = entry.getName() != null ? entry.getName() : entry.getUser();
+	Log.e(TAG + "UPDATE GROUP", "Contact : " + displayName + " GroupID :" + rawGroupID);
+	ContentProviderOperation.Builder builder = null;
+	if (isInsert) {
+	    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
+	    builder.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID);
+	    builder.withValue(ContactsContract.Data.MIMETYPE,
+		ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE);
+	    builder.withValue(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID, rawGroupID);
+	}
+	//TODO: delete - contact doesnt appear anymore in this group 
+	return builder;
+    }
+
+    /**
+     * Method to insert or update IM informations.
+     * @param entry The roster entry to sync
+     * @param rawContactID The contact ID in the android database
+     * @param isInsert Insert boolean
+     * @return
+     */
+    private ContentProviderOperation.Builder createProfile(RosterEntry entry, long rawContactID, Account account) {
+	String displayName = entry.getName() != null ? entry.getName() : entry.getUser();
+	ContentProviderOperation.Builder builder;
+	builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
+	builder.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID);
+	builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE);
+	builder.withValue(ContactsContract.CommonDataKinds.Im.RAW_CONTACT_ID, rawContactID);
+	builder.withValue(ContactsContract.CommonDataKinds.Im.DATA1, displayName);
+	builder.withValue(ContactsContract.CommonDataKinds.Im.PROTOCOL,
+	    ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER);
+	return builder;
+    }
+
+    /**
+     * Method to insert or update IM informations.
+     * @param entry The roster entry to sync
+     * @param rawContactID The contact ID in the android database
+     * @param isInsert Insert boolean
+     * @return
+     */
+    private void addUpdateStatus(ArrayList<ContentProviderOperation> ops, RosterEntry entry, Presence p,
+	long rawContactID) {
+	String displayName = entry.getName() != null ? entry.getName() : entry.getUser();
+	Log.i(TAG + "UPDATESTATUS", "Contact : " + displayName + " Presence status : " + p.getStatus()
+	    + " Presence status state : " + Status.getStatusFromPresence(p));
+	ContentProviderOperation.Builder builder;
+	builder = ContentProviderOperation.newInsert(ContactsContract.StatusUpdates.CONTENT_URI);
+	builder.withValue(ContactsContract.StatusUpdates.PROTOCOL, ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER);
+	builder.withValue(ContactsContract.StatusUpdates.IM_HANDLE, displayName);
+	//TODO: Get account name
+	builder.withValue(ContactsContract.StatusUpdates.IM_ACCOUNT, "beem@elyzion.net");
+	builder.withValue(ContactsContract.StatusUpdates.STATUS, p.getStatus());
+	builder.withValue(ContactsContract.StatusUpdates.STATUS_RES_PACKAGE, "com.beem.project.beem");
+	builder.withValue(ContactsContract.StatusUpdates.STATUS_LABEL, R.string.app_name);
+	//TODO: Get status icon
+	builder.withValue(ContactsContract.StatusUpdates.STATUS_ICON, R.drawable.beem_status_icon);
+	//TODO: Pb presence ... 2 appear on 3 raw .... random appear
+	builder.withValue(ContactsContract.StatusUpdates.PRESENCE, Status.getStatusFromPresence(p));
+	ops.add(builder.build());
+    }
+
+    /**
+     * Get contact ID from android database.
+     * @param account The account related
+     * @param jid The jid related
+     * @return ID in the database of the jid
+     */
+    private long getRawContactID(String account, String jid) {
+	long authorId = -1;
+	final Cursor c = getContentResolver().query(ContactsContract.RawContacts.CONTENT_URI,
+	    new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.SOURCE_ID },
+	    ContactsContract.RawContacts.ACCOUNT_NAME + "=? AND " + ContactsContract.RawContacts.SOURCE_ID + "=?",
+	    new String[] { account, jid }, null);
+	try {
+	    if (c.moveToFirst())
+		authorId = c.getInt(c.getColumnIndex(ContactsContract.RawContacts._ID));
+	} finally {
+	    if (c != null)
+		c.close();
+	}
+	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 long getRawGroupID(String account, String group) {
+	long authorId = -1;
+	final Cursor c = getContentResolver().query(ContactsContract.Groups.CONTENT_URI,
+	    new String[] { ContactsContract.Groups._ID },
+	    ContactsContract.Groups.ACCOUNT_NAME + "=? AND " + ContactsContract.Groups.TITLE + "=?",
+	    new String[] { account, group }, null);
+	try {
+	    if (c.moveToFirst())
+		authorId = c.getInt(c.getColumnIndex(ContactsContract.Groups._ID));
+	} finally {
+	    if (c != null)
+		c.close();
+	}
+	return authorId;
+    }
 }
--- a/src/com/beem/project/beem/account/SyncAdapterService.java	Mon Jun 13 15:00:23 2011 +0200
+++ b/src/com/beem/project/beem/account/SyncAdapterService.java	Thu Jul 21 23:03:26 2011 +0200
@@ -64,6 +64,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.IntentFilter;
 import android.content.OperationApplicationException;
 import android.content.SyncResult;
 import android.database.Cursor;
@@ -75,6 +76,7 @@
 import android.util.Log;
 
 import com.beem.project.beem.BeemConnection;
+import com.beem.project.beem.BeemIntent;
 import com.beem.project.beem.R;
 import com.beem.project.beem.service.BeemAvatarCache;
 import com.beem.project.beem.utils.Status;
@@ -139,293 +141,38 @@
      */
     public static void performSync(Context context, final Account account, Bundle extras, String authority,
 	ContentProviderClient provider, SyncResult syncResult) throws OperationCanceledException {
-	mContentResolver = context.getContentResolver();
-	Log.i(TAG, "performSync: " + account.toString());
-
-	//TODO: Get BeemService connectino support
-	//TODO: Get resource information
-	BeemConnection beemco = new BeemConnection(mContext.getSharedPreferences(account.name, MODE_PRIVATE), null);
-	//if (!BeemService.getIsLaunch())
-	//beemco.setNoPresence();
-	XMPPConnection con = new XMPPConnection(beemco.getConnectionConfiguration());
-	Roster roster = null;
-	try {
-	    con.connect();
-	    //SharedPreferences sp = context.getSharedPreferences(account.name, MODE_PRIVATE);	    
-	    con.login(beemco.getLogin(), beemco.getPassword(), "beem sync adapter");
-	    roster = con.getRoster();
-	} catch (XMPPException e) {
-	    Log.e(TAG, "Error while connecting with syncAdapter", e);
-	} catch (IllegalStateException e) {
-	    Log.e(TAG, "Not connected to server", e);
-	}
-	if (roster != null)
-	    manageRoster(roster, account);
-	con.disconnect();
-    }
-
-    /**
-     * Method to execute content provider operation.
-     * @param ops
-     */
-    private static void executeOperation(final ArrayList<ContentProviderOperation> ops) {
-	try {
-	    mContentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
-	} catch (RemoteException e) {
-	    Log.d(TAG, "Error during sync of contact", e);
-	} catch (OperationApplicationException e) {
-	    Log.d(TAG, "Error during sync of contact", e);
-	}
-	ops.clear();
-    }
-
-    /**
-     * Roster sync method.
-     * @param r The roster to sync
-     * @param a The account related
-     */
-    private static void manageRoster(final Roster r, final Account a) {
-	ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
-	for (RosterGroup group : r.getGroups()) {
-	    if (group != null) {
-		manageGroup(ops, a, group);
-	    }
-	    if (ops.size() > NB_DB_OPERATION)
-		executeOperation(ops);	    
-	}
-	if (ops.size() > 0)
-	    executeOperation(ops);
-	for (RosterEntry entry : r.getEntries()) {
-	    if (entry != null) {
-		long rawContactID = manageEntry(ops, a, entry);
-		addUpdateStatus(ops, entry, r.getPresence(entry.getUser()), rawContactID);
-	    }
-	    if (ops.size() > NB_DB_OPERATION)
-		executeOperation(ops);
-	}
-	if (ops.size() > 0)
-	    executeOperation(ops);
-    }
-
-    private static void manageGroup(ArrayList<ContentProviderOperation> ops, Account account, RosterGroup group) {
-	Log.i(TAG, "Sync group : " + group.getName() + " " + group.getEntryCount());
-	long rawGroupID = getRawGroupID(account.name, group.getName());
-	if (rawGroupID == -1) {
-	    ContentProviderOperation.Builder builder = ContentProviderOperation
-		.newInsert(ContactsContract.Groups.CONTENT_URI);
-	    builder.withValue(ContactsContract.Groups.ACCOUNT_NAME, account.name);
-	    builder.withValue(ContactsContract.Groups.ACCOUNT_TYPE, account.type);
-	    builder.withValue(ContactsContract.Groups.TITLE, group.getName());
-	    ops.add(builder.build());
-	}
-    }
+	Log.i(TAG, "performSync: " + account.toString());	
+	Intent intent = new Intent(BeemIntent.ACTION_SYNC );
+	intent.putExtra(BeemIntent.EXTRA_ACCOUNT, account);
+//	IntentFilter filter = new IntentFilter(BeemIntent.ACTION_CONNECTED);
+//	filter.addAction(BeemIntent.ACTION_DISCONNECTED);
+//	registerReceiver(mReceiver, filter);
+	context.startService(intent);
+	
+//	mContentResolver = context.getContentResolver();
 
-    /**
-     * RosterEntry sync method.
-     * @param ops The content provider operation
-     * @param account The account related
-     * @param entry The roster entry to sync
-     * @return The raw contact ID
-     */
-    private static long manageEntry(ArrayList<ContentProviderOperation> ops, Account account, RosterEntry entry) {
-	long rawContactID = getRawContactID(account.name, entry.getUser());
-	Log.i(TAG, "Sync Contact : " + entry.getUser() + " RawContactID : " + rawContactID);
-	if (rawContactID == -1) { // Not found in database, add new
-	    ContentValues values = new ContentValues();
-	    values.put(ContactsContract.RawContacts.ACCOUNT_TYPE, account.type);
-	    values.put(ContactsContract.RawContacts.ACCOUNT_NAME, account.name);
-	    values.put(ContactsContract.RawContacts.SOURCE_ID, entry.getUser());
-	    Uri rawContactUri = mContentResolver.insert(ContactsContract.RawContacts.CONTENT_URI, values);
-	    rawContactID = ContentUris.parseId(rawContactUri);
-	    values.clear();
-	    ContentProviderOperation.Builder builder = addUpdateStructuredName(entry, rawContactID, true);
-	    ops.add(builder.build());
-	    for (RosterGroup group : entry.getGroups()) {
-		builder = addUpdateGroup(entry, rawContactID, getRawGroupID(account.name, group.getName()), true);
-		ops.add(builder.build());
-	    }
-	    builder = createProfile(entry, rawContactID, account);
-	    ops.add(builder.build());
-	} 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;
-    }
-
-    /**
-     * Method to insert or update structured name informations.
-     * @param entry The roster entry to sync
-     * @param rawContactID The contact ID in the android database
-     * @param isInsert Insert boolean
-     * @return
-     */
-    private static ContentProviderOperation.Builder addUpdateStructuredName(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.StructuredName.CONTENT_ITEM_TYPE);
-	    builder.withValue(ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID, rawContactID);
-	} else {
-	    builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
-	    builder.withSelection(
-		ContactsContract.CommonDataKinds.StructuredName.RAW_CONTACT_ID + " =? AND "
-		    + ContactsContract.Data.MIMETYPE + " = '" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE
-		    + "'", new String[] { String.valueOf(rawContactID) });
-	}
-	builder.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName);
-	builder.withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, displayName);
-	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;
+//
+//	//TODO: Get BeemService connectino support
+//	//TODO: Get resource information
+//	BeemConnection beemco = new BeemConnection(mContext.getSharedPreferences(account.name, MODE_PRIVATE), null);
+//	//if (!BeemService.getIsLaunch())
+//	//beemco.setNoPresence();
+//	XMPPConnection con = new XMPPConnection(beemco.getConnectionConfiguration());
+//	Roster roster = null;
+//	try {
+//	    con.connect();
+//	    //SharedPreferences sp = context.getSharedPreferences(account.name, MODE_PRIVATE);	    
+//	    con.login(beemco.getLogin(), beemco.getPassword(), "beem sync adapter");
+//	    roster = con.getRoster();
+//	} catch (XMPPException e) {
+//	    Log.e(TAG, "Error while connecting with syncAdapter", e);
+//	} catch (IllegalStateException e) {
+//	    Log.e(TAG, "Not connected to server", e);
+//	}
+//	if (roster != null)
+//	    manageRoster(roster, account);
+//	con.disconnect();
     }
 
 
-    /**
-     * 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();
-	Log.e(TAG + "UPDATE GROUP", "Contact : " + displayName + " GroupID :" + rawGroupID);
-	ContentProviderOperation.Builder builder = null;
-	if (isInsert) {
-	    builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
-	    builder.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID);
-	    builder.withValue(ContactsContract.Data.MIMETYPE,
-		ContactsContract.CommonDataKinds.GroupMembership.CONTENT_ITEM_TYPE);
-	    builder.withValue(ContactsContract.CommonDataKinds.GroupMembership.GROUP_ROW_ID, rawGroupID);
-	}
-	//TODO: delete - contact doesnt appear anymore in this group 
-	return builder;
-    }
-
-    /**
-     * Method to insert or update IM informations.
-     * @param entry The roster entry to sync
-     * @param rawContactID The contact ID in the android database
-     * @param isInsert Insert boolean
-     * @return
-     */
-    private static ContentProviderOperation.Builder createProfile(RosterEntry entry, long rawContactID, Account account) {
-	String displayName = entry.getName() != null ? entry.getName() : entry.getUser();
-	ContentProviderOperation.Builder builder;
-	builder = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI);
-	builder.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID);
-	builder.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE);
-	builder.withValue(ContactsContract.CommonDataKinds.Im.RAW_CONTACT_ID, rawContactID);
-	builder.withValue(ContactsContract.CommonDataKinds.Im.DATA1, displayName);
-	builder.withValue(ContactsContract.CommonDataKinds.Im.PROTOCOL,
-	    ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER);
-	return builder;
-    }
-
-    /**
-     * Method to insert or update IM informations.
-     * @param entry The roster entry to sync
-     * @param rawContactID The contact ID in the android database
-     * @param isInsert Insert boolean
-     * @return
-     */
-    private static void addUpdateStatus(ArrayList<ContentProviderOperation> ops, RosterEntry entry, Presence p,
-	long rawContactID) {
-	String displayName = entry.getName() != null ? entry.getName() : entry.getUser();
-	Log.i(TAG + "UPDATESTATUS", "Contact : " + displayName + " Presence status : " + p.getStatus()
-	    + " Presence status state : " + Status.getStatusFromPresence(p));
-	ContentProviderOperation.Builder builder;
-	builder = ContentProviderOperation.newInsert(ContactsContract.StatusUpdates.CONTENT_URI);
-	builder.withValue(ContactsContract.StatusUpdates.PROTOCOL, ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER);
-	builder.withValue(ContactsContract.StatusUpdates.IM_HANDLE, displayName);
-	//TODO: Get account name
-	builder.withValue(ContactsContract.StatusUpdates.IM_ACCOUNT, "beem@elyzion.net");
-	builder.withValue(ContactsContract.StatusUpdates.STATUS, p.getStatus());
-	builder.withValue(ContactsContract.StatusUpdates.STATUS_RES_PACKAGE, "com.beem.project.beem");
-	builder.withValue(ContactsContract.StatusUpdates.STATUS_LABEL, R.string.app_name);
-	//TODO: Get status icon
-	builder.withValue(ContactsContract.StatusUpdates.STATUS_ICON, R.drawable.beem_status_icon);
-	//TODO: Pb presence ... 2 appear on 3 raw .... random appear
-	builder.withValue(ContactsContract.StatusUpdates.PRESENCE, Status.getStatusFromPresence(p));
-	ops.add(builder.build());
-    }
-
-    /**
-     * Get contact ID from android database.
-     * @param account The account related
-     * @param jid The jid related
-     * @return ID in the database of the jid
-     */
-    private static long getRawContactID(String account, String jid) {
-	long authorId = -1;
-	final Cursor c = mContentResolver.query(ContactsContract.RawContacts.CONTENT_URI, new String[] {
-	    ContactsContract.RawContacts._ID, ContactsContract.RawContacts.SOURCE_ID },
-	    ContactsContract.RawContacts.ACCOUNT_NAME + "=? AND " + ContactsContract.RawContacts.SOURCE_ID + "=?",
-	    new String[] { account, jid }, null);
-	try {
-	    if (c.moveToFirst())
-		authorId = c.getInt(c.getColumnIndex(ContactsContract.RawContacts._ID));
-	} finally {
-	    if (c != null)
-		c.close();
-	}
-	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,
-	    new String[] { ContactsContract.Groups._ID }, ContactsContract.Groups.ACCOUNT_NAME + "=? AND "
-		+ ContactsContract.Groups.TITLE + "=?", new String[] { account, group }, null);
-	try {
-	    if (c.moveToFirst())
-		authorId = c.getInt(c.getColumnIndex(ContactsContract.Groups._ID));
-	} finally {
-	    if (c != null)
-		c.close();
-	}
-	return authorId;
-    }
-
 }
--- a/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Mon Jun 13 15:00:23 2011 +0200
+++ b/src/com/beem/project/beem/service/XmppConnectionAdapter.java	Thu Jul 21 23:03:26 2011 +0200
@@ -40,7 +40,7 @@
     Flavien Astraud, November 26, 2009
     Head of the EIP Laboratory.
 
-*/
+ */
 package com.beem.project.beem.service;
 
 import java.util.Iterator;
@@ -65,6 +65,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
+import android.os.Bundle;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.util.Log;
@@ -114,8 +115,7 @@
     private AvatarManager mAvatarManager;
     private PepSubManager mPepManager;
     private SharedPreferences mPref;
-    private final RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners =
-	new RemoteCallbackList<IBeemConnectionListener>();
+    private final RemoteCallbackList<IBeemConnectionListener> mRemoteConnListeners = new RemoteCallbackList<IBeemConnectionListener>();
     private final SubscribePacketListener mSubscribePacketListener = new SubscribePacketListener();
 
     private final ConnexionListenerAdapter mConListener = new ConnexionListenerAdapter();
@@ -195,8 +195,8 @@
 		try {
 		    //TODO NIKITA DOES SOME SHIT !!! Fix this monstruosity
 		    String str = mService.getResources().getString(
-			mService.getResources().getIdentifier(
-			    e.getXMPPError().getCondition().replace("-", "_"), "string", "com.beem.project.beem"));
+			mService.getResources().getIdentifier(e.getXMPPError().getCondition().replace("-", "_"),
+			    "string", "com.beem.project.beem"));
 		    mErrorMsg = str;
 		} catch (NullPointerException e2) {
 		    if (!"".equals(e.getMessage()))
@@ -328,7 +328,6 @@
 
     /**
      * Get the AvatarManager of this connection.
-     *
      * @return the AvatarManager or null if there is not
      */
     public AvatarManager getAvatarManager() {
@@ -408,7 +407,6 @@
 	return mRoster;
     }
 
-
     /**
      * Returns true if currently authenticated by successfully calling the login method.
      * @return true when successfully authenticated
@@ -450,6 +448,15 @@
 	return mErrorMsg;
     }
 
+    public void handleMessage(android.os.Message msg) {
+	Bundle b = (Bundle) msg.obj;
+	switch (msg.what) {
+
+	    default:
+		Log.w(TAG, "Unknown message " + msg);
+	}
+    }
+
     /**
      * Initialize the features provided by beem.
      */
@@ -645,11 +652,10 @@
 			R.string.AcceptContactRequest, from), System.currentTimeMillis());
 		    notif.flags = Notification.FLAG_AUTO_CANCEL;
 		    Intent intent = new Intent(mService, Subscription.class);
-		    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
-			.putExtra("from", from);
+		    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK).putExtra("from", from);
 		    notif.setLatestEventInfo(mService, from, mService
 			.getString(R.string.AcceptContactRequestFrom, from), PendingIntent.getActivity(mService, 0,
-			    intent, PendingIntent.FLAG_ONE_SHOT));
+			intent, PendingIntent.FLAG_ONE_SHOT));
 		    int id = packet.hashCode();
 		    mService.sendNotification(id, notif);
 		}
@@ -697,8 +703,8 @@
 	    notification.flags = Notification.FLAG_AUTO_CANCEL;
 	    Intent intent = new Intent(mService, Subscription.class);
 	    intent.setData(Contact.makeXmppUri(from));
-	    notification.setLatestEventInfo(mService, from, mService
-		.getString(R.string.AcceptContactRequestFrom, from), PendingIntent.getActivity(mService, 0,
+	    notification.setLatestEventInfo(mService, from,
+		mService.getString(R.string.AcceptContactRequestFrom, from), PendingIntent.getActivity(mService, 0,
 		    intent, PendingIntent.FLAG_ONE_SHOT));
 	    int id = p.hashCode();
 	    mService.sendNotification(id, notification);
--- a/src/com/beem/project/beem/smack/avatar/AvatarManager.java	Mon Jun 13 15:00:23 2011 +0200
+++ b/src/com/beem/project/beem/smack/avatar/AvatarManager.java	Thu Jul 21 23:03:26 2011 +0200
@@ -43,20 +43,21 @@
 */
 package com.beem.project.beem.smack.avatar;
 
-import com.beem.project.beem.smack.avatar.AvatarMetadataExtension.Info;
-import com.beem.project.beem.smack.pep.PEPListener;
-import com.beem.project.beem.smack.pep.PepSubManager;
-
 import java.io.IOException;
-
+import java.util.LinkedList;
 import java.util.List;
-import java.util.LinkedList;
 
 import org.jivesoftware.smack.Connection;
 import org.jivesoftware.smack.packet.PacketExtension;
 import org.jivesoftware.smackx.pubsub.Item;
 import org.jivesoftware.smackx.pubsub.PayloadItem;
 
+import android.util.Log;
+
+import com.beem.project.beem.smack.avatar.AvatarMetadataExtension.Info;
+import com.beem.project.beem.smack.pep.PEPListener;
+import com.beem.project.beem.smack.pep.PepSubManager;
+
 /**
  * This class deals with the avatar data.
  * It can be configured to auto retrieve the avatar and put it in cache.
--- a/src/com/beem/project/beem/ui/Login.java	Mon Jun 13 15:00:23 2011 +0200
+++ b/src/com/beem/project/beem/ui/Login.java	Thu Jul 21 23:03:26 2011 +0200
@@ -142,7 +142,7 @@
     @Override
     protected void onDestroy() {     
         super.onDestroy();
-        unbindService(mServConn);
+        //unbindService(mServConn);
     }
 
     @Override