#15162: make incoming call from java UI
#14371: Add logger.h in opensllayer.cpp
#14371: Use Android Logging system
Merge branch 'master' of git+ssh://git.sflphone.org/var/repos/sflphone/git/sflphone into android
#14371: Add delay in capture callback
diff --git a/jni/sflphone b/jni/sflphone
index d500229..da2080f 160000
--- a/jni/sflphone
+++ b/jni/sflphone
@@ -1 +1 @@
-Subproject commit d5002296adff02e18e99c9b0c9fade39ad5f862b
+Subproject commit da2080f4b867155ac668e01abe14f54fbcb2016f
diff --git a/res/drawable-hdpi/ic_incomingcall.png b/res/drawable-hdpi/ic_incomingcall.png
new file mode 100644
index 0000000..999f437
--- /dev/null
+++ b/res/drawable-hdpi/ic_incomingcall.png
Binary files differ
diff --git a/res/drawable-ldpi/ic_incomingcall.png b/res/drawable-ldpi/ic_incomingcall.png
new file mode 100644
index 0000000..273f105
--- /dev/null
+++ b/res/drawable-ldpi/ic_incomingcall.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_incomingcall.png b/res/drawable-mdpi/ic_incomingcall.png
new file mode 100644
index 0000000..fb62521
--- /dev/null
+++ b/res/drawable-mdpi/ic_incomingcall.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_incomingcall.png b/res/drawable-xhdpi/ic_incomingcall.png
new file mode 100644
index 0000000..d0eb07d
--- /dev/null
+++ b/res/drawable-xhdpi/ic_incomingcall.png
Binary files differ
diff --git a/res/layout/test_layout.xml b/res/layout/test_layout.xml
index 47411bb..391ee56 100644
--- a/res/layout/test_layout.xml
+++ b/res/layout/test_layout.xml
@@ -113,6 +113,16 @@
         android:onClick="onClick"
         android:src="@drawable/ic_hangup" />
 
+    <ImageButton
+        android:id="@+id/buttonIncomingCall"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight=".5"
+        android:gravity="center_vertical"
+        android:onClick="onClick"
+        android:src="@drawable/ic_incomingcall"
+        android:background="@drawable/hangup_button"
+        android:drawable="@drawable/hangup_button" />
     </LinearLayout>
 
 <!--         android:background="@drawable/custom_button" -->
diff --git a/src/com/savoirfairelinux/sflphone/client/ButtonSectionFragment.java b/src/com/savoirfairelinux/sflphone/client/ButtonSectionFragment.java
index a1bf70f..74de208 100644
--- a/src/com/savoirfairelinux/sflphone/client/ButtonSectionFragment.java
+++ b/src/com/savoirfairelinux/sflphone/client/ButtonSectionFragment.java
@@ -8,6 +8,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.Button;
+import android.widget.ImageButton;
 import android.widget.TextView;
 
 import com.savoirfairelinux.sflphone.R;
@@ -17,6 +18,7 @@
 		static final String TAG = "ButtonSectionFragment";
 		private TextView callVoidText, NewDataText, DataStringText;
 		Button buttonCallVoid, buttonGetNewData, buttonGetDataString;
+		ImageButton buttonCall, buttonIncomingCall, buttonHangUp;
 
 		public ButtonSectionFragment()
 		{
@@ -34,7 +36,19 @@
 		public TextView getDataStringText() {
 			return DataStringText;
 		}
+		
+		public ImageButton getCallButton() {
+			return buttonCall;
+		}
 
+		public ImageButton getIncomingCallButton() {
+			return buttonIncomingCall;
+		}
+		
+		public ImageButton getHangUpButton() {
+			return buttonHangUp;
+		}
+		
 		public static final String ARG_SECTION_NUMBER = "section_number";
 
 		@Override
@@ -52,13 +66,16 @@
 
 		    DataStringText = (TextView) view.findViewById(R.id.DataString_text);
 		    buttonGetDataString = (Button) view.findViewById(R.id.buttonGetDataString);
-			
+			buttonCall = (ImageButton) view.findViewById(R.id.buttonCall);
+			buttonHangUp = (ImageButton) view.findViewById(R.id.buttonHangUp);
+
 		    try {
 				inflater.inflate(R.layout.test_layout, parent, false);
 			} catch (InflateException e) {
 				Log.e(TAG, "Error inflating test_layout ", e);
 				return null;
 			}
+
 			return view;
 		}
 }
\ No newline at end of file
diff --git a/src/com/savoirfairelinux/sflphone/client/ManagerImpl.java b/src/com/savoirfairelinux/sflphone/client/ManagerImpl.java
index 50fd15a..ab4cb84 100644
--- a/src/com/savoirfairelinux/sflphone/client/ManagerImpl.java
+++ b/src/com/savoirfairelinux/sflphone/client/ManagerImpl.java
@@ -4,17 +4,38 @@
 import android.os.Bundle;
 import android.os.Message;
 import android.util.Log;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.LinearInterpolator;
+import android.widget.ImageButton;
+
+import com.savoirfairelinux.sflphone.R;
 
 public class ManagerImpl {
 	
 	private static final String TAG = "ManagerImpl";
 	private static int sipLogLevel = 6;
 	static Handler h;
+	private static ButtonSectionFragment buttonSecFragment;
 	static String appPath;
+	static Animation animation;
+	static SFLPhoneHome uiThread;
+	static ImageButton buttonCall;
 	
 	public ManagerImpl () {}
 	
-	public ManagerImpl(Handler h) {
+	public ManagerImpl(Handler h) {		
+		// Change alpha from fully visible to invisible
+	    animation = new AlphaAnimation(1, 0);
+	    // duration - half a second
+	    animation.setDuration(500);
+	    // do not alter animation rate
+	    animation.setInterpolator(new LinearInterpolator());
+	    // Repeat animation infinitely
+	    animation.setRepeatCount(Animation.INFINITE);
+	    // Reverse
+	    animation.setRepeatMode(Animation.REVERSE);
+	    
 		this.h = h;
 	}
 	
@@ -27,6 +48,34 @@
 		m.setTarget(h);
 		m.sendToTarget();
 	}
+	
+	public static void incomingCall(String accountID, String callID, String from) {
+		Log.i(TAG, "incomingCall(" + accountID + ", " + callID + ", " + from + ")");
+		buttonCall = (ImageButton) buttonSecFragment.getCallButton();
+		
+		// FIXME that's ugly...
+		uiThread.runOnUiThread(new Runnable() {
+		     public void run() {
+		 		try {
+					buttonCall.startAnimation(animation);
+					buttonCall.setImageResource(R.drawable.ic_incomingcall);
+				} catch (Exception e) {
+					Log.w(TAG, "exception in runOnUiThread ", e);
+				}
+		    }
+		});
+
+		uiThread.setIncomingCallID(callID);
+	}
+	
+	// FIXME
+	public static void setButtonFragment(ButtonSectionFragment f) {
+		buttonSecFragment = f;
+	}
+	
+	public static void setActivity(SFLPhoneHome a) {
+		uiThread = a;
+	}
 
 	public static String getAppPath() {
 		return appPath;
@@ -49,4 +98,6 @@
 	public static native void initN(String config_file);
 	public static native void placeCall(String accountID, String callID, String to);
 	public static native void hangUp(String callID);
+	public static native void answerCall(String callID);
+	public static native void refuseCall(String callID);
 }
diff --git a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHome.java b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHome.java
index 8c2e8e2..27172fa 100644
--- a/src/com/savoirfairelinux/sflphone/client/SFLPhoneHome.java
+++ b/src/com/savoirfairelinux/sflphone/client/SFLPhoneHome.java
@@ -52,7 +52,9 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.ViewGroup;
-import android.widget.Button;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.LinearInterpolator;
 import android.widget.EditText;
 import android.widget.ImageButton;
 import android.widget.TextView;
@@ -63,13 +65,14 @@
 {
 	SectionsPagerAdapter mSectionsPagerAdapter;
 	static final String TAG = "SFLPhoneHome";
-	ButtonSectionFragment buttonFragment;
+	private ButtonSectionFragment buttonFragment;
 	ImageButton buttonCall, buttonHangup;
 	Handler callbackHandler;
 	static ManagerImpl managerImpl;
 	/* default callID */
 	static String callID = "007";
 	static boolean callOnGoing = false;
+	private String incomingCallID = "";
 
 	/**
 	 * The {@link ViewPager} that will host the section contents.
@@ -131,7 +134,12 @@
 		};
 		ManagerImpl.setAppPath(getAppPath());
 		managerImpl = new ManagerImpl(callbackHandler);
+		managerImpl.setActivity(this);
 		Log.i(TAG, "managerImpl created with callbackHandler " + callbackHandler);
+
+		buttonCall = (ImageButton) findViewById(R.id.buttonCall);
+		buttonHangup = (ImageButton) findViewById(R.id.buttonHangUp);
+//		buttonIncomingCall = (ImageButton) findViewById(R.id.buttonIncomingCall);
 	}
 
 	// FIXME
@@ -178,6 +186,10 @@
 //		ManagerImpl.initN("");
 	}
 
+	public void setIncomingCallID(String id) {
+		incomingCallID = id;
+	}
+	
 	/**
 	 * A {@link FragmentStatePagerAdapter} that returns a fragment corresponding to
 	 * one of the primary sections of the app.
@@ -206,6 +218,7 @@
 				buttonFragment = new ButtonSectionFragment();
 				Log.i(TAG, "getItem: fragment is " + buttonFragment);
 				fragment = buttonFragment;
+				managerImpl.setButtonFragment(buttonFragment);
 				break;
 			default:
 				Log.e(TAG, "getItem: unknown tab position " + i);
@@ -285,9 +298,9 @@
 	@Override
     public void onClick(View view)
     {
-		buttonCall = (ImageButton) findViewById(R.id.buttonCall);
-		buttonHangup = (ImageButton) findViewById(R.id.buttonHangUp);
-				
+		buttonCall = buttonFragment.getCallButton();
+		buttonHangup = buttonFragment.getHangUpButton();
+		
     	switch (view.getId()) {
     	case R.id.buttonCall:
     		TextView textView = (TextView) findViewById(R.id.editAccountID);
@@ -295,32 +308,52 @@
     		EditText editText;
     		Random random = new Random();
 
-    		if (callOnGoing == false) {
-    			editText = (EditText) findViewById(R.id.editTo);
-    			String to = editText.getText().toString();
-    			if (to == null) {
-    				Log.e(TAG, "to string is " + to);
-    				break;
-    			}
-
-    			/* new random callID */
-    			callID = Integer.toString(random.nextInt());
-
-    			Log.d(TAG, "ManagerImpl.placeCall(" + accountID + ", " + callID + ", " + to + ");");
-    			ManagerImpl.placeCall(accountID, callID, to);
+    		if (incomingCallID != "") {
+    			buttonCall.clearAnimation();
+    			ManagerImpl.answerCall(incomingCallID);
+    			callID = incomingCallID;
+    			incomingCallID="";
     			callOnGoing = true;
-    			buttonCall.setEnabled(false);
-    			buttonHangup.setEnabled(true);
+				buttonCall.setEnabled(false);
+				buttonHangup.setEnabled(true);
+    		} else {
+    			if (callOnGoing == false) {
+    				editText = (EditText) findViewById(R.id.editTo);
+    				String to = editText.getText().toString();
+    				if (to == null) {
+    					Log.e(TAG, "to string is " + to);
+    					break;
+    				}
+
+    				/* new random callID */
+    				callID = Integer.toString(random.nextInt());
+
+    				Log.d(TAG, "ManagerImpl.placeCall(" + accountID + ", " + callID + ", " + to + ");");
+    				ManagerImpl.placeCall(accountID, callID, to);
+    				callOnGoing = true;
+    				buttonCall.setEnabled(false);
+    				buttonHangup.setEnabled(true);
+    			}
     		}
         	break;
     	case R.id.buttonHangUp:
-    		if (callOnGoing == true) {
-    			Log.d(TAG, "ManagerImpl.hangUp(" + callID + ");");
-    			ManagerImpl.hangUp(callID);
-    			callOnGoing = false;
-    			buttonCall.setEnabled(true);
-    			buttonHangup.setEnabled(false);
+    		if (incomingCallID != "") {
+    			buttonCall.clearAnimation();
+    			ManagerImpl.refuseCall(incomingCallID);
+    			incomingCallID="";
+				buttonCall.setEnabled(true);
+				buttonHangup.setEnabled(true);
+    		} else {
+    			if (callOnGoing == true) {
+    				Log.d(TAG, "ManagerImpl.hangUp(" + callID + ");");
+    				ManagerImpl.hangUp(callID);
+    				callOnGoing = false;
+    				buttonCall.setEnabled(true);
+    				buttonHangup.setEnabled(false);
+    			}
     		}
+
+			buttonCall.setImageResource(R.drawable.ic_call);
     		break;
     	case R.id.buttonInit:
     		ManagerImpl.initN("");