diff --git a/README b/README index 5a133c2c7..50cc863fb 100644 --- a/README +++ b/README @@ -3,7 +3,7 @@ To build liblinphone for Android, you must: 1) download the Android ndk (>=r5c) from google. -2) install the autotools: autoconf, automake, aclocal, libtoolize +2) install the autotools: autoconf, automake, aclocal, libtoolize pkgconfig 3) run the ./prepare_sources.sh script in the top level directory. This will download iLBC source files and convert some assembly files in VP8 project. $ ./prepare_sources.sh diff --git a/jni/Android.mk b/jni/Android.mk index b2218a002..d6f8cef16 100755 --- a/jni/Android.mk +++ b/jni/Android.mk @@ -2,6 +2,8 @@ #default values BUILD_AMR=light +BUILD_SRTP=1 + ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) BUILD_X264=1 LINPHONE_VIDEO=1 @@ -14,7 +16,7 @@ endif ##ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) ifeq ($(BUILD_GPLV3_ZRTP), 1) -BUILD_SRTP=1 + BUILD_SRTP=1 ZRTP_C_INCLUDE= \ $(linphone-root-dir)/submodules/externals/libzrtpcpp/src endif diff --git a/jni/Application.mk b/jni/Application.mk index 88e0e64f0..85985223d 100644 --- a/jni/Application.mk +++ b/jni/Application.mk @@ -1,5 +1,5 @@ APP_PROJECT_PATH := $(call my-dir)/../ -APP_MODULES :=libspeex libgsm libortp libosip2 libeXosip2 libmediastreamer2 liblinphone +APP_MODULES :=libspeex libgsm libortp libosip2 libeXosip2 libmediastreamer2 liblinphone APP_STL := stlport_static ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) diff --git a/res/values/non_localizable_strings.xml b/res/values/non_localizable_strings.xml index cc7222cda..a5ef23b8b 100644 --- a/res/values/non_localizable_strings.xml +++ b/res/values/non_localizable_strings.xml @@ -50,6 +50,8 @@ pref_codecs_key pref_stun_server_key pref_video_codec_vp8_key - - + pref_media_encryption_key + none + srtp + zrtp diff --git a/res/values/strings.xml b/res/values/strings.xml index 99b7d5708..e10a5d1e9 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -202,4 +202,8 @@ AMR codec might not be present on your phone VP8 +Media encryption +None +SRTP +ZRTP diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index a0970e193..fb3927936 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -146,6 +146,9 @@ + diff --git a/src/org/linphone/IncallActivity.java b/src/org/linphone/IncallActivity.java index 7342e1943..0ce27783f 100644 --- a/src/org/linphone/IncallActivity.java +++ b/src/org/linphone/IncallActivity.java @@ -32,6 +32,7 @@ import org.linphone.core.LinphoneCall; import org.linphone.core.LinphoneCoreException; import org.linphone.core.Log; import org.linphone.core.LinphoneCall.State; +import org.linphone.core.LinphoneCore.MediaEncryption; import org.linphone.mediastream.Version; import org.linphone.ui.Numpad; @@ -452,8 +453,8 @@ public class IncallActivity extends AbstractCalleesActivity implements final OnClickListener l = new CallActionListener(call); confButton.setOnClickListener(l); - String mediaEncryption = call.getCurrentParamsCopy().getMediaEncryption(); - if ("none".equals(mediaEncryption)) { + MediaEncryption mediaEncryption = call.getCurrentParamsCopy().getMediaEncryption(); + if (MediaEncryption.None == mediaEncryption) { setVisibility(v, R.id.callee_status_secured, false); setVisibility(v, R.id.callee_status_maybe_secured, false); setVisibility(v, R.id.callee_status_not_secured, false); @@ -477,13 +478,13 @@ public class IncallActivity extends AbstractCalleesActivity implements enableView(content, R.id.merge_to_conference, l, showMergeToConf); enableView(content, R.id.terminate_call, l, true); - String mediaEncryption = call.getCurrentParamsCopy().getMediaEncryption(); - if ("none".equals(mediaEncryption)) { - boolean showUnencrypted = Version.hasZrtp(); - setVisibility(content, R.id.unencrypted, showUnencrypted); - } else { + MediaEncryption mediaEncryption = call.getCurrentParamsCopy().getMediaEncryption(); + MediaEncryption supposedEncryption = LinphoneManager.getLc().getMediaEncryption(); + if (mediaEncryption==MediaEncryption.None) { + setVisibility(content, R.id.unencrypted, supposedEncryption!=MediaEncryption.None); + } else{ TextView token = (TextView) content.findViewById(R.id.authentication_token); - if ("zrtp".equals(mediaEncryption)) { + if (mediaEncryption==MediaEncryption.ZRTP) { boolean authVerified = call.isAuthenticationTokenVerified(); String fmt = getString(authVerified ? R.string.reset_sas_fmt : R.string.validate_sas_fmt); token.setText(String.format(fmt, call.getAuthenticationToken())); diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java index d4c2faa76..d92d027d8 100644 --- a/src/org/linphone/LinphoneManager.java +++ b/src/org/linphone/LinphoneManager.java @@ -66,6 +66,7 @@ import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCore.EcCalibratorStatus; import org.linphone.core.LinphoneCore.FirewallPolicy; import org.linphone.core.LinphoneCore.GlobalState; +import org.linphone.core.LinphoneCore.MediaEncryption; import org.linphone.core.LinphoneCore.RegistrationState; import org.linphone.core.LinphoneCore.Transports; import org.linphone.mediastream.Version; @@ -472,6 +473,18 @@ public final class LinphoneManager implements LinphoneCoreListener { } return false; } + + void initMediaEncryption(){ + String pref = mPref.getString(getString(R.string.pref_media_encryption_key), + getString(R.string.pref_media_encryption_key_none)); + MediaEncryption me=MediaEncryption.None; + if (pref.equals(getString(R.string.pref_media_encryption_key_srtp))) + me=MediaEncryption.SRTP; + else if (pref.equals(getString(R.string.pref_media_encryption_key_zrtp))) + me=MediaEncryption.ZRTP; + Log.i("Media encryption set to "+pref); + mLc.setMediaEncryption(me); + } public void initFromConf() throws LinphoneConfigException { //traces @@ -482,7 +495,7 @@ public final class LinphoneManager implements LinphoneCoreListener { initialTransports = mLc.getSignalingTransportPorts(); setSignalingTransportsFromConfiguration(initialTransports); - + initMediaEncryption(); try { // Configure audio codecs @@ -658,7 +671,7 @@ public final class LinphoneManager implements LinphoneCoreListener { key = R.string.pref_video_codec_h264_key; } else if ("H263-1998".equals(mime)) { key = R.string.pref_video_codec_h263_key; - } else if ("VP8-DRAFT-0-3-2".equals(mime)) { + } else if ("VP8".equals(mime)) { key = R.string.pref_video_codec_vp8_key; } else { Log.e("Unhandled video codec ", mime); diff --git a/src/org/linphone/LinphonePreferencesActivity.java b/src/org/linphone/LinphonePreferencesActivity.java index c86710588..cb7928153 100644 --- a/src/org/linphone/LinphonePreferencesActivity.java +++ b/src/org/linphone/LinphonePreferencesActivity.java @@ -28,8 +28,10 @@ import static org.linphone.R.string.pref_codec_speex16_key; import static org.linphone.R.string.pref_echo_cancellation_key; import static org.linphone.R.string.pref_echo_canceller_calibration_key; import static org.linphone.R.string.pref_echo_limiter_key; +import static org.linphone.R.string.pref_media_encryption_key; import static org.linphone.R.string.pref_video_enable_key; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -39,6 +41,7 @@ import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCoreException; import org.linphone.core.Log; import org.linphone.core.LinphoneCore.EcCalibratorStatus; +import org.linphone.core.LinphoneCore.MediaEncryption; import org.linphone.mediastream.Version; import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; import org.linphone.mediastream.video.capture.hwconf.Hacks; @@ -47,6 +50,7 @@ import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.preference.CheckBoxPreference; +import android.preference.ListPreference; import android.preference.Preference; import android.preference.PreferenceActivity; import android.preference.Preference.OnPreferenceChangeListener; @@ -58,6 +62,7 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements E private CheckBoxPreference ecCalibratePref; private CheckBoxPreference elPref; private CheckBoxPreference ecPref; + private ListPreference mencPref; private SharedPreferences prefs() { return getPreferenceManager().getSharedPreferences(); @@ -98,6 +103,7 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements E }); ecPref = (CheckBoxPreference) findPreference(pref_echo_cancellation_key); elPref = (CheckBoxPreference) findPreference(pref_echo_limiter_key); + mencPref = (ListPreference) findPreference(pref_media_encryption_key); boolean fastCpu = Version.isArmv7(); if (fastCpu) { @@ -108,7 +114,9 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements E }else{ findPreference(pref_echo_limiter_key).setEnabled(true); } - + + initializeMediaEncryptionPreferences(); + detectAudioCodec(pref_codec_amr_key,"AMR",8000, false); //detectAudioCodec(R.string.pref_codec_silk8_key,"SILK",8000, true); //detectAudioCodec(R.string.pref_codec_silk12_key,"SILK",12000, true); @@ -136,6 +144,38 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements E if (Hacks.needSoftvolume()) checkAndDisableCheckbox(R.string.pref_audio_soft_volume_key); } + + + private void initializeMediaEncryptionPreferences() { + LinphoneCore lc=LinphoneManager.getLc(); + boolean hasZrtp=lc.mediaEncryptionSupported(MediaEncryption.ZRTP); + boolean hasSrtp=lc.mediaEncryptionSupported(MediaEncryption.SRTP); + if (!hasSrtp && !hasZrtp){ + mencPref.setEnabled(false); + }else{ + List mencEntries=new ArrayList(); + List mencEntryValues=new ArrayList(); + mencEntries.add(getString(R.string.media_encryption_none)); + mencEntryValues.add(getString(R.string.pref_media_encryption_key_none)); + if (hasSrtp){ + mencEntries.add(getString(R.string.media_encryption_srtp)); + mencEntryValues.add(getString(R.string.pref_media_encryption_key_srtp)); + } + if (hasZrtp){ + mencEntries.add(getString(R.string.media_encryption_zrtp)); + mencEntryValues.add(getString(R.string.pref_media_encryption_key_zrtp)); + } + CharSequence[] contents=new CharSequence[mencEntries.size()]; + mencEntries.toArray(contents); + mencPref.setEntries(contents); + contents=new CharSequence[mencEntryValues.size()]; + mencEntryValues.toArray(contents); + mencPref.setEntryValues(contents); + mencPref.setDefaultValue(getString(R.string.media_encryption_none)); + //mencPref.setValueIndex(mencPref.findIndexOfValue(getString(R.string.media_encryption_none))); + } + } + private void addEchoPrefsListener(){ OnPreferenceChangeListener ec_listener=new OnPreferenceChangeListener(){ public boolean onPreferenceChange(Preference arg0, Object newValue) { diff --git a/src/org/linphone/core/LinphoneCallParamsImpl.java b/src/org/linphone/core/LinphoneCallParamsImpl.java index 8a7fba15c..bb7e9b1ab 100644 --- a/src/org/linphone/core/LinphoneCallParamsImpl.java +++ b/src/org/linphone/core/LinphoneCallParamsImpl.java @@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.linphone.core; +import org.linphone.core.LinphoneCore.MediaEncryption; + public class LinphoneCallParamsImpl implements LinphoneCallParams { protected final long nativePtr; @@ -28,8 +30,8 @@ public class LinphoneCallParamsImpl implements LinphoneCallParams { private native void enableVideo(long nativePtr, boolean b); private native boolean getVideoEnabled(long nativePtr); private native void audioBandwidth(long nativePtr, int bw); - private native void setMediaEncryption(long nativePtr, String menc); - private native String getMediaEncryption(long nativePtr); + private native void setMediaEncryption(long nativePtr, int menc); + private native int getMediaEncryption(long nativePtr); private native void destroy(long nativePtr); @@ -51,12 +53,12 @@ public class LinphoneCallParamsImpl implements LinphoneCallParams { audioBandwidth(nativePtr, value); } - public String getMediaEncryption() { - return getMediaEncryption(nativePtr); + public MediaEncryption getMediaEncryption() { + return MediaEncryption.fromInt(getMediaEncryption(nativePtr)); } - public void setMediaEnctyption(String menc) { - setMediaEncryption(nativePtr, menc); + public void setMediaEnctyption(MediaEncryption menc) { + setMediaEncryption(nativePtr, menc.mValue); } private native boolean localConferenceMode(long nativePtr); diff --git a/src/org/linphone/core/LinphoneCoreImpl.java b/src/org/linphone/core/LinphoneCoreImpl.java index 363ac8ac4..eeb082dca 100644 --- a/src/org/linphone/core/LinphoneCoreImpl.java +++ b/src/org/linphone/core/LinphoneCoreImpl.java @@ -105,8 +105,8 @@ class LinphoneCoreImpl implements LinphoneCore { private native void enableEchoLimiter(long nativePtr2, boolean val); private native int setVideoDevice(long nativePtr2, int id); private native int getVideoDevice(long nativePtr2); - private native String getMediaEncryption(long nativePtr); - private native void setMediaEncryption(long nativePtr, String menc); + private native int getMediaEncryption(long nativePtr); + private native void setMediaEncryption(long nativePtr, int menc); private native boolean isMediaEncryptionMandatory(long nativePtr); private native void setMediaEncryptionMandatory(long nativePtr, boolean yesno); @@ -571,14 +571,14 @@ class LinphoneCoreImpl implements LinphoneCore { return (LinphoneCall) findCallFromUri(nativePtr, uri); } - public String getMediaEncryption() { - return getMediaEncryption(nativePtr); + public MediaEncryption getMediaEncryption() { + return MediaEncryption.fromInt(getMediaEncryption(nativePtr)); } public boolean isMediaEncryptionMandatory() { return isMediaEncryptionMandatory(nativePtr); } - public void setMediaEncryption(String menc) { - setMediaEncryption(nativePtr, menc); + public void setMediaEncryption(MediaEncryption menc) { + setMediaEncryption(nativePtr, menc.mValue); } public void setMediaEncryptionMandatory(boolean yesno) { setMediaEncryptionMandatory(nativePtr, yesno); @@ -610,4 +610,9 @@ class LinphoneCoreImpl implements LinphoneCore { public boolean isEchoLimiterEnabled() { return isEchoLimiterEnabled(nativePtr); } + private native boolean mediaEncryptionSupported(long nativePtr, int menc); + @Override + public boolean mediaEncryptionSupported(MediaEncryption menc) { + return mediaEncryptionSupported(nativePtr,menc.mValue); + } } diff --git a/submodules/linphone b/submodules/linphone index ab498e8e8..72a508632 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit ab498e8e8cea496d6eb96a72d76cd987e49be544 +Subproject commit 72a508632760bf20c2aeac7e253f7a481974f499