From 29381534cd71db918ba814737ceac6aceaf9d343 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 8 Mar 2012 16:04:20 +0100 Subject: [PATCH] Dynamic video with asking dependings on the settings + linphone submodule updated --- res/values/strings.xml | 4 + src/org/linphone/IncallActivity.java | 101 ++++++++++++++++++-- src/org/linphone/LinphoneService.java | 33 +++++-- src/org/linphone/core/LinphoneCoreImpl.java | 38 ++++---- submodules/linphone | 2 +- 5 files changed, 142 insertions(+), 36 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index 896ccecbf..438e4e3ff 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -227,6 +227,10 @@ SRTP ZRTP +Your correspondent would like to switch to video +Accept video +Deny video + pref_nb_accounts_extra pref_default_account SIP Accounts diff --git a/src/org/linphone/IncallActivity.java b/src/org/linphone/IncallActivity.java index 057a7dcd4..18a636c44 100644 --- a/src/org/linphone/IncallActivity.java +++ b/src/org/linphone/IncallActivity.java @@ -29,9 +29,11 @@ import java.util.List; import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener; import org.linphone.LinphoneSimpleListener.LinphoneOnCallEncryptionChangedListener; +import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCall.State; +import org.linphone.core.LinphoneCallParams; import org.linphone.core.LinphoneCore.MediaEncryption; import org.linphone.core.LinphoneCoreException; import org.linphone.core.Log; @@ -44,6 +46,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.res.Resources; import android.os.Bundle; +import android.os.CountDownTimer; import android.os.Handler; import android.text.TextUtils; import android.view.KeyEvent; @@ -63,6 +66,7 @@ import android.widget.Toast; */ public class IncallActivity extends AbstractCalleesActivity implements LinphoneOnAudioChangedListener, + LinphoneOnCallStateChangedListener, LinphoneOnCallEncryptionChangedListener, Comparator, OnLongClickListener, @@ -73,12 +77,23 @@ public class IncallActivity extends AbstractCalleesActivity implements private static final int numpadDialogId = 1; private static final int addCallId = 1; private static final int transferCallId = 2; + private static final int promptVideoId = 3; + private static IncallActivity instance; + private CountDownTimer timer; public static boolean active; @Override protected void setActive(boolean a) {active = a;} @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() { LinphoneCall call = lc().getCurrentCall(); if (call != null && !call.isInConference()) { @@ -99,7 +114,8 @@ public class IncallActivity extends AbstractCalleesActivity implements return; } setContentView(R.layout.incall_layout); - + instance = this; + mAllowTransfers = getResources().getBoolean(R.bool.allow_transfers); 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); - boolean mMayDoVideo = Version.isVideoCapable() - && LinphoneManager.getInstance().isVideoEnabled(); + boolean mMayDoVideo = Version.isVideoCapable() && LinphoneManager.getInstance().isVideoEnabled(); if (mMayDoVideo) { findViewById(R.id.conf_simple_video).setOnClickListener(this); } else { @@ -178,22 +193,63 @@ public class IncallActivity extends AbstractCalleesActivity implements 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 + //FIXME : Store texts into resources protected Dialog onCreateDialog(final int 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: Numpad numpad = new Numpad(this, true); return new AlertDialog.Builder(this).setView(numpad) // .setIcon(R.drawable.logo_linphone_57x57) // .setTitle("Send DTMFs") - .setPositiveButton(getString(R.string.close_button_text), new + .setPositiveButton(R.string.close_button_text, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int whichButton) - { - dismissDialog(id); - } - }) + public void onClick(DialogInterface dialog, int whichButton) + { + dismissDialog(id); + } + }) .create(); default: 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); + } } diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java index b3103987f..57d8694a7 100644 --- a/src/org/linphone/LinphoneService.java +++ b/src/org/linphone/LinphoneService.java @@ -25,13 +25,14 @@ import java.lang.reflect.Method; import org.linphone.LinphoneManager.NewOutgoingCallUiListener; import org.linphone.LinphoneSimpleListener.LinphoneServiceListener; import org.linphone.core.LinphoneCall; +import org.linphone.core.LinphoneCall.State; 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.Log; 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 android.app.Notification; @@ -45,12 +46,12 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.media.MediaPlayer; import android.media.RingtoneManager; import android.net.Uri; +import android.net.wifi.WifiManager; +import android.net.wifi.WifiManager.WifiLock; import android.os.Build; import android.os.Handler; import android.os.IBinder; 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(); } + private static final LinphoneOnCallStateChangedListener incallListener() { + return IncallActivity.instance(); + } @@ -447,6 +451,23 @@ public final class LinphoneService extends Service implements LinphoneServiceLis .setClass(this, LinphoneActivity.class) .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) { // 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() { public void run() { if (guiListener() != null) - guiListener().onCallStateChanged(call, state, message); + guiListener().onCallStateChanged(call, state, message); } }); } diff --git a/src/org/linphone/core/LinphoneCoreImpl.java b/src/org/linphone/core/LinphoneCoreImpl.java index 8e2a83008..b79d19306 100644 --- a/src/org/linphone/core/LinphoneCoreImpl.java +++ b/src/org/linphone/core/LinphoneCoreImpl.java @@ -589,21 +589,21 @@ class LinphoneCoreImpl implements LinphoneCore { return (LinphoneCall) findCallFromUri(nativePtr, uri); } - public MediaEncryption getMediaEncryption() { + public synchronized MediaEncryption getMediaEncryption() { return MediaEncryption.fromInt(getMediaEncryption(nativePtr)); } - public boolean isMediaEncryptionMandatory() { + public synchronized boolean isMediaEncryptionMandatory() { return isMediaEncryptionMandatory(nativePtr); } - public void setMediaEncryption(MediaEncryption menc) { + public synchronized void setMediaEncryption(MediaEncryption menc) { setMediaEncryption(nativePtr, menc.mValue); } - public void setMediaEncryptionMandatory(boolean yesno) { + public synchronized void setMediaEncryptionMandatory(boolean yesno) { setMediaEncryptionMandatory(nativePtr, yesno); } private native int getMaxCalls(long nativePtr); - public int getMaxCalls() { + public synchronized int getMaxCalls() { return getMaxCalls(nativePtr); } @Override @@ -614,61 +614,61 @@ class LinphoneCoreImpl implements LinphoneCore { } private native boolean soundResourcesLocked(long nativePtr); - public boolean soundResourcesLocked() { + public synchronized boolean soundResourcesLocked() { return soundResourcesLocked(nativePtr); } private native void setMaxCalls(long nativePtr, int max); @Override - public void setMaxCalls(int max) { + public synchronized void setMaxCalls(int max) { setMaxCalls(nativePtr, max); } private native boolean isEchoLimiterEnabled(long nativePtr); @Override - public boolean isEchoLimiterEnabled() { + public synchronized boolean isEchoLimiterEnabled() { return isEchoLimiterEnabled(nativePtr); } private native boolean mediaEncryptionSupported(long nativePtr, int menc); @Override - public boolean mediaEncryptionSupported(MediaEncryption menc) { + public synchronized boolean mediaEncryptionSupported(MediaEncryption menc) { return mediaEncryptionSupported(nativePtr,menc.mValue); } private native void setPlayFile(long nativePtr, String path); @Override - public void setPlayFile(String path) { + public synchronized void setPlayFile(String path) { setPlayFile(nativePtr, path); } private native void tunnelAddServerAndMirror(long nativePtr, String host, int port, int mirror, int ms); @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); } private native void tunnelAutoDetect(long nativePtr); @Override - public void tunnelAutoDetect() { + public synchronized void tunnelAutoDetect() { tunnelAutoDetect(nativePtr); } private native void tunnelCleanServers(long nativePtr); @Override - public void tunnelCleanServers() { + public synchronized void tunnelCleanServers() { tunnelCleanServers(nativePtr); } private native void tunnelEnable(long nativePtr, boolean enable); @Override - public void tunnelEnable(boolean enable) { + public synchronized void tunnelEnable(boolean enable) { tunnelEnable(nativePtr, enable); } private native void tunnelEnableLogs(long nativePtr, boolean enable); @Override - public void tunnelEnableLogs(boolean enable) { + public synchronized void tunnelEnableLogs(boolean enable) { tunnelEnableLogs(nativePtr, enable); } @@ -678,27 +678,27 @@ class LinphoneCoreImpl implements LinphoneCore { private native void acceptCallWithParams(long nativePtr, long aCall, long params); @Override - public void acceptCallWithParams(LinphoneCall aCall, + public synchronized void acceptCallWithParams(LinphoneCall aCall, LinphoneCallParams params) throws LinphoneCoreException { acceptCallWithParams(nativePtr, getCallPtr(aCall), getCallParamsPtr(params)); } private native void acceptCallUpdate(long nativePtr, long aCall, long params); @Override - public void acceptCallUpdate(LinphoneCall aCall, LinphoneCallParams params) + public synchronized void acceptCallUpdate(LinphoneCall aCall, LinphoneCallParams params) throws LinphoneCoreException { acceptCallUpdate(nativePtr, getCallPtr(aCall), getCallParamsPtr(params)); } private native void deferCallUpdate(long nativePtr, long aCall); @Override - public void deferCallUpdate(LinphoneCall aCall) + public synchronized void deferCallUpdate(LinphoneCall aCall) throws LinphoneCoreException { deferCallUpdate(nativePtr, getCallPtr(aCall)); } 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); } } diff --git a/submodules/linphone b/submodules/linphone index dc0361975..6c49da243 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit dc0361975b2b845e66a88e58c8559758b1bd21e1 +Subproject commit 6c49da243ca8e823ff11dd8891af4a60f5330610