* #24121 First integration of IM working
diff --git a/src/com/savoirfairelinux/sflphone/client/CallActivity.java b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
index a35e307..e5feab3 100644
--- a/src/com/savoirfairelinux/sflphone/client/CallActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/CallActivity.java
@@ -234,4 +234,14 @@
         
     }
 
+    public void onRecordCall() {
+        mCall.notifyServiceRecord(service);
+        
+    }
+
+    public void onSendMessage(String msg) {
+        mCall.notifyServiceSendMsg(service,msg);
+        
+    }
+
 }
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
index bbd7363..dd1a746 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHomeActivity.java
@@ -30,6 +30,8 @@
  */
 package com.savoirfairelinux.sflphone.client;
 
+import java.io.ObjectInputStream.GetField;
+
 import android.app.ActionBar;
 import android.app.Activity;
 import android.app.Fragment;
@@ -48,6 +50,7 @@
 import android.view.Menu;
 import android.view.MenuItem;
 import android.widget.ImageButton;
+import android.widget.Toast;
 
 import com.savoirfairelinux.sflphone.R;
 import com.savoirfairelinux.sflphone.fragments.CallElementListFragment;
@@ -272,6 +275,16 @@
                 mCallElementList.updateCall(cID, state);
 
             }
+
+            @Override
+            public void incomingText(Intent msg) throws RemoteException {
+                Bundle b = msg.getBundleExtra("com.savoirfairelinux.sflphone.service.newtext");
+                b.getString("CallID");
+                String from = b.getString("From");
+                String mess = b.getString("Msg");
+                Toast.makeText(getApplicationContext(), "text from "+from+" : " + mess , Toast.LENGTH_LONG).show();
+                
+            }
         };
 
         @Override
diff --git a/src/com/savoirfairelinux/sflphone/fragments/AccountManagementFragment.java b/src/com/savoirfairelinux/sflphone/fragments/AccountManagementFragment.java
index 5435c8b..3adf846 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/AccountManagementFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/AccountManagementFragment.java
@@ -41,6 +41,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Bundle;
+import android.os.Environment;
 import android.os.RemoteException;
 import android.preference.Preference;
 import android.preference.PreferenceCategory;
diff --git a/src/com/savoirfairelinux/sflphone/fragments/OngoingCallFragment.java b/src/com/savoirfairelinux/sflphone/fragments/OngoingCallFragment.java
index dca9117..90eae4d 100644
--- a/src/com/savoirfairelinux/sflphone/fragments/OngoingCallFragment.java
+++ b/src/com/savoirfairelinux/sflphone/fragments/OngoingCallFragment.java
@@ -5,109 +5,115 @@
 import android.os.Bundle;
 import android.view.LayoutInflater;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.View.OnClickListener;
+import android.view.ViewGroup;
 import android.widget.Button;
 import android.widget.EditText;
 import android.widget.TextView;
 
 import com.savoirfairelinux.sflphone.R;
 import com.savoirfairelinux.sflphone.client.CallActivity;
-import com.savoirfairelinux.sflphone.client.CallActivity.CallFragment;
 import com.savoirfairelinux.sflphone.model.SipCall;
 
-public class OngoingCallFragment extends Fragment implements CallActivity.CallFragment, OnClickListener
-{
-	private CallActivity listener;
-	private Button end_btn, suspend_btn;
-	private TextView callstatus_txt;
-	private TextView calllength_txt;
-	private TextView contact_name_txt;
+public class OngoingCallFragment extends Fragment implements CallActivity.CallFragment, OnClickListener {
+    private CallActivity listener;
+    private Button end_btn, suspend_btn;
+    private TextView callstatus_txt;
+    private TextView calllength_txt;
+    private TextView contact_name_txt;
 
-	private SipCall mCall = null;
+    private SipCall mCall = null;
 
-	public void setCall(SipCall call)
-	{
-		mCall = call;
-		if(isAdded())
-			updateUI();
-	}
+    public void setCall(SipCall call) {
+        mCall = call;
+        if (isAdded())
+            updateUI();
+    }
 
-	EditText transfer_txt;
-	@Override
-	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
-	{
-		ViewGroup v = (ViewGroup) inflater.inflate(R.layout.frag_call_ongoing, container, false);
-		
-		transfer_txt = (EditText) v.findViewById(R.id.text_transfer);
-		contact_name_txt = (TextView) v.findViewById(R.id.contact_name_txt);
-		end_btn = (Button) v.findViewById(R.id.end_btn);
-		suspend_btn = (Button) v.findViewById(R.id.suspend_btn);
-		Button transfer_btn = (Button) v.findViewById(R.id.transfer);
-		transfer_btn.setOnClickListener(new OnClickListener() {
-            
+    EditText transfer_txt, msg_txt;
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
+        ViewGroup v = (ViewGroup) inflater.inflate(R.layout.frag_call_ongoing, container, false);
+
+        transfer_txt = (EditText) v.findViewById(R.id.text_transfer);
+        msg_txt = (EditText) v.findViewById(R.id.text_message);
+        contact_name_txt = (TextView) v.findViewById(R.id.contact_name_txt);
+        end_btn = (Button) v.findViewById(R.id.end_btn);
+        suspend_btn = (Button) v.findViewById(R.id.suspend_btn);
+
+        ((Button) v.findViewById(R.id.transfer)).setOnClickListener(new OnClickListener() {
+
             @Override
             public void onClick(View v) {
                 listener.onCalltransfered(transfer_txt.getText().toString());
-                    
-                
+
             }
         });
-		
-		
-		
-		callstatus_txt = (TextView) v.findViewById(R.id.callstatus_txt);
-		calllength_txt = (TextView) v.findViewById(R.id.calllength_txt);
 
-		end_btn.setOnClickListener(this);
-		suspend_btn.setOnClickListener(this);
-		
-		updateUI();
-		return v;
-	}
+        ((Button) v.findViewById(R.id.record_call)).setOnClickListener(new OnClickListener() {
 
-	private void updateUI()
-	{
-		if (mCall == null)
-			return;
-		contact_name_txt.setText(mCall.getDisplayName());
-		callstatus_txt.setText(mCall.getCallStateString());
-		
-		int state = mCall.getCallStateInt();
-		if(state == SipCall.CALL_STATE_HOLD) {
-			suspend_btn.setText("Resume");
-		} else {
-			suspend_btn.setText("Suspend");
-		}
-		/*
-		switch(mCall.getCallStateInt()) {
-		case SipCall.CALL_STATE_HOLD:
-			suspend_btn.setText("Resume");
-			break;
-		case SipCall.CALL_STATE_HOLD:
-			suspend_btn.setText("Resume");
-			break;
+            @Override
+            public void onClick(View v) {
+                listener.onRecordCall();
 
-		}*/
-	}
+            }
+        });
+        
+        ((Button) v.findViewById(R.id.send_msg)).setOnClickListener(new OnClickListener() {
 
-	@Override
-	public void onAttach(Activity activity)
-	{
-		super.onAttach(activity);
-		listener = (CallActivity) activity;
-	}
+            @Override
+            public void onClick(View v) {
+                listener.onSendMessage(msg_txt.getText().toString());
 
-	@Override
-	public void onClick(View v)
-	{
-		if (v == end_btn) {
-			listener.onCallEnded();
-		} else if (v == suspend_btn) {
-			if(mCall.getCallStateInt() == SipCall.CALL_STATE_HOLD)
-				listener.onCallResumed();
-			else
-				listener.onCallSuspended();
-		}
-	}
+            }
+        });
+
+        callstatus_txt = (TextView) v.findViewById(R.id.callstatus_txt);
+        calllength_txt = (TextView) v.findViewById(R.id.calllength_txt);
+
+        end_btn.setOnClickListener(this);
+        suspend_btn.setOnClickListener(this);
+
+        updateUI();
+        return v;
+    }
+
+    private void updateUI() {
+        if (mCall == null)
+            return;
+        contact_name_txt.setText(mCall.getDisplayName());
+        callstatus_txt.setText(mCall.getCallStateString());
+
+        int state = mCall.getCallStateInt();
+        if (state == SipCall.CALL_STATE_HOLD) {
+            suspend_btn.setText("Resume");
+        } else {
+            suspend_btn.setText("Suspend");
+        }
+        /*
+         * switch(mCall.getCallStateInt()) { case SipCall.CALL_STATE_HOLD: suspend_btn.setText("Resume"); break; case SipCall.CALL_STATE_HOLD:
+         * suspend_btn.setText("Resume"); break;
+         * 
+         * }
+         */
+    }
+
+    @Override
+    public void onAttach(Activity activity) {
+        super.onAttach(activity);
+        listener = (CallActivity) activity;
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v == end_btn) {
+            listener.onCallEnded();
+        } else if (v == suspend_btn) {
+            if (mCall.getCallStateInt() == SipCall.CALL_STATE_HOLD)
+                listener.onCallResumed();
+            else
+                listener.onCallSuspended();
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/com/savoirfairelinux/sflphone/model/SipCall.java b/src/com/savoirfairelinux/sflphone/model/SipCall.java
index caad658..fcd826e 100644
--- a/src/com/savoirfairelinux/sflphone/model/SipCall.java
+++ b/src/com/savoirfairelinux/sflphone/model/SipCall.java
@@ -34,6 +34,7 @@
 
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Environment;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.RemoteException;
@@ -406,4 +407,28 @@
             Log.e(TAG, "Cannot call service method", e);
         } 
     }
+
+    public void notifyServiceRecord(ISipService service) {
+        try {
+            if(getCallStateInt() == CALL_STATE_CURRENT) {
+                service.setRecordPath(Environment.getExternalStorageDirectory().getAbsolutePath());
+                Log.w(TAG,"Recording path"+service.getRecordPath());
+                service.setRecordingCall(mCallInfo.mCallID);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Cannot call service method", e);
+        } 
+        
+    }
+
+    public void notifyServiceSendMsg(ISipService service,String msg) {
+        try {
+            if(getCallStateInt() == CALL_STATE_CURRENT) {
+                service.sendTextMessage(mCallInfo.mCallID, msg, mCallInfo.mDisplayName);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Cannot call service method", e);
+        } 
+        
+    }
 }
diff --git a/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java b/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
index 921997b..c0390e3 100644
--- a/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
+++ b/src/com/savoirfairelinux/sflphone/service/CallManagerCallBack.java
@@ -15,6 +15,7 @@
     static public final String NEW_CALL_CREATED = "new-call-created"; 
     static public final String CALL_STATE_CHANGED = "call-state-changed";
     static public final String INCOMING_CALL = "incoming-call";
+    static public final String INCOMING_TEXT = "incoming-text";
 
     public CallManagerCallBack(Context context) {
         mContext = context;
@@ -49,6 +50,12 @@
     }
     
     @Override
+    public void on_incoming_message(String ID, String from, String msg){
+        Log.w(TAG,"on_incoming_message:"+msg);
+        sendIncomingTextMessage(ID, from, msg);
+    }
+    
+    @Override
     public void on_conference_removed(String confID){
         Log.w(TAG,"CONFERENCE REMOVED:"+confID);
     }
@@ -89,4 +96,17 @@
         intent.putExtra("com.savoirfairelinux.sflphone.service.newcall", bundle);
         LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
     }
+    
+    private void sendIncomingTextMessage(String id, String from, String msg) {
+        Bundle bundle = new Bundle();
+
+        bundle.putString("CallID", id);
+        bundle.putString("From", from);
+        bundle.putString("Msg", msg);
+        Intent intent = new Intent(INCOMING_TEXT);
+        intent.putExtra(SIGNAL_NAME, INCOMING_TEXT); 
+        intent.putExtra("com.savoirfairelinux.sflphone.service.newtext", bundle);
+        LocalBroadcastManager.getInstance(mContext).sendBroadcast(intent);
+        
+    }
 }
diff --git a/src/com/savoirfairelinux/sflphone/service/ConfigurationManagerJNI.java b/src/com/savoirfairelinux/sflphone/service/ConfigurationManagerJNI.java
index 765a8bf..310e5d8 100644
--- a/src/com/savoirfairelinux/sflphone/service/ConfigurationManagerJNI.java
+++ b/src/com/savoirfairelinux/sflphone/service/ConfigurationManagerJNI.java
@@ -199,6 +199,10 @@
     SFLPhoneserviceJNI.ConfigurationManagerJNI_setIsAlwaysRecording(swigCPtr, this, rec);
   }
 
+  public void setRecordingCall(String id) {
+    SFLPhoneserviceJNI.ConfigurationManagerJNI_setRecordingCall(swigCPtr, this, id);
+  }
+
   public SWIGTYPE_p_int32_t getHistoryLimit() {
     return new SWIGTYPE_p_int32_t(SFLPhoneserviceJNI.ConfigurationManagerJNI_getHistoryLimit(swigCPtr, this), true);
   }
diff --git a/src/com/savoirfairelinux/sflphone/service/ISipClient.aidl b/src/com/savoirfairelinux/sflphone/service/ISipClient.aidl
index b845f66..068b2c1 100644
--- a/src/com/savoirfairelinux/sflphone/service/ISipClient.aidl
+++ b/src/com/savoirfairelinux/sflphone/service/ISipClient.aidl
@@ -3,4 +3,5 @@
 interface ISipClient {
     void incomingCall(in Intent call);
     void callStateChanged(in Intent callState);
+    void incomingText(in Intent msg);
 }
\ No newline at end of file
diff --git a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
index eb76ffb..2450f97 100644
--- a/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
+++ b/src/com/savoirfairelinux/sflphone/service/ISipService.aidl
@@ -17,8 +17,18 @@
     void setAccountDetails(in String accountId, in Map accountDetails);
     void setAudioPlugin(in String callID);
     String getCurrentAudioOutputPlugin();
+    
+    /* History */
     List getHistory();
     
+    /* Recording */
+    void setRecordPath(in String path);
+    String getRecordPath();
+    void setRecordingCall(in String id);
+    
+    /* IM */
+    void sendTextMessage(in String callID, in String message, in String from);
+    
     void registerClient(in ISipClient callback);
     
     void transfer(in String callID, in String to);
diff --git a/src/com/savoirfairelinux/sflphone/service/SipService.java b/src/com/savoirfairelinux/sflphone/service/SipService.java
index ef04a4c..03b5233 100644
--- a/src/com/savoirfairelinux/sflphone/service/SipService.java
+++ b/src/com/savoirfairelinux/sflphone/service/SipService.java
@@ -66,7 +66,7 @@
     private ManagerImpl managerImpl;
     private boolean isPjSipStackStarted = false;
     ISipClient client;
-    
+
     int clients = 0;
 
     private BroadcastReceiver IncomingReceiver = new BroadcastReceiver() {
@@ -79,13 +79,14 @@
                 try {
                     if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED)) {
                         Log.i(TAG, "Received" + intent.getAction());
-                    }else if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNTS_LOADED)) {
+                    } else if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNTS_LOADED)) {
                         Log.i(TAG, "Received" + intent.getAction());
-                    }else if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNTS_CHANGED)) {
+                    } else if (intent.getAction().contentEquals(ConfigurationManagerCallback.ACCOUNTS_CHANGED)) {
                         Log.i(TAG, "Received" + intent.getAction());
-                    }
-
-                    if (intent.getAction().contentEquals(CallManagerCallBack.INCOMING_CALL)) {
+                    } else if(intent.getAction().contentEquals(CallManagerCallBack.INCOMING_TEXT)) {
+                        Log.i(TAG, "Received" + intent.getAction());
+                        client.incomingText(intent);
+                    } else 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)) {
@@ -127,7 +128,8 @@
         callFilter.addAction(ConfigurationManagerCallback.ACCOUNT_STATE_CHANGED);
         callFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_CHANGED);
         callFilter.addAction(ConfigurationManagerCallback.ACCOUNTS_LOADED);
-        
+        callFilter.addAction(CallManagerCallBack.INCOMING_TEXT);
+
         LocalBroadcastManager.getInstance(this).registerReceiver(IncomingReceiver, callFilter);
         getExecutor().execute(new StartRunnable());
     }
@@ -438,7 +440,7 @@
             CurrentAudioPlugin runInstance = new CurrentAudioPlugin();
             getExecutor().execute(runInstance);
             while (!runInstance.isDone()) {
-                Log.e(TAG,"Waiting for Nofing");
+                Log.e(TAG, "Waiting for Nofing");
             }
             return (String) runInstance.getVal();
         }
@@ -456,7 +458,7 @@
             AccountList runInstance = new AccountList();
             getExecutor().execute(runInstance);
             while (!runInstance.isDone()) {
-                Log.e(TAG,"Waiting for Nofing");
+                Log.e(TAG, "Waiting for Nofing");
             }
             StringVect swigvect = (StringVect) runInstance.getVal();
 
@@ -488,7 +490,7 @@
             getExecutor().execute(runInstance);
             clients++;
             while (!runInstance.isDone()) {
-                Log.e(TAG,"Waiting for Details "+clients);
+                Log.w(TAG, "Waiting for Details " + clients);
             }
             clients--;
             StringMap swigmap = (StringMap) runInstance.getVal();
@@ -528,14 +530,13 @@
                     return configurationManagerJNI.addAccount(map);
                 }
             }
-            
 
             final StringMap swigmap = AccountDetailsHandler.convertFromNativeToSwig((HashMap<String, String>) map);
 
             AddAccount runInstance = new AddAccount(swigmap);
             getExecutor().execute(runInstance);
             while (!runInstance.isDone()) {
-                Log.e(TAG,"Waiting for Nofing");
+                Log.e(TAG, "Waiting for Nofing");
             }
             String accountId = (String) runInstance.getVal();
 
@@ -573,7 +574,7 @@
             History runInstance = new History();
             getExecutor().execute(runInstance);
             while (!runInstance.isDone()) {
-                Log.e(TAG,"Waiting for Nofing");
+                Log.w(TAG, "Waiting for getHistory");
             }
             VectMap swigmap = (VectMap) runInstance.getVal();
 
@@ -759,7 +760,7 @@
             ConfList runInstance = new ConfList();
             getExecutor().execute(runInstance);
             while (!runInstance.isDone()) {
-                Log.e(TAG,"Waiting for Nofing");
+                Log.w(TAG, "Waiting for getConferenceList");
             }
             StringVect swigvect = (StringVect) runInstance.getVal();
 
@@ -789,5 +790,61 @@
             return null;
         }
 
+        @Override
+        public String getRecordPath() throws RemoteException {
+            class RecordPath extends SipRunnableWithReturn {
+
+                @Override
+                protected String doRun() throws SameThreadException {
+                    Log.i(TAG, "SipService.getRecordPath() thread running...");
+                    return configurationManagerJNI.getRecordPath();
+                }
+            }
+
+            RecordPath runInstance = new RecordPath();
+            getExecutor().execute(runInstance);
+            while (!runInstance.isDone()) {
+                Log.w(TAG, "Waiting for getRecordPath");
+            }
+            String path = (String) runInstance.getVal();
+
+            return path;
+        }
+
+        @Override
+        public void setRecordingCall(final String id) throws RemoteException {
+            getExecutor().execute(new SipRunnable() {
+                @Override
+                protected void doRun() throws SameThreadException, RemoteException {
+                    Log.i(TAG, "SipService.setRecordingCall() thread running...");
+                    callManagerJNI.setRecordingCall(id);
+                }
+            });
+
+        }
+
+        @Override
+        public void setRecordPath(final String path) throws RemoteException {
+            getExecutor().execute(new SipRunnable() {
+                @Override
+                protected void doRun() throws SameThreadException, RemoteException {
+                    Log.i(TAG, "SipService.setRecordingCall() thread running...");
+                    configurationManagerJNI.setRecordPath(path);
+                }
+            });
+        }
+
+        @Override
+        public void sendTextMessage(final String callID, final String message, final String from) throws RemoteException {
+            getExecutor().execute(new SipRunnable() {
+                @Override
+                protected void doRun() throws SameThreadException, RemoteException {
+                    Log.i(TAG, "SipService.sendTextMessage() thread running...");
+                    callManagerJNI.sendTextMessage(callID, message, from);
+                }
+            });
+
+        }
+
     };
 }