Modified architecture, SipService now handles all communications
Large Refactoring
Client Activities of the service must implement the ISipClient aidl
diff --git a/src/com/savoirfairelinux/sflphone/account/AccountSelectionSpinner.java b/src/com/savoirfairelinux/sflphone/account/AccountSelectionSpinner.java
index efc6178..78ff0b5 100644
--- a/src/com/savoirfairelinux/sflphone/account/AccountSelectionSpinner.java
+++ b/src/com/savoirfairelinux/sflphone/account/AccountSelectionSpinner.java
@@ -49,7 +49,6 @@
     private static final String TAG = AccountSelectionSpinner.class.getSimpleName();
     public static final String DEFAULT_ACCOUNT_ID = "IP2IP";
     private Context mContext;
-    private AccountListReceiver mAccountList = null;
     AccountSelectionAdapter mAdapter;
     ISipService serviceRef;
 
@@ -103,6 +102,10 @@
         setAdapter(mAdapter);
     }
 
+    public String getAccount() {
+        return mAdapter.getSelectedAccount();
+    }
+
     /****************************************
      * AccountManagementUI Interface
      ****************************************/
diff --git a/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
index 7f4b099..1f73eab 100644
--- a/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
+++ b/src/com/savoirfairelinux/sflphone/adapters/AccountSelectionAdapter.java
@@ -229,4 +229,8 @@
        selectedAccount = pos;
     }
 
+    public String getSelectedAccount() {
+       return accountIDs.get(selectedAccount);
+    }
+
 }
diff --git a/src/com/savoirfairelinux/sflphone/adapters/CallElementAdapter.java b/src/com/savoirfairelinux/sflphone/adapters/CallElementAdapter.java
index dc66ecd..c89c236 100644
--- a/src/com/savoirfairelinux/sflphone/adapters/CallElementAdapter.java
+++ b/src/com/savoirfairelinux/sflphone/adapters/CallElementAdapter.java
@@ -1,5 +1,7 @@
 package com.savoirfairelinux.sflphone.adapters;
 
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -22,13 +24,17 @@
 public class CallElementAdapter extends BaseAdapter {
     private ExecutorService infos_fetcher = Executors.newCachedThreadPool();
     private Context mContext;
-    private final List<SipCall> mCallList;
+    private final HashMap<String, SipCall> mCallList;
     private static final String CURRENT_STATE_LABEL = "    CURRENT STATE: ";
 
     public CallElementAdapter(Context context, List<SipCall> callList) {
         super();
         mContext = context;
-        mCallList = callList;
+        mCallList = new HashMap<String, SipCall>();
+        for(SipCall c : callList){
+            mCallList.put(c.getCallId(), c);
+        }
+       
     }
 
     @Override
@@ -58,8 +64,8 @@
 
         // Transfer the stock data from the data object
         // to the view objects
-        SipCall call = (SipCall) mCallList.get(position);
-        call.setAssociatedRowView(rowView);
+        
+        SipCall call = (SipCall) mCallList.values().toArray()[position];
         entryView.displayName.setText(call.getDisplayName());
         entryView.phones.setText(call.getPhone());
         entryView.state.setText(CURRENT_STATE_LABEL + call.getCallStateString());
@@ -84,7 +90,7 @@
 
     @Override
     public Object getItem(int pos) {
-        return mCallList.get(pos);
+        return mCallList.values().toArray()[pos];
     }
 
     @Override
@@ -94,12 +100,33 @@
     }
 
     public void add(SipCall c) {
-      mCallList.add(c);
+        mCallList.put(c.getCallId(), c);
+        notifyDataSetChanged();
         
     }
 
-    public void remove(SipCall c) {
-        mCallList.remove(c);
+
+    public void update(String id, String newState) {
+        if(newState.equals("INCOMING")) {
+            mCallList.get(id).setCallState(SipCall.CALL_STATE_INCOMING);
+        } else if(newState.equals("RINGING")) {
+            mCallList.get(id).setCallState(SipCall.CALL_STATE_RINGING);
+        } else if(newState.equals("CURRENT")) {
+            mCallList.get(id).setCallState(SipCall.CALL_STATE_CURRENT);
+        } else if(newState.equals("HUNGUP")) {
+            mCallList.get(id).setCallState(SipCall.CALL_STATE_HUNGUP);
+        } else if(newState.equals("BUSY")) {
+            mCallList.get(id).setCallState(SipCall.CALL_STATE_BUSY);
+        } else if(newState.equals("FAILURE")) {
+            mCallList.get(id).setCallState(SipCall.CALL_STATE_FAILURE);
+        } else if(newState.equals("HOLD")) {
+            mCallList.get(id).setCallState(SipCall.CALL_STATE_HOLD);
+        } else if(newState.equals("UNHOLD")) {
+            mCallList.get(id).setCallState(SipCall.CALL_STATE_CURRENT);
+        } else {
+            mCallList.get(id).setCallState(SipCall.CALL_STATE_NONE);
+        }
+        notifyDataSetChanged();
         
     }
 
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
index 0ae022e..34d3ab5 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
@@ -66,7 +66,7 @@
 import com.savoirfairelinux.sflphone.service.ISipService;
 import com.savoirfairelinux.sflphone.service.SipService;
 
-public class SFLPhoneHomeActivity extends Activity implements ActionBar.TabListener {
+public class SFLPhoneHomeActivity extends Activity implements ActionBar.TabListener, CallElementListFragment.Callbacks {
     SectionsPagerAdapter mSectionsPagerAdapter = null;
     static final String TAG = "SFLPhoneHome";
     private static final int REQUEST_CODE_PREFERENCES = 1;
@@ -76,8 +76,8 @@
     private HistoryFragment mHistorySectionFragment = null;
     private boolean mBound = false;
     private ISipService service;
-//    public AccountListReceiver mAccountList;
-//    public CallListReceiver mCallList = new CallListReceiver(this);
+    // public AccountListReceiver mAccountList;
+    // public CallListReceiver mCallList = new CallListReceiver(this);
     private SFLphoneApplication mApplication;
 
     private static final int ACTION_BAR_TAB_CONTACT = 0;
@@ -189,28 +189,28 @@
                 processingNewCallAction();
             }
         });
-        
-        buttonHangup.setOnClickListener(new OnClickListener() { 
+
+        buttonHangup.setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View v) {
                 processingHangUpAction();
-                
+
             }
         });
 
-//        IntentFilter callFilter = new IntentFilter(CallManagerCallBack.NEW_CALL_CREATED);
-//        callFilter.addAction(CallManagerCallBack.INCOMING_CALL);
-//        callFilter.addAction(CallManagerCallBack.CALL_STATE_CHANGED);
-//        LocalBroadcastManager.getInstance(this).registerReceiver(mCallList, callFilter);
-//
-//        mAccountList = mApplication.getAccountList();
-//        Log.w(TAG, "mAccountList=" + mAccountList + ", mCallElementList=" + mCallElementList);
+        // IntentFilter callFilter = new IntentFilter(CallManagerCallBack.NEW_CALL_CREATED);
+        // callFilter.addAction(CallManagerCallBack.INCOMING_CALL);
+        // callFilter.addAction(CallManagerCallBack.CALL_STATE_CHANGED);
+        // LocalBroadcastManager.getInstance(this).registerReceiver(mCallList, callFilter);
+        //
+        // mAccountList = mApplication.getAccountList();
+        // Log.w(TAG, "mAccountList=" + mAccountList + ", mCallElementList=" + mCallElementList);
 
         IntentFilter accountFilter = new IntentFilter(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
         accountFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
-//        LocalBroadcastManager.getInstance(this).registerReceiver(mAccountList, accountFilter);
+        // LocalBroadcastManager.getInstance(this).registerReceiver(mAccountList, accountFilter);
 
-        SipCall.setSFLPhoneHomeContext(this);
+//        SipCall.setSFLPhoneHomeContext(this);
     }
 
     @Override
@@ -255,36 +255,58 @@
         }
 
         /* unregister broadcast receiver */
-//        LocalBroadcastManager.getInstance(this).unregisterReceiver(mCallList);
-//        LocalBroadcastManager.getInstance(this).unregisterReceiver(mAccountList);
+        // LocalBroadcastManager.getInstance(this).unregisterReceiver(mCallList);
+        // LocalBroadcastManager.getInstance(this).unregisterReceiver(mAccountList);
 
         super.onDestroy();
     }
+    
+    public void launchCallActivity(SipCall.CallInfo infos)
+    {
+        Log.i(TAG, "Launch Call Activity");
+        Bundle bundle = new Bundle();
+        bundle.putParcelable("CallInfo", infos);
+        Intent intent = new Intent().setClass(this, CallActivity.class);
+        intent.putExtras(bundle);
+        startActivity(intent);
+    }
 
     /** Defines callbacks for service binding, passed to bindService() */
     private ServiceConnection mConnection = new ServiceConnection() {
 
         private ISipClient callback = new ISipClient.Stub() {
-            
+
             @Override
-            public void incomingCall() throws RemoteException {
-                Log.i(TAG,"Incoming call transfered from Service");
+            public void incomingCall(Intent call) throws RemoteException {
+                Log.i(TAG, "Incoming call transfered from Service");
+                SipCall.CallInfo infos = new SipCall.CallInfo(call);
                 
+                SipCall c = new SipCall(infos);
+                mCallElementList.addCall(c);
+            }
+
+            @Override
+            public void callStateChanged(Intent callState) throws RemoteException {
+                Bundle b = callState.getBundleExtra("com.savoirfairelinux.sflphone.service.newstate");
+                String cID = b.getString("CallID");
+                String state = b.getString("State");
+                Log.i(TAG,"callStateChanged"+cID+"    "+state);
+                mCallElementList.updateCall(cID, state);
+
             }
         };
 
         @Override
         public void onServiceConnected(ComponentName className, IBinder binder) {
             service = ISipService.Stub.asInterface(binder);
-            
+
             try {
-                service.registerClient(callback );
+                service.registerClient(callback);
             } catch (RemoteException e) {
-                Log.e(TAG,e.toString());
+                Log.e(TAG, e.toString());
             }
             mApplication.setSipService(service);
             mBound = true;
-//            mAccountList.setSipService(service);
             mCallElementList.onServiceSipBinded(service);
             Log.d(TAG, "Service connected service=" + service);
         }
@@ -310,12 +332,12 @@
 
         return super.onOptionsItemSelected(item);
     }
-    
+
     @Override
-    public void onActivityResult(int requestCode,int resultCode,Intent data){
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
         super.onActivityResult(requestCode, resultCode, data);
-        if(service != null){
-            // Refresh Spinner with accounts
+        if (REQUEST_CODE_PREFERENCES == requestCode && service != null) {
+            // Refresh Spinner with modified accounts
             mCallElementList.onServiceSipBinded(service);
         }
     }
@@ -341,30 +363,6 @@
         // Log.d(TAG, "onTabReselected");
     }
 
-    public void onSelectedCallAction(SipCall call) {
-        int callState = call.getCallStateInt();
-
-        if ((callState == SipCall.CALL_STATE_NONE) || (callState == SipCall.CALL_STATE_CURRENT)) {
-            buttonCall.setEnabled(false);
-            buttonHangup.setEnabled(true);
-        } else {
-            buttonCall.setEnabled(true);
-            buttonHangup.setEnabled(false);
-        }
-
-        buttonCall.setTag(call);
-        buttonHangup.setTag(call);
-    }
-
-    public void onUnselectedCallAction() {
-        buttonCall.setTag(null);
-        buttonCall.setTag(null);
-
-        buttonCall.setEnabled(true);
-        buttonHangup.setEnabled(false);
-    }
-
-
 
     public void processingNewCallAction() {
         // String accountID = mAccountList.currentAccountID;
@@ -385,15 +383,14 @@
         info.mCallType = SipCall.CALL_TYPE_OUTGOING;
 
         SipCall call = CallListReceiver.getCallInstance(info);
-        call.launchCallActivity(this);
-        call.placeCallUpdateUi();
+        launchCallActivity(call.mCallInfo);
+
         try {
             service.placeCall(info.mAccountID, info.mCallID, info.mPhone);
         } catch (RemoteException e) {
             Log.e(TAG, "Cannot call service method", e);
         }
-
-        onSelectedCallAction(call);
+        mCallElementList.addCall(call);
     }
 
     public void processingHangUpAction() {
@@ -423,8 +420,8 @@
                 break;
             case 1:
                 mCallElementList = new CallElementListFragment();
-                SipCall.setCallElementList(mCallElementList);
-//                mCallElementList.setAccountList(mAccountList);
+//                SipCall.setCallElementList(mCallElementList);
+                // mCallElementList.setAccountList(mAccountList);
                 fragment = mCallElementList;
                 Log.w(TAG, "getItem() CallElementList=" + fragment);
                 break;
@@ -513,4 +510,10 @@
         }
     }
 
+    @Override
+    public void onCallSelected(SipCall c) {
+        launchCallActivity(c.mCallInfo);
+        
+    }
+
 }
diff --git a/src/com/savoirfairelinux/sflphone/client/receiver/CallListReceiver.java b/src/com/savoirfairelinux/sflphone/client/receiver/CallListReceiver.java
index 5b1dc16..0a65b06 100644
--- a/src/com/savoirfairelinux/sflphone/client/receiver/CallListReceiver.java
+++ b/src/com/savoirfairelinux/sflphone/client/receiver/CallListReceiver.java
@@ -121,7 +121,7 @@
             call.setCallState(SipCall.CALL_STATE_CURRENT);
         } else if(newState.equals("HUNGUP")) {
             call.setCallState(SipCall.CALL_STATE_HUNGUP);
-            call.hangupUpdateUi();
+//            call.hangupUpdateUi();
             mList.remove(call);
         } else if(newState.equals("BUSY")) {
             call.setCallState(SipCall.CALL_STATE_BUSY);
@@ -151,7 +151,7 @@
         info.mCallType = SipCall.CALL_TYPE_INCOMING;
                 
         SipCall call = getCallInstance(info);
-        call.receiveCallUpdateUi();
-        call.launchCallActivity(mHome); 
+//        call.receiveCallUpdateUi();
+//        call.launchCallActivity(mHome); 
     }
 }
diff --git a/src/com/savoirfairelinux/sflphone/fragments/CallElementListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/CallElementListFragment.java
index 9ed7c72..82d3aba 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/CallElementListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/CallElementListFragment.java
@@ -43,6 +43,7 @@
 import android.content.Context;
 import android.content.CursorLoader;
 import android.content.DialogInterface;
+import android.content.Intent;
 import android.content.Loader;
 import android.database.Cursor;
 import android.graphics.Bitmap;
@@ -60,12 +61,14 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
 import android.widget.AdapterView.OnItemLongClickListener;
 import android.widget.ListView;
 
 import com.savoirfairelinux.sflphone.R;
 import com.savoirfairelinux.sflphone.account.AccountSelectionSpinner;
 import com.savoirfairelinux.sflphone.adapters.CallElementAdapter;
+import com.savoirfairelinux.sflphone.client.CallActivity;
 import com.savoirfairelinux.sflphone.client.SFLPhoneHomeActivity;
 import com.savoirfairelinux.sflphone.client.SFLphoneApplication;
 import com.savoirfairelinux.sflphone.client.receiver.AccountListReceiver;
@@ -77,34 +80,59 @@
  */
 public class CallElementListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
     private static final String TAG = CallElementListFragment.class.getSimpleName();
-
-    // private ContactManager mContactManager;
     private CallElementAdapter mAdapter;
     private String mCurFilter;
     private SFLPhoneHomeActivity sflphoneHome;
-    // private SFLphoneApplication sflphoneApplication;
     private ISipService service;
     private AccountSelectionSpinner mAccountSelectionSpinner;
-
     private AccountListReceiver mAccountList;
-
     private boolean isReady = false;
 
     static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { Contacts._ID, Contacts.DISPLAY_NAME, Contacts.PHOTO_ID, Contacts.LOOKUP_KEY };
     static final String[] CONTACTS_PHONES_PROJECTION = new String[] { Phone.NUMBER, Phone.TYPE };
     static final String[] CONTACTS_SIP_PROJECTION = new String[] { SipAddress.SIP_ADDRESS, SipAddress.TYPE };
 
+    private Callbacks mCallbacks = sDummyCallbacks;
+    /**
+     * A dummy implementation of the {@link Callbacks} interface that does nothing. Used only when this fragment is not attached to an activity.
+     */
+    private static Callbacks sDummyCallbacks = new Callbacks() {
+        @Override
+        public void onCallSelected(SipCall c) {
+        }
+
+    };
+
+    /**
+     * The Activity calling this fragment has to implement this interface
+     * 
+     */
+    public interface Callbacks {
+        public void onCallSelected(SipCall c);
+
+    }
+
     @Override
     public void onAttach(Activity activity) {
         super.onAttach(activity);
         sflphoneHome = (SFLPhoneHomeActivity) activity;
         service = ((SFLphoneApplication) sflphoneHome.getApplication()).getSipService();
+        if (!(activity instanceof Callbacks)) {
+            throw new IllegalStateException("Activity must implement fragment's callbacks.");
+        }
+
+        mCallbacks = (Callbacks) activity;
         Log.w(TAG, "onAttach() service=" + service + ", accountList=" + mAccountList);
     }
+    
+    @Override
+    public void onDetach(){
+        super.onDetach();
+        mCallbacks = sDummyCallbacks;
+    }
 
     public String getSelectedAccount() {
-        // return mAccountSelectionButton.getText().toString();
-        return "CIOUCOU";
+        return mAccountSelectionSpinner.getAccount();
     }
 
     /**
@@ -179,10 +207,10 @@
         mAdapter.add(c);
     }
 
-    public void removeCall(SipCall c) {
-        Log.i(TAG, "Removing call " + c.mCallInfo.mDisplayName);
-        mAdapter.remove(c);
-    }
+    // public void removeCall(SipCall c) {
+    // Log.i(TAG, "Removing call " + c.mCallInfo.mDisplayName);
+    // mAdapter.remove(c);
+    // }
 
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
@@ -247,6 +275,25 @@
                 return true;
             }
         });
+
+        lv.setOnItemClickListener(new OnItemClickListener() {
+
+            @Override
+            public void onItemClick(AdapterView<?> arg0, View v, int pos, long arg3) {
+                mCallbacks.onCallSelected((SipCall) mAdapter.getItem(pos));
+
+            }
+
+        });
+    }
+
+    public void launchCallActivity(SipCall call) {
+        Log.i(TAG, "Launch Call Activity");
+        Bundle bundle = new Bundle();
+        bundle.putParcelable("CallInfo", call.mCallInfo);
+        Intent intent = new Intent().setClass(getActivity(), CallActivity.class);
+        intent.putExtras(bundle);
+        getActivity().startActivity(intent);
     }
 
     @Override
@@ -255,9 +302,6 @@
         View inflatedView = inflater.inflate(R.layout.frag_call_element, container, false);
 
         mAccountSelectionSpinner = (AccountSelectionSpinner) inflatedView.findViewById(R.id.account_selection_button);
-//        mAccountList.addManagementUI(mAccountSelectionSpinner);
-//        mAccountSelectionSpinner.setAccountList(mAccountList);
-
         isReady = true;
         if (service != null) {
             onServiceSipBinded(service);
@@ -265,15 +309,6 @@
         return inflatedView;
     }
 
-    public void onListItemClick(ListView l, View v, int position, long id) {
-        // Insert desired behavior here.
-        SipCall call = (SipCall) mAdapter.getItem(position);
-        Log.i(TAG, "Call Clicked: " + call.getCallId());
-
-        call.launchCallActivity(getActivity());
-        sflphoneHome.onSelectedCallAction(call);
-    }
-
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
 
@@ -329,7 +364,6 @@
      */
     public void onServiceSipBinded(ISipService isip) {
 
-        
         if (isReady) {
             service = isip;
             ArrayList<String> accountList;
@@ -343,4 +377,9 @@
 
     }
 
+    public void updateCall(String iD, String newState) {
+        mAdapter.update(iD, newState);
+
+    }
+
 }
diff --git a/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java b/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java
index 888af04..9e4c7c4 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/ContactListFragment.java
@@ -222,7 +222,7 @@
                                 Log.i(TAG, "Selected " + items[item]);
                                 switch (item) {
                                 case 0:
-                                    call.placeCallUpdateUi();
+//                                    call.placeCallUpdateUi();
                                     break;
                                 case 1:
                                     call.sendTextMessage();
diff --git a/src/com/savoirfairelinux/sflphone/model/SipCall.java b/src/com/savoirfairelinux/sflphone/model/SipCall.java
index ad3f49c..c9b6f41 100644
--- a/src/com/savoirfairelinux/sflphone/model/SipCall.java
+++ b/src/com/savoirfairelinux/sflphone/model/SipCall.java
@@ -51,10 +51,7 @@
 {
     final static String TAG = "SipCall";
     public CallInfo mCallInfo;
-    // Update UI on actions (answer, hangup)
-    static private CallElementListFragment mCallElementList = null;
-    static private SFLPhoneHomeActivity mHome = null;
-    private View mRowView = null;
+
 
     public static final int CALL_TYPE_UNDETERMINED = 0;
     public static final int CALL_TYPE_INCOMING = 1;
@@ -139,6 +136,13 @@
             mCallState = in.readInt();
             mMediaState = in.readInt();
         }
+
+        public CallInfo(Intent call) {
+            Bundle b = call.getBundleExtra("com.savoirfairelinux.sflphone.service.newcall");
+            mAccountID = b.getString("AccountID");
+            mCallID = b.getString("CallID");
+            mDisplayName = b.getString("From");
+        }
     }
 
     public SipCall()
@@ -151,20 +155,7 @@
         mCallInfo = info; 
     }
 
-    public static void setCallElementList(CallElementListFragment list)
-    {
-        mCallElementList = list;
-    }
 
-    public static void setSFLPhoneHomeContext(SFLPhoneHomeActivity home)
-    {
-        mHome = home;
-    }
-
-    public void setAssociatedRowView(View view)
-    {
-        mRowView = view;
-    }
 
     public void setCallID(String callID) {
         mCallInfo.mCallID = callID;
@@ -224,15 +215,6 @@
 
     public void setCallState(int callState) {
         mCallInfo.mCallState = callState;
-      
-        // Check if this call is associated to a view in CallElementList 
-        if(mRowView == null)
-            return;
-
-        // Update the state to the view
-        CallElementView entryView = (CallElementView) mRowView.getTag();
-        final String CURRENT_STATE_LABEL = "    CURRENT STATE: ";
-        entryView.state.setText(CURRENT_STATE_LABEL + getCallStateString());
     }
 
     public int getCallStateInt() {
@@ -283,31 +265,7 @@
         return mCallInfo.mMediaState;
     }
 
-    public void placeCallUpdateUi()
-    {
-        if(mCallElementList != null)
-            mCallElementList.addCall(this);
-
-        if(mHome != null)
-            mHome.onSelectedCallAction(this);
-    }
-
-
-    public void receiveCallUpdateUi()
-    {
-        if(mCallElementList != null)
-            mCallElementList.addCall(this); 
-
-        if(mHome != null)
-            mHome.onSelectedCallAction(this);
-    }
-
-    public void answerUpdateUi()
-    {
-        if(mHome != null)
-            mHome.onSelectedCallAction(this);
-        
-    }
+    
 
     public boolean notifyServiceAnswer(ISipService service)
     {
@@ -330,15 +288,15 @@
      * Perform hangup action without sending request to the service
      * Used when SipService haved been notified that this call hung up
      */
-    public void hangupUpdateUi() {
-        Log.i(TAG, "Hangup call " + mCallInfo.mCallID);
-
-        if(mCallElementList != null)
-            mCallElementList.removeCall(this);
-
-        if(mHome != null)
-            mHome.onUnselectedCallAction();
-    }
+//    public void hangupUpdateUi() {
+//        Log.i(TAG, "Hangup call " + mCallInfo.mCallID);
+//
+//        if(mCallElementList != null)
+//            mCallElementList.removeCall(this);
+//
+//        if(mHome != null)
+//            mHome.onUnselectedCallAction();
+//    }
 
     /**
      * Perform hangup action and send request to the service
@@ -432,15 +390,7 @@
         Log.i(TAG, "          Contact: " + mCallInfo.mRemoteContact);
     }
 
-    public void launchCallActivity(Context context)
-    {
-        Log.i(TAG, "Launch Call Activity");
-        Bundle bundle = new Bundle();
-        bundle.putParcelable("CallInfo", mCallInfo);
-        Intent intent = new Intent().setClass(context, CallActivity.class);
-        intent.putExtras(bundle);
-        context.startActivity(intent);
-    }
+
     
     /**
      * Compare sip calls based on call ID
diff --git a/src/com/savoirfairelinux/sflphone/service/ISipClient.aidl b/src/com/savoirfairelinux/sflphone/service/ISipClient.aidl
index 2da24cc..b845f66 100644
--- a/src/com/savoirfairelinux/sflphone/service/ISipClient.aidl
+++ b/src/com/savoirfairelinux/sflphone/service/ISipClient.aidl
@@ -1,5 +1,6 @@
 package com.savoirfairelinux.sflphone.service;
 
 interface ISipClient {
-    void incomingCall();
+    void incomingCall(in Intent call);
+    void callStateChanged(in Intent callState);
 }
\ No newline at end of file
diff --git a/src/com/savoirfairelinux/sflphone/service/SipService.java b/src/com/savoirfairelinux/sflphone/service/SipService.java
index e84562d..6edce10 100644
--- a/src/com/savoirfairelinux/sflphone/service/SipService.java
+++ b/src/com/savoirfairelinux/sflphone/service/SipService.java
@@ -63,7 +63,6 @@
     private ManagerImpl managerImpl;
     private boolean isPjSipStackStarted = false;
     ISipClient client;
-    
 
     /* Implement public interface for the service */
     private final ISipService.Stub mBinder = new ISipService.Stub() {
@@ -137,11 +136,11 @@
         @Override
         public void setAudioPlugin(final String audioPlugin) {
             getExecutor().execute(new SipRunnable() {
-               @Override
-               protected void doRun() throws SameThreadException {
-                   Log.i(TAG, "SipService.setAudioPlugin() thread running...");
-                   configurationManagerJNI.setAudioPlugin(audioPlugin);
-               }
+                @Override
+                protected void doRun() throws SameThreadException {
+                    Log.i(TAG, "SipService.setAudioPlugin() thread running...");
+                    configurationManagerJNI.setAudioPlugin(audioPlugin);
+                }
             });
         }
 
@@ -153,11 +152,13 @@
                     Log.i(TAG, "SipService.getCurrentAudioOutputPlugin() thread running...");
                     return configurationManagerJNI.getCurrentAudioOutputPlugin();
                 }
-            };
+            }
+            ;
 
             CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
             getExecutor().execute(runInstance);
-            while(!runInstance.isDone()) {}
+            while (!runInstance.isDone()) {
+            }
             return (String) runInstance.getVal();
         }
 
@@ -169,36 +170,44 @@
                     Log.i(TAG, "SipService.getAccountList() thread running...");
                     return configurationManagerJNI.getAccountList();
                 }
-            };
+            }
+            ;
             AccountList runInstance = new AccountList();
             getExecutor().execute(runInstance);
-            while(!runInstance.isDone()) {}
+            while (!runInstance.isDone()) {
+            }
             StringVect swigvect = (StringVect) runInstance.getVal();
 
             ArrayList<String> nativelist = new ArrayList<String>();
 
-            for(int i = 0; i < swigvect.size(); i++)
-               nativelist.add(swigvect.get(i));
+            for (int i = 0; i < swigvect.size(); i++)
+                nativelist.add(swigvect.get(i));
 
             return nativelist;
-        } 
+        }
 
         @Override
-        public HashMap<String,String> getAccountDetails(final String accountID) {
+        public HashMap<String, String> getAccountDetails(final String accountID) {
             class AccountDetails extends SipRunnableWithReturn {
                 private String id;
-                AccountDetails(String accountId) { id = accountId; }
+
+                AccountDetails(String accountId) {
+                    id = accountId;
+                }
+
                 @Override
                 protected StringMap doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getAccountDetails() thread running...");
                     return configurationManagerJNI.getAccountDetails(id);
                 }
-            };
+            }
+            ;
 
             AccountDetails runInstance = new AccountDetails(accountID);
             getExecutor().execute(runInstance);
-            while(!runInstance.isDone()) {}
-            StringMap swigmap = (StringMap) runInstance.getVal(); 
+            while (!runInstance.isDone()) {
+            }
+            StringMap swigmap = (StringMap) runInstance.getVal();
 
             HashMap<String, String> nativemap = AccountDetailsHandler.convertSwigToNative(swigmap);
 
@@ -207,7 +216,7 @@
 
         @Override
         public void setAccountDetails(final String accountId, Map map) {
-            HashMap<String,String> nativemap = (HashMap<String,String>) map;
+            HashMap<String, String> nativemap = (HashMap<String, String>) map;
 
             final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig(nativemap);
 
@@ -224,19 +233,25 @@
         public String addAccount(Map map) {
             class AddAccount extends SipRunnableWithReturn {
                 StringMap map;
-                AddAccount(StringMap m) { map = m; }
+
+                AddAccount(StringMap m) {
+                    map = m;
+                }
+
                 @Override
                 protected String doRun() throws SameThreadException {
                     Log.i(TAG, "SipService.getAccountDetails() thread running...");
                     return configurationManagerJNI.addAccount(map);
                 }
-            };
+            }
+            ;
 
-            final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig((HashMap<String,String>)map);
+            final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig((HashMap<String, String>) map);
 
             AddAccount runInstance = new AddAccount(swigmap);
             getExecutor().execute(runInstance);
-            while(!runInstance.isDone()) {}
+            while (!runInstance.isDone()) {
+            }
             String accountId = (String) runInstance.getVal();
 
             return accountId;
@@ -255,30 +270,36 @@
 
         @Override
         public void registerClient(ISipClient callback) throws RemoteException {
-           client = callback;
+            client = callback;
         }
     };
     private BroadcastReceiver IncomingReceiver = new BroadcastReceiver() {
-        
+
         @Override
         public void onReceive(Context context, Intent intent) {
-            Log.i(TAG, "Received"+ intent.getAction());
-         // Get instance of Vibrator from current Context
-//            Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
-//            mVibrator.vibrate(300);
-            if(intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)){
-                try {
-                    client.incomingCall();
-                } catch (RemoteException e) {
-                    Log.e(TAG,e.toString());
+            // Get instance of Vibrator from current Context
+            // Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
+            // mVibrator.vibrate(300);
+            try {
+                if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)) {
+                    Log.i(TAG, "Received" + intent.getAction());
+
+                    client.incomingCall(intent);
+
+                } else if (intent.getAction().contentEquals(CallManagerCallBack.CALL_STATE_CHANGED)) {
+                    Log.i(TAG, "Received" + intent.getAction());
+                    client.callStateChanged(intent);
+                } else if (intent.getAction().contentEquals(CallManagerCallBack.NEW_CALL_CREATED)) {
+                    Log.i(TAG, "Received" + intent.getAction());
                 }
+            } catch (RemoteException e) {
+                Log.e(TAG, e.toString());
             }
         }
     };
 
     /**
-     * Class used for the client Binder.  Because we know this service always
-     * runs in the same process as its clients, we don't need to deal with IPC.
+     * Class used for the client Binder. Because we know this service always runs in the same process as its clients, we don't need to deal with IPC.
      */
     public class LocalBinder extends Binder {
         public SipService getService() {
@@ -287,17 +308,27 @@
         }
     }
 
+    @Override
+    public boolean onUnbind(Intent i) {
+        super.onUnbind(i);
+        Log.i(TAG, "onUnbind(intent)");
+        return false;
+
+    }
+
     /* called once by startService() */
     @Override
     public void onCreate() {
         Log.i(TAG, "onCreated");
         super.onCreate();
+
         sflphoneApp = (SFLphoneApplication) getApplication();
         sipServiceThread = new SipServiceThread();
-        
-        IntentFilter callFilter = new IntentFilter();
+
+        IntentFilter callFilter = new IntentFilter(CallManagerCallBack.CALL_STATE_CHANGED);
         callFilter.addAction(CallManagerCallBack.INCOMING_CALL);
-        LocalBroadcastManager.getInstance(this).registerReceiver(IncomingReceiver , callFilter);
+        callFilter.addAction(CallManagerCallBack.NEW_CALL_CREATED);
+        LocalBroadcastManager.getInstance(this).registerReceiver(IncomingReceiver, callFilter);
         getExecutor().execute(new StartRunnable());
     }
 
@@ -326,7 +357,7 @@
         sflphoneApp.setServiceRunning(false);
         Toast.makeText(this, "Sflphone Service stopped", Toast.LENGTH_SHORT).show();
         super.onDestroy();
-        
+
         Log.i(TAG, "onDestroyed");
     }
 
@@ -337,7 +368,7 @@
     }
 
     private static Looper createLooper() {
-        if(executorThread == null) {
+        if (executorThread == null) {
             Log.d(TAG, "Creating new handler thread");
             // ADT gives a fake warning due to bad parse rule.
             executorThread = new HandlerThread("SipService.Executor");
@@ -447,7 +478,7 @@
         public void run() {
             try {
                 doRun();
-            }catch(SameThreadException e) {
+            } catch (SameThreadException e) {
                 Log.e(TAG, "Not done from same thread");
             }
         }
@@ -470,8 +501,8 @@
         public void run() {
             try {
                 obj = doRun();
-                done = true; 
-            }catch(SameThreadException e) {
+                done = true;
+            } catch (SameThreadException e) {
                 Log.e(TAG, "Not done from same thread");
             }
         }
@@ -485,16 +516,16 @@
     }
 
     private class SipServiceThread extends Thread {
-        
+
         public SipServiceThread() {
             super("sipServiceThread");
         }
-        
+
         @Override
         public void run() {
             Log.i(TAG, "SipService thread running...");
             SipService sipService = SipService.this;
-            while(sipService.runFlag) {
+            while (sipService.runFlag) {
                 try {
                     Thread.sleep(DELAY);
                 } catch (InterruptedException e) {