diff --git a/res/raw/linphonerc b/res/raw/linphonerc
index a9d417c94..70f2c1359 100644
--- a/res/raw/linphonerc
+++ b/res/raw/linphonerc
@@ -15,7 +15,7 @@ use_ipv6=0
register_only_when_network_is_up=1
default_proxy=0
auto_net_state_mon=0
-keepalive_period=3600000
+keepalive_period=30000
[rtp]
audio_rtp_port=7076
@@ -30,7 +30,7 @@ ringer_dev_id=ANDROID SND: Android Sound card
capture_dev_id=ANDROID SND: Android Sound card
remote_ring=/data/data/org.linphone/files/ringback.wav
local_ring=/data/data/org.linphone/files/oldphone_mono.wav
-ec_tail_len=100
+ec_tail_len=120
el_type=mic
el_thres=0.05
el_force=100000
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 81ad41cf6..2a15530a2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1,5 +1,7 @@
+ pref_echo_canceller_calibration_key
+ Echo calibration
Use front camera
pref_video_use_front_camera_key
Video
@@ -85,10 +87,12 @@
Yes
No
Dismiss
+Continue
Never remind me
%s, do you want to go to the settings page ?
<P ALIGN=CENTER>No SIP account has been configured yet, do you want to go to the settings page ?<br/><br/> Need help ?<br/> "http://www.linphone.org/m/help"</p>
-<P ALIGN=CENTER>Welcome to Linphone SIP phone<br/><br/> If you are new to SIP, have a look at<br/> "http://www.linphone.org/m/help"</p>
+<P ALIGN=CENTER>Welcome to Linphone SIP phone<br/><br/> If you are new to SIP, have a look at<br/> "http://www.linphone.org/m/help"</p>
+Starting echo cancelation audio calibration
Cannot initiate a new call because a call is already engaged
History
Cannot build destination address from [%s]
@@ -102,4 +106,7 @@
Removes the echo heard by other end
Stun server
pref_stun_server_key
+Calibrating...
+Calibrated [%s ms]
+failed
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index d9623bcfd..e7651acf5 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -45,7 +45,7 @@
-
-
+
+
diff --git a/src/org/linphone/DialerActivity.java b/src/org/linphone/DialerActivity.java
index 609f43f49..cda9d8dca 100644
--- a/src/org/linphone/DialerActivity.java
+++ b/src/org/linphone/DialerActivity.java
@@ -25,6 +25,7 @@ import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
+import org.linphone.core.LinphoneCore.EcCalibratorStatus;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreListener;
import org.linphone.core.LinphoneFriend;
@@ -100,7 +101,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
private ImageButton mAddVideo;
private static final String PREF_CHECK_CONFIG = "pref_check_config";
- private static final String PREF_FIRST_LAUNCH = "pref_first_launch";
+ public static final String PREF_FIRST_LAUNCH = "pref_first_launch";
private static String CURRENT_ADDRESS = "org.linphone.current-address";
private static String CURRENT_DISPLAYNAME = "org.linphone.current-displayname";
static int VIDEO_VIEW_ACTIVITY = 100;
@@ -359,10 +360,9 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
builder.setCustomTitle(lDialogTextView)
.setCancelable(false)
- .setPositiveButton(getString(R.string.dismiss), new DialogInterface.OnClickListener() {
+ .setPositiveButton(getString(R.string.cont), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
LinphoneActivity.instance().startprefActivity();
- mPref.edit().putBoolean(PREF_FIRST_LAUNCH, false).commit();
accountCheckingDone = true;
}
});
@@ -490,7 +490,6 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
if (state == LinphoneCall.State.OutgoingInit) {
- mWakeLock.acquire();
enterIncalMode(lc);
routeAudioToReceiver();
} else if (state == LinphoneCall.State.IncomingReceived) {
@@ -550,6 +549,7 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
}
setVolumeControlStream(AudioManager.STREAM_VOICE_CALL);
LinphoneActivity.instance().startProxymitySensor();
+ if (!mWakeLock.isHeld()) mWakeLock.acquire();
}
private void configureMuteAndSpeakerButtons() {
@@ -741,4 +741,8 @@ public class DialerActivity extends Activity implements LinphoneCoreListener {
private AndroidCameraRecordManager getVideoManager() {
return AndroidCameraRecordManager.getInstance();
}
+ public void ecCalibrationStatus(LinphoneCore lc, EcCalibratorStatus status,
+ int delay_ms, Object data) {
+
+ }
}
diff --git a/src/org/linphone/KeepAliveManager.java b/src/org/linphone/KeepAliveManager.java
new file mode 100644
index 000000000..3baf685c9
--- /dev/null
+++ b/src/org/linphone/KeepAliveManager.java
@@ -0,0 +1,46 @@
+/*
+ContactPickerActivity.java
+Copyright (C) 2010 Belledonne Communications, Grenoble, France
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+package org.linphone;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+
+
+
+public class KeepAliveManager extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ if (!LinphoneService.isready()) {
+ Log.i(LinphoneService.TAG, "Linphone service not ready");
+ return;
+ } else {
+ if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) {
+ LinphoneService.getLc().enableKeepAlive(true);
+ } else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) {
+ LinphoneService.getLc().enableKeepAlive(false);
+ }
+ }
+
+ }
+
+}
diff --git a/src/org/linphone/LinphonePreferencesActivity.java b/src/org/linphone/LinphonePreferencesActivity.java
index e86615c16..69077ba62 100644
--- a/src/org/linphone/LinphonePreferencesActivity.java
+++ b/src/org/linphone/LinphonePreferencesActivity.java
@@ -21,26 +21,39 @@ package org.linphone;
+import org.linphone.core.LinphoneCoreException;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.DialogInterface.OnClickListener;
+import android.media.AudioManager;
import android.os.Build;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.util.Log;
public class LinphonePreferencesActivity extends PreferenceActivity {
private static final int version = Integer.parseInt(Build.VERSION.SDK);
-
+ boolean mIsLowEndCpu = true;
+ private AudioManager mAudioManager;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+ mAudioManager = ((AudioManager)getSystemService(Context.AUDIO_SERVICE));
boolean enableIlbc=false;
if (LinphoneService.isready()) {
// if not ilbc, we are on low end cpu.
enableIlbc = LinphoneService.instance().getLinphoneCore().findPayloadType("iLBC", 8000)!=null?true:false;
- if (enableIlbc && !getPreferenceManager().getSharedPreferences().contains(getString(R.string.pref_echo_cancellation_key))) {
+ mIsLowEndCpu=!enableIlbc;
+ if (!mIsLowEndCpu && !getPreferenceManager().getSharedPreferences().contains(getString(R.string.pref_echo_cancellation_key))) {
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.pref_echo_cancellation_key), true).commit();
}
- if (!enableIlbc) {
+ if (mIsLowEndCpu) {
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.pref_codec_ilbc_key), false).commit();
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.pref_codec_speex16_key), false).commit();
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(R.string.pref_codec_speex32_key), false).commit();
@@ -50,18 +63,48 @@ public class LinphonePreferencesActivity extends PreferenceActivity {
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
- if (enableIlbc) {
+ if (!mIsLowEndCpu) {
getPreferenceScreen().findPreference(getString(R.string.pref_codec_ilbc_key)).setEnabled(enableIlbc);
getPreferenceScreen().findPreference(getString(R.string.pref_codec_speex16_key)).setEnabled(enableIlbc);
//getPreferenceScreen().findPreference(getString(R.string.pref_codec_speex32_key)).setEnabled(enableIlbc);
}
+ getPreferenceScreen().findPreference(getString(R.string.pref_echo_canceller_calibration_key)).setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ startEcCalibration(preference);
+ return false;
+ }
+ });
// Force disable video
if (version < 5 || !enableIlbc) {
disableCheckbox(R.string.pref_video_enable_key);
}
- }
+ if (getPreferenceManager().getSharedPreferences().getBoolean(DialerActivity.PREF_FIRST_LAUNCH,true)) {
+ if (!mIsLowEndCpu ) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setTitle(R.string.ec_calibration_launch_message).setCancelable(false).setPositiveButton(getString(R.string.cont), new OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ startEcCalibration(getPreferenceScreen().findPreference(getString(R.string.pref_echo_canceller_calibration_key)));
+ }
+ }).create().show();
+ }
+ getPreferenceManager().getSharedPreferences().edit().putBoolean(DialerActivity.PREF_FIRST_LAUNCH, false).commit();
+ }
+
+ }
+ private void startEcCalibration(Preference preference) {
+ try {
+ while (mAudioManager.getStreamVolume(AudioManager.STREAM_VOICE_CALL) != mAudioManager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL)) {
+ mAudioManager.adjustStreamVolume(AudioManager.STREAM_VOICE_CALL, AudioManager.ADJUST_RAISE, 0);
+ }
+ LinphoneService.getLc().startEchoCalibration(preference);
+ preference.setSummary(R.string.ec_calibrating);
+ preference.getEditor().putBoolean(getString(R.string.pref_echo_canceller_calibration_key), false).commit();
+ } catch (LinphoneCoreException e) {
+ Log.w(LinphoneService.TAG, "Cannot calibrate EC",e);
+ }
+ }
private void disableCheckbox(int key) {
getPreferenceManager().getSharedPreferences().edit().putBoolean(getString(key), false).commit();
CheckBoxPreference box = (CheckBoxPreference) getPreferenceScreen().findPreference(getString(key));
diff --git a/src/org/linphone/LinphoneService.java b/src/org/linphone/LinphoneService.java
index 29687d937..61393dd84 100644
--- a/src/org/linphone/LinphoneService.java
+++ b/src/org/linphone/LinphoneService.java
@@ -30,6 +30,7 @@ import org.linphone.core.LinphoneAuthInfo;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
+import org.linphone.core.LinphoneCore.EcCalibratorStatus;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreListener;
@@ -44,8 +45,10 @@ import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
+import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.media.AudioManager;
import android.media.MediaPlayer;
@@ -55,6 +58,8 @@ import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Vibrator;
+import android.preference.CheckBoxPreference;
+import android.preference.Preference;
import android.preference.PreferenceManager;
import android.util.Log;
@@ -86,6 +91,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
LinphoneCall.State mCurrentCallState;
Vibrator mVibrator;
private AudioManager mAudioManager;
+ private BroadcastReceiver mReceiver = new KeepAliveManager();
private Handler mHandler = new Handler() ;
static boolean isready() {
@@ -145,12 +151,17 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
};
mTimer.scheduleAtFixedRate(lTask, 0, 100);
-
-
+ IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
+ lFilter.addAction(Intent.ACTION_SCREEN_OFF);
+ registerReceiver(mReceiver, lFilter);
+
+
+
}
catch (Exception e) {
Log.e(TAG,"Cannot start linphone",e);
}
+
}
@@ -445,6 +456,7 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
mLinphoneCore.destroy();
theLinphone=null;
mNotificationManager.cancel(NOTIFICATION_ID);
+ unregisterReceiver(mReceiver);
}
public void newSubscriptionRequest(LinphoneCore lc, LinphoneFriend lf,
String url) {
@@ -496,5 +508,21 @@ public class LinphoneService extends Service implements LinphoneCoreListener {
mVibrator.cancel();
}
}
+ public void ecCalibrationStatus(final LinphoneCore lc,final EcCalibratorStatus status, final int delay_ms,
+ final Object data) {
+ final CheckBoxPreference pref = (CheckBoxPreference) data;
+ mHandler.post(new Runnable() {
+ public void run() {
+ if (status == EcCalibratorStatus.Done) {
+ pref.setSummary(String.format(getString(R.string.ec_calibrated), delay_ms));
+ pref.setChecked(true);
+
+ } else if (status == EcCalibratorStatus.Failed) {
+ pref.setSummary(R.string.failed);
+ pref.setChecked(false);
+ }
+ }
+ });
+ }
}
diff --git a/src/org/linphone/core/LinphoneCoreImpl.java b/src/org/linphone/core/LinphoneCoreImpl.java
index 01ba4e652..1a9fc67a7 100644
--- a/src/org/linphone/core/LinphoneCoreImpl.java
+++ b/src/org/linphone/core/LinphoneCoreImpl.java
@@ -88,6 +88,9 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void setRing(long nativePtr, String path);
private native String getRing(long nativePtr);
private native long[] listVideoPayloadTypes(long nativePtr);
+ private native void enableKeepAlive(long nativePtr,boolean enable);
+ private native boolean isKeepAliveEnabled(long nativePtr);
+ private native int startEchoCalibration(long nativePtr,Object data);
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig,File factoryConfig,Object userdata) throws IOException {
@@ -426,4 +429,14 @@ class LinphoneCoreImpl implements LinphoneCore {
public boolean isNetworkReachable() {
throw new RuntimeException("Not implemented");
}
+ public void enableKeepAlive(boolean enable) {
+ enableKeepAlive(nativePtr,enable);
+
+ }
+ public boolean isKeepAliveEnabled() {
+ return isKeepAliveEnabled(nativePtr);
+ }
+ public void startEchoCalibration(Object data) throws LinphoneCoreException {
+ startEchoCalibration(nativePtr, data);
+ }
}
diff --git a/submodules/linphone b/submodules/linphone
index 407d88929..4166afa48 160000
--- a/submodules/linphone
+++ b/submodules/linphone
@@ -1 +1 @@
-Subproject commit 407d88929acc90da18c7a047f0d47d21efe09420
+Subproject commit 4166afa48fd099283684fd147c8fd07fd0b68c16