Dynamic video with asking dependings on the settings + linphone submodule updated

This commit is contained in:
Sylvain Berfini 2012-03-08 16:04:20 +01:00
parent b98ab90412
commit 29381534cd
5 changed files with 142 additions and 36 deletions

View file

@ -227,6 +227,10 @@
<string name="media_encryption_srtp">SRTP</string> <string name="media_encryption_srtp">SRTP</string>
<string name="media_encryption_zrtp">ZRTP</string> <string name="media_encryption_zrtp">ZRTP</string>
<string name="dynamic_video_asking">Your correspondent would like to switch to video</string>
<string name="dynamic_video_accept">Accept video</string>
<string name="dynamic_video_deny">Deny video</string>
<string name="pref_extra_accounts">pref_nb_accounts_extra</string> <string name="pref_extra_accounts">pref_nb_accounts_extra</string>
<string name="pref_default_account">pref_default_account</string> <string name="pref_default_account">pref_default_account</string>
<string name="pref_sipaccounts">SIP Accounts</string> <string name="pref_sipaccounts">SIP Accounts</string>

View file

@ -29,9 +29,11 @@ import java.util.List;
import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener; import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener;
import org.linphone.LinphoneSimpleListener.LinphoneOnCallEncryptionChangedListener; import org.linphone.LinphoneSimpleListener.LinphoneOnCallEncryptionChangedListener;
import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener;
import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCallParams;
import org.linphone.core.LinphoneCore.MediaEncryption; import org.linphone.core.LinphoneCore.MediaEncryption;
import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreException;
import org.linphone.core.Log; import org.linphone.core.Log;
@ -44,6 +46,7 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler; import android.os.Handler;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -63,6 +66,7 @@ import android.widget.Toast;
*/ */
public class IncallActivity extends AbstractCalleesActivity implements public class IncallActivity extends AbstractCalleesActivity implements
LinphoneOnAudioChangedListener, LinphoneOnAudioChangedListener,
LinphoneOnCallStateChangedListener,
LinphoneOnCallEncryptionChangedListener, LinphoneOnCallEncryptionChangedListener,
Comparator<LinphoneCall>, Comparator<LinphoneCall>,
OnLongClickListener, OnLongClickListener,
@ -73,12 +77,23 @@ public class IncallActivity extends AbstractCalleesActivity implements
private static final int numpadDialogId = 1; private static final int numpadDialogId = 1;
private static final int addCallId = 1; private static final int addCallId = 1;
private static final int transferCallId = 2; private static final int transferCallId = 2;
private static final int promptVideoId = 3;
private static IncallActivity instance;
private CountDownTimer timer;
public static boolean active; public static boolean active;
@Override protected void setActive(boolean a) {active = a;} @Override protected void setActive(boolean a) {active = a;}
@Override protected boolean isActive() {return active;} @Override protected boolean isActive() {return active;}
public static boolean isReady() {
return instance!=null;
}
static IncallActivity instance() {
if (isReady()) return instance;
return null;
}
private void pauseCurrentCallOrLeaveConference() { private void pauseCurrentCallOrLeaveConference() {
LinphoneCall call = lc().getCurrentCall(); LinphoneCall call = lc().getCurrentCall();
if (call != null && !call.isInConference()) { if (call != null && !call.isInConference()) {
@ -99,7 +114,8 @@ public class IncallActivity extends AbstractCalleesActivity implements
return; return;
} }
setContentView(R.layout.incall_layout); setContentView(R.layout.incall_layout);
instance = this;
mAllowTransfers = getResources().getBoolean(R.bool.allow_transfers); mAllowTransfers = getResources().getBoolean(R.bool.allow_transfers);
findViewById(R.id.addCall).setOnClickListener(this); findViewById(R.id.addCall).setOnClickListener(this);
@ -117,8 +133,7 @@ public class IncallActivity extends AbstractCalleesActivity implements
enableView(mConferenceVirtualCallee, R.id.conf_header_details, this, true); enableView(mConferenceVirtualCallee, R.id.conf_header_details, this, true);
boolean mMayDoVideo = Version.isVideoCapable() boolean mMayDoVideo = Version.isVideoCapable() && LinphoneManager.getInstance().isVideoEnabled();
&& LinphoneManager.getInstance().isVideoEnabled();
if (mMayDoVideo) { if (mMayDoVideo) {
findViewById(R.id.conf_simple_video).setOnClickListener(this); findViewById(R.id.conf_simple_video).setOnClickListener(this);
} else { } else {
@ -178,22 +193,63 @@ public class IncallActivity extends AbstractCalleesActivity implements
view.setVisibility(VISIBLE); view.setVisibility(VISIBLE);
} }
private void acceptCallUpdate(boolean accept, int id) {
removeDialog(id);
timer.cancel();
LinphoneCall call = LinphoneManager.getLc().getCurrentCall();
if (call == null)
return;
LinphoneCallParams params = call.getCurrentParamsCopy();
if (accept) {
params.setVideoEnabled(true);
LinphoneManager.getLc().enableVideo(true, true);
}
try {
LinphoneManager.getLc().acceptCallUpdate(call, params);
} catch (LinphoneCoreException e) {
e.printStackTrace();
}
updateUI();
}
@Override @Override
//FIXME : Store texts into resources
protected Dialog onCreateDialog(final int id) { protected Dialog onCreateDialog(final int id) {
switch (id) { switch (id) {
case promptVideoId:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.dynamic_video_asking);
builder.setNegativeButton(R.string.dynamic_video_deny, new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton)
{
acceptCallUpdate(false, id);
}
});
builder.setPositiveButton(R.string.dynamic_video_accept, new
DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton)
{
acceptCallUpdate(true, id);
}
});
return builder.create();
case numpadDialogId: case numpadDialogId:
Numpad numpad = new Numpad(this, true); Numpad numpad = new Numpad(this, true);
return new AlertDialog.Builder(this).setView(numpad) return new AlertDialog.Builder(this).setView(numpad)
// .setIcon(R.drawable.logo_linphone_57x57) // .setIcon(R.drawable.logo_linphone_57x57)
// .setTitle("Send DTMFs") // .setTitle("Send DTMFs")
.setPositiveButton(getString(R.string.close_button_text), new .setPositiveButton(R.string.close_button_text, new
DialogInterface.OnClickListener() { DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) public void onClick(DialogInterface dialog, int whichButton)
{ {
dismissDialog(id); dismissDialog(id);
} }
}) })
.create(); .create();
default: default:
throw new IllegalArgumentException("unkown dialog id " + id); throw new IllegalArgumentException("unkown dialog id " + id);
@ -740,4 +796,29 @@ public class IncallActivity extends AbstractCalleesActivity implements
}); });
} }
@Override
public void onCallStateChanged(LinphoneCall call, final State state, String message) {
if (state == State.CallUpdatedByRemote) {
// If the correspondent proposes video while audio call
boolean remoteVideo = call.getRemoteParams().getVideoEnabled();
boolean localVideo = call.getCurrentParamsCopy().getVideoEnabled();
boolean autoAcceptCameraPolicy = LinphoneManager.getInstance().isAutoAcceptCamera();
if (remoteVideo && !localVideo && !autoAcceptCameraPolicy && !LinphoneManager.getLc().isInConference()) {
mHandler.post(new Runnable() {
public void run() {
showDialog(promptVideoId);
// We let 30 secs for the user to decide
timer = new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) { }
public void onFinish() {
removeDialog(promptVideoId);
}
}.start();
}
});
}
}
super.onCallStateChanged(call, state, message);
}
} }

View file

@ -25,13 +25,14 @@ import java.lang.reflect.Method;
import org.linphone.LinphoneManager.NewOutgoingCallUiListener; import org.linphone.LinphoneManager.NewOutgoingCallUiListener;
import org.linphone.LinphoneSimpleListener.LinphoneServiceListener; import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCore.GlobalState;
import org.linphone.core.LinphoneCore.RegistrationState;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneProxyConfig; import org.linphone.core.LinphoneProxyConfig;
import org.linphone.core.Log; import org.linphone.core.Log;
import org.linphone.core.OnlineStatus; import org.linphone.core.OnlineStatus;
import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCore.GlobalState;
import org.linphone.core.LinphoneCore.RegistrationState;
import org.linphone.mediastream.Version; import org.linphone.mediastream.Version;
import android.app.Notification; import android.app.Notification;
@ -45,12 +46,12 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.media.RingtoneManager; import android.media.RingtoneManager;
import android.net.Uri; import android.net.Uri;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;
import android.os.Build; import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.os.IBinder; import android.os.IBinder;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.net.wifi.WifiManager.WifiLock;
import android.net.wifi.WifiManager;
/** /**
* *
@ -381,6 +382,9 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
return DialerActivity.instance(); return DialerActivity.instance();
} }
private static final LinphoneOnCallStateChangedListener incallListener() {
return IncallActivity.instance();
}
@ -447,6 +451,23 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
.setClass(this, LinphoneActivity.class) .setClass(this, LinphoneActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
} }
if (state == State.CallUpdatedByRemote) {
// If the correspondent proposes video while audio call
boolean remoteVideo = call.getRemoteParams().getVideoEnabled();
boolean localVideo = call.getCurrentParamsCopy().getVideoEnabled();
boolean autoAcceptCameraPolicy = LinphoneManager.getInstance().isAutoAcceptCamera();
if (remoteVideo && !localVideo && !autoAcceptCameraPolicy) {
try {
LinphoneManager.getLc().deferCallUpdate(call);
if (incallListener() != null)
incallListener().onCallStateChanged(call, state, message);
} catch (LinphoneCoreException e) {
e.printStackTrace();
}
}
}
if (state == State.StreamsRunning) { if (state == State.StreamsRunning) {
// Workaround bug current call seems to be updated after state changed to streams running // Workaround bug current call seems to be updated after state changed to streams running
@ -461,7 +482,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
mHandler.post(new Runnable() { mHandler.post(new Runnable() {
public void run() { public void run() {
if (guiListener() != null) if (guiListener() != null)
guiListener().onCallStateChanged(call, state, message); guiListener().onCallStateChanged(call, state, message);
} }
}); });
} }

View file

@ -589,21 +589,21 @@ class LinphoneCoreImpl implements LinphoneCore {
return (LinphoneCall) findCallFromUri(nativePtr, uri); return (LinphoneCall) findCallFromUri(nativePtr, uri);
} }
public MediaEncryption getMediaEncryption() { public synchronized MediaEncryption getMediaEncryption() {
return MediaEncryption.fromInt(getMediaEncryption(nativePtr)); return MediaEncryption.fromInt(getMediaEncryption(nativePtr));
} }
public boolean isMediaEncryptionMandatory() { public synchronized boolean isMediaEncryptionMandatory() {
return isMediaEncryptionMandatory(nativePtr); return isMediaEncryptionMandatory(nativePtr);
} }
public void setMediaEncryption(MediaEncryption menc) { public synchronized void setMediaEncryption(MediaEncryption menc) {
setMediaEncryption(nativePtr, menc.mValue); setMediaEncryption(nativePtr, menc.mValue);
} }
public void setMediaEncryptionMandatory(boolean yesno) { public synchronized void setMediaEncryptionMandatory(boolean yesno) {
setMediaEncryptionMandatory(nativePtr, yesno); setMediaEncryptionMandatory(nativePtr, yesno);
} }
private native int getMaxCalls(long nativePtr); private native int getMaxCalls(long nativePtr);
public int getMaxCalls() { public synchronized int getMaxCalls() {
return getMaxCalls(nativePtr); return getMaxCalls(nativePtr);
} }
@Override @Override
@ -614,61 +614,61 @@ class LinphoneCoreImpl implements LinphoneCore {
} }
private native boolean soundResourcesLocked(long nativePtr); private native boolean soundResourcesLocked(long nativePtr);
public boolean soundResourcesLocked() { public synchronized boolean soundResourcesLocked() {
return soundResourcesLocked(nativePtr); return soundResourcesLocked(nativePtr);
} }
private native void setMaxCalls(long nativePtr, int max); private native void setMaxCalls(long nativePtr, int max);
@Override @Override
public void setMaxCalls(int max) { public synchronized void setMaxCalls(int max) {
setMaxCalls(nativePtr, max); setMaxCalls(nativePtr, max);
} }
private native boolean isEchoLimiterEnabled(long nativePtr); private native boolean isEchoLimiterEnabled(long nativePtr);
@Override @Override
public boolean isEchoLimiterEnabled() { public synchronized boolean isEchoLimiterEnabled() {
return isEchoLimiterEnabled(nativePtr); return isEchoLimiterEnabled(nativePtr);
} }
private native boolean mediaEncryptionSupported(long nativePtr, int menc); private native boolean mediaEncryptionSupported(long nativePtr, int menc);
@Override @Override
public boolean mediaEncryptionSupported(MediaEncryption menc) { public synchronized boolean mediaEncryptionSupported(MediaEncryption menc) {
return mediaEncryptionSupported(nativePtr,menc.mValue); return mediaEncryptionSupported(nativePtr,menc.mValue);
} }
private native void setPlayFile(long nativePtr, String path); private native void setPlayFile(long nativePtr, String path);
@Override @Override
public void setPlayFile(String path) { public synchronized void setPlayFile(String path) {
setPlayFile(nativePtr, path); setPlayFile(nativePtr, path);
} }
private native void tunnelAddServerAndMirror(long nativePtr, String host, int port, int mirror, int ms); private native void tunnelAddServerAndMirror(long nativePtr, String host, int port, int mirror, int ms);
@Override @Override
public void tunnelAddServerAndMirror(String host, int port, int mirror, int ms) { public synchronized void tunnelAddServerAndMirror(String host, int port, int mirror, int ms) {
tunnelAddServerAndMirror(nativePtr, host, port, mirror, ms); tunnelAddServerAndMirror(nativePtr, host, port, mirror, ms);
} }
private native void tunnelAutoDetect(long nativePtr); private native void tunnelAutoDetect(long nativePtr);
@Override @Override
public void tunnelAutoDetect() { public synchronized void tunnelAutoDetect() {
tunnelAutoDetect(nativePtr); tunnelAutoDetect(nativePtr);
} }
private native void tunnelCleanServers(long nativePtr); private native void tunnelCleanServers(long nativePtr);
@Override @Override
public void tunnelCleanServers() { public synchronized void tunnelCleanServers() {
tunnelCleanServers(nativePtr); tunnelCleanServers(nativePtr);
} }
private native void tunnelEnable(long nativePtr, boolean enable); private native void tunnelEnable(long nativePtr, boolean enable);
@Override @Override
public void tunnelEnable(boolean enable) { public synchronized void tunnelEnable(boolean enable) {
tunnelEnable(nativePtr, enable); tunnelEnable(nativePtr, enable);
} }
private native void tunnelEnableLogs(long nativePtr, boolean enable); private native void tunnelEnableLogs(long nativePtr, boolean enable);
@Override @Override
public void tunnelEnableLogs(boolean enable) { public synchronized void tunnelEnableLogs(boolean enable) {
tunnelEnableLogs(nativePtr, enable); tunnelEnableLogs(nativePtr, enable);
} }
@ -678,27 +678,27 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void acceptCallWithParams(long nativePtr, long aCall, private native void acceptCallWithParams(long nativePtr, long aCall,
long params); long params);
@Override @Override
public void acceptCallWithParams(LinphoneCall aCall, public synchronized void acceptCallWithParams(LinphoneCall aCall,
LinphoneCallParams params) throws LinphoneCoreException { LinphoneCallParams params) throws LinphoneCoreException {
acceptCallWithParams(nativePtr, getCallPtr(aCall), getCallParamsPtr(params)); acceptCallWithParams(nativePtr, getCallPtr(aCall), getCallParamsPtr(params));
} }
private native void acceptCallUpdate(long nativePtr, long aCall, long params); private native void acceptCallUpdate(long nativePtr, long aCall, long params);
@Override @Override
public void acceptCallUpdate(LinphoneCall aCall, LinphoneCallParams params) public synchronized void acceptCallUpdate(LinphoneCall aCall, LinphoneCallParams params)
throws LinphoneCoreException { throws LinphoneCoreException {
acceptCallUpdate(nativePtr, getCallPtr(aCall), getCallParamsPtr(params)); acceptCallUpdate(nativePtr, getCallPtr(aCall), getCallParamsPtr(params));
} }
private native void deferCallUpdate(long nativePtr, long aCall); private native void deferCallUpdate(long nativePtr, long aCall);
@Override @Override
public void deferCallUpdate(LinphoneCall aCall) public synchronized void deferCallUpdate(LinphoneCall aCall)
throws LinphoneCoreException { throws LinphoneCoreException {
deferCallUpdate(nativePtr, getCallPtr(aCall)); deferCallUpdate(nativePtr, getCallPtr(aCall));
} }
private native void setVideoPolicy(long nativePtr, boolean autoInitiate, boolean autoAccept); private native void setVideoPolicy(long nativePtr, boolean autoInitiate, boolean autoAccept);
public void setVideoPolicy(boolean autoInitiate, boolean autoAccept) { public synchronized void setVideoPolicy(boolean autoInitiate, boolean autoAccept) {
setVideoPolicy(nativePtr, autoInitiate, autoAccept); setVideoPolicy(nativePtr, autoInitiate, autoAccept);
} }
} }

@ -1 +1 @@
Subproject commit dc0361975b2b845e66a88e58c8559758b1bd21e1 Subproject commit 6c49da243ca8e823ff11dd8891af4a60f5330610