diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 5a734ffae..6209687bc 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -88,6 +88,7 @@
+
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a0f30fdc0..fc549ffa6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -222,4 +222,8 @@
None
SRTP
ZRTP
+
+pref_nb_accounts_extra
+pref_default_account
+SIP Accounts
diff --git a/res/xml/account_preferences.xml b/res/xml/account_preferences.xml
new file mode 100644
index 000000000..7bf2aa65d
--- /dev/null
+++ b/res/xml/account_preferences.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index 9f9ec184f..476ed1b69 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -2,8 +2,8 @@
-
-
+
+
-
+
@@ -91,45 +92,45 @@
android:title="@string/pref_codec_pcma"/>
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java
index 2d7f60f0c..416dd3c29 100644
--- a/src/org/linphone/LinphoneManager.java
+++ b/src/org/linphone/LinphoneManager.java
@@ -47,14 +47,21 @@ import java.util.Timer;
import java.util.TimerTask;
import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener;
-import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
import org.linphone.LinphoneSimpleListener.LinphoneOnAudioChangedListener.AudioState;
+import org.linphone.LinphoneSimpleListener.LinphoneServiceListener;
import org.linphone.core.CallDirection;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneAuthInfo;
import org.linphone.core.LinphoneCall;
+import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneCore;
+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.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
import org.linphone.core.LinphoneCoreListener;
@@ -62,18 +69,11 @@ import org.linphone.core.LinphoneFriend;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.core.Log;
import org.linphone.core.PayloadType;
-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;
import org.linphone.mediastream.video.capture.AndroidVideoApi5JniWrapper;
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration;
-import org.linphone.mediastream.video.capture.hwconf.Hacks;
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration.AndroidCamera;
+import org.linphone.mediastream.video.capture.hwconf.Hacks;
import android.app.Activity;
import android.content.BroadcastReceiver;
@@ -93,8 +93,8 @@ import android.media.MediaPlayer;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.PowerManager;
-import android.os.Vibrator;
import android.os.PowerManager.WakeLock;
+import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
@@ -184,7 +184,6 @@ public final class LinphoneManager implements LinphoneCoreListener {
private BroadcastReceiver mKeepAliveReceiver = new KeepAliveReceiver();
private native void hackSpeakerState(boolean speakerOn);
- @SuppressWarnings("unused")
private static void sRouteAudioToSpeakerHelperHelper(boolean speakerOn) {
getInstance().routeAudioToSpeakerHelperHelper(speakerOn);
}
@@ -623,7 +622,6 @@ public final class LinphoneManager implements LinphoneCoreListener {
mLc.addAuthInfo(lAuthInfo);
}
-
//proxy
mLc.clearProxyConfigs();
String lProxy = getPrefString(R.string.pref_proxy_key,null);
@@ -640,7 +638,16 @@ public final class LinphoneManager implements LinphoneCoreListener {
if (lDefaultProxyConfig == null) {
lDefaultProxyConfig = LinphoneCoreFactory.instance().createProxyConfig(lIdentity, lProxy, null,true);
mLc.addProxyConfig(lDefaultProxyConfig);
- mLc.setDefaultProxyConfig(lDefaultProxyConfig);
+ int defaultAccount = getPrefInt(R.string.pref_default_account, 0);
+ if (defaultAccount == 0 || defaultAccount >= getPrefInt(R.string.pref_extra_accounts, 0)) {
+ //outbound proxy
+ if (getPrefBoolean(R.string.pref_enable_outbound_proxy_key, false)) {
+ lDefaultProxyConfig.setRoute(lProxy);
+ } else {
+ lDefaultProxyConfig.setRoute(null);
+ }
+ mLc.setDefaultProxyConfig(lDefaultProxyConfig);
+ }
} else {
lDefaultProxyConfig.edit();
@@ -649,8 +656,43 @@ public final class LinphoneManager implements LinphoneCoreListener {
lDefaultProxyConfig.enableRegister(true);
lDefaultProxyConfig.done();
}
+
+ // Extra accounts
+ for (int i = 1; i < getPrefExtraAccountsNumber(); i++) {
+ lUserName = getPrefString(getString(R.string.pref_username_key) + i, null);
+ lPasswd = getPrefString(getString(R.string.pref_passwd_key) + i, null);
+ if (lUserName != null && lUserName.length() > 0) {
+ LinphoneAuthInfo lAuthInfo = LinphoneCoreFactory.instance().createAuthInfo(lUserName, lPasswd, null);
+ mLc.addAuthInfo(lAuthInfo);
+
+ lDomain = getPrefString(getString(R.string.pref_domain_key) + i, null);
+ if (lDomain != null && lDomain.length() > 0) {
+ lIdentity = "sip:"+lUserName+"@"+lDomain;
+ lProxy = getPrefString(getString(R.string.pref_proxy_key) + i, null);
+ if (lProxy == null || lProxy.length() == 0) {
+ lProxy = "sip:" + lDomain;
+ }
+ if (!lProxy.startsWith("sip:")) {
+ lProxy = "sip:" + lProxy;
+ }
+ lDefaultProxyConfig = LinphoneCoreFactory.instance().createProxyConfig(lIdentity, lProxy, null, true);
+ mLc.addProxyConfig(lDefaultProxyConfig);
+
+ //outbound proxy
+ if (getPrefBoolean(getString(R.string.pref_enable_outbound_proxy_key) + i, false)) {
+ lDefaultProxyConfig.setRoute(lProxy);
+ } else {
+ lDefaultProxyConfig.setRoute(null);
+ }
+
+ if (i == getPrefInt(R.string.pref_default_account, 0)) {
+ mLc.setDefaultProxyConfig(lDefaultProxyConfig);
+ }
+ }
+ }
+ }
+
lDefaultProxyConfig = mLc.getDefaultProxyConfig();
-
if (lDefaultProxyConfig !=null) {
//prefix
String lPrefix = getPrefString(R.string.pref_prefix_key, null);
@@ -659,14 +701,8 @@ public final class LinphoneManager implements LinphoneCoreListener {
}
//escape +
lDefaultProxyConfig.setDialEscapePlus(getPrefBoolean(R.string.pref_escape_plus_key,false));
- //outbound proxy
- if (getPrefBoolean(R.string.pref_enable_outbound_proxy_key, false)) {
- lDefaultProxyConfig.setRoute(lProxy);
- } else {
- lDefaultProxyConfig.setRoute(null);
- }
-
}
+
//init network state
NetworkInfo networkInfo = mConnectivityManager.getActiveNetworkInfo();
mLc.setNetworkReachable(networkInfo !=null? networkInfo.getState() == NetworkInfo.State.CONNECTED:false);
@@ -766,13 +802,24 @@ public final class LinphoneManager implements LinphoneCoreListener {
private boolean getPrefBoolean(int key, boolean value) {
return mPref.getBoolean(mR.getString(key), value);
}
+ private boolean getPrefBoolean(String key, boolean value) {
+ return mPref.getBoolean(key, value);
+ }
private String getPrefString(int key, String value) {
return mPref.getString(mR.getString(key), value);
}
+ private int getPrefInt(int key, int value) {
+ return mPref.getInt(mR.getString(key), value);
+ }
private String getPrefString(int key, int value) {
return mPref.getString(mR.getString(key), mR.getString(value));
}
-
+ private String getPrefString(String key, String value) {
+ return mPref.getString(key, value);
+ }
+ private int getPrefExtraAccountsNumber() {
+ return mPref.getInt(getString(R.string.pref_extra_accounts), 0);
+ }
/* Simple implementation as Android way seems very complicate:
diff --git a/src/org/linphone/LinphonePreferencesActivity.java b/src/org/linphone/LinphonePreferencesActivity.java
index 5c9f58555..46c1b2ac4 100644
--- a/src/org/linphone/LinphonePreferencesActivity.java
+++ b/src/org/linphone/LinphonePreferencesActivity.java
@@ -37,24 +37,26 @@ import java.util.List;
import org.linphone.LinphoneManager.EcCalibrationListener;
import org.linphone.LinphoneManager.LinphoneConfigException;
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.core.LinphoneCoreException;
+import org.linphone.core.Log;
import org.linphone.mediastream.Version;
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration;
import org.linphone.mediastream.video.capture.hwconf.Hacks;
+import android.content.Intent;
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.PreferenceCategory;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
public class LinphonePreferencesActivity extends PreferenceActivity implements EcCalibrationListener {
private Handler mHandler = new Handler();
@@ -62,6 +64,8 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements E
private CheckBoxPreference elPref;
private CheckBoxPreference ecPref;
private ListPreference mencPref;
+ private int nbAccounts = 1;
+ private static final int ADD_SIP_ACCOUNT = 0x666;
private SharedPreferences prefs() {
return getPreferenceManager().getSharedPreferences();
@@ -84,6 +88,78 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements E
findPreference(id).setEnabled(LinphoneManager.getInstance().detectVideoCodec(mime));
}
+ private void createDynamicAccountsPreferences() {
+ PreferenceScreen root = getPreferenceScreen();
+
+ // Get the good preference screen
+ final PreferenceCategory accounts = (PreferenceCategory) root.getPreference(0);
+ accounts.removeAll();
+ Preference addAccount = (Preference) root.getPreference(1);
+ addAccount.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ addExtraAccountPreferencesButton(accounts, nbAccounts, true);
+ Intent i = new Intent();
+ i.putExtra("Account",nbAccounts);
+ nbAccounts++;
+ i.setClass(LinphonePreferencesActivity.this, LinphonePreferencesSIPAccountActivity.class);
+ startActivityForResult(i, ADD_SIP_ACCOUNT);
+ return true;
+ }
+ });
+
+ // Get already configured extra accounts
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ nbAccounts = prefs.getInt(getString(R.string.pref_extra_accounts), 1);
+ for (int i = 0; i < nbAccounts; i++) {
+ // For each, add menus to configure it
+ addExtraAccountPreferencesButton(accounts, i, false);
+ }
+ }
+
+ public int getNbAccountsExtra() {
+ return nbAccounts;
+ }
+
+ private void addExtraAccountPreferencesButton(PreferenceCategory parent, final int n, boolean isNewAccount) {
+ SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+ if (isNewAccount) {
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putInt(getString(R.string.pref_extra_accounts), n+1);
+ editor.commit();
+ }
+
+ Preference me = new Preference(LinphonePreferencesActivity.this);
+ String keyUsername = getString(R.string.pref_username_key);
+ String keyDomain = getString(R.string.pref_domain_key);
+ if (n > 0) {
+ keyUsername += n + "";
+ keyDomain += n + "";
+ }
+ if (prefs.getString(keyUsername, null) == null) {
+ me.setTitle(getString(R.string.pref_sipaccount));
+ } else {
+ me.setTitle(prefs.getString(keyUsername, "") + "@" + prefs.getString(keyDomain, ""));
+ }
+
+ me.setOnPreferenceClickListener(new OnPreferenceClickListener()
+ {
+ public boolean onPreferenceClick(Preference preference) {
+ Intent i = new Intent();
+ i.putExtra("Account", n);
+ i.setClass(LinphonePreferencesActivity.this, LinphonePreferencesSIPAccountActivity.class);
+ startActivityForResult(i, ADD_SIP_ACCOUNT);
+ return false;
+ }
+ });
+ parent.addPreference(me);
+ }
+
+ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ if (requestCode == ADD_SIP_ACCOUNT) {
+ createDynamicAccountsPreferences();
+ }
+ }
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -91,6 +167,7 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements E
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
+ createDynamicAccountsPreferences();
addTransportChecboxesListener();
ecCalibratePref = (CheckBoxPreference) findPreference(pref_echo_canceller_calibration_key);
diff --git a/src/org/linphone/LinphonePreferencesSIPAccountActivity.java b/src/org/linphone/LinphonePreferencesSIPAccountActivity.java
new file mode 100644
index 000000000..47bcfad77
--- /dev/null
+++ b/src/org/linphone/LinphonePreferencesSIPAccountActivity.java
@@ -0,0 +1,133 @@
+package org.linphone;
+
+import org.linphone.core.Log;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.CheckBoxPreference;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.Preference.OnPreferenceClickListener;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceCategory;
+import android.preference.PreferenceScreen;
+import android.text.InputType;
+
+public class LinphonePreferencesSIPAccountActivity extends PreferenceActivity {
+
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.account_preferences);
+
+ PreferenceScreen screen = getPreferenceScreen();
+ int n = getIntent().getExtras().getInt("Account", 1);
+ addExtraAccountPreferencesFields(screen, n);
+ }
+
+ private void addExtraAccountPreferencesFields(PreferenceScreen parent, final int n) {
+ final SharedPreferences prefs = getPreferenceManager().getSharedPreferences();
+
+ PreferenceCategory category = new PreferenceCategory(this);
+ category.setTitle(getString(R.string.pref_sipaccount));
+
+ EditTextPreference username = new EditTextPreference(this);
+ username.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
+ username.setTitle(getString(R.string.pref_username));
+ username.setPersistent(true);
+ username.setKey(getString(R.string.pref_username_key) + getAccountNumber(n));
+
+ EditTextPreference password = new EditTextPreference(this);
+ password.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
+ password.setTitle(getString(R.string.pref_passwd));
+ password.setPersistent(true);
+ password.setKey(getString(R.string.pref_passwd_key) + getAccountNumber(n));
+
+ EditTextPreference domain = new EditTextPreference(this);
+ domain.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
+ domain.setTitle(getString(R.string.pref_domain));
+ domain.setPersistent(true);
+ domain.setKey(getString(R.string.pref_domain_key) + getAccountNumber(n));
+
+ EditTextPreference proxy = new EditTextPreference(this);
+ proxy.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
+ proxy.setTitle(getString(R.string.pref_proxy));
+ proxy.setPersistent(true);
+ proxy.setKey(getString(R.string.pref_proxy_key) + getAccountNumber(n));
+
+ CheckBoxPreference outboundProxy = new CheckBoxPreference(this);
+ outboundProxy.setTitle(getString(R.string.pref_enable_outbound_proxy));
+ outboundProxy.setPersistent(true);
+ outboundProxy.setKey(getString(R.string.pref_enable_outbound_proxy_key) + getAccountNumber(n));
+
+ final Preference delete = new Preference(this);
+ delete.setTitle("Delete this account");
+ delete.setOnPreferenceClickListener(new OnPreferenceClickListener() {
+ public boolean onPreferenceClick(Preference preference) {
+ int nbAccounts = prefs.getInt(getString(R.string.pref_extra_accounts), 1);
+ SharedPreferences.Editor editor = prefs.edit();
+
+ for (int i = n; i < nbAccounts - 1; i++) {
+ editor.putString(getString(R.string.pref_username_key) + i, prefs.getString(getString(R.string.pref_username_key) + (i+1), null));
+ editor.putString(getString(R.string.pref_passwd_key) + i, prefs.getString(getString(R.string.pref_passwd_key) + (i+1), null));
+ editor.putString(getString(R.string.pref_domain_key) + i, prefs.getString(getString(R.string.pref_domain_key) + (i+1), null));
+ editor.putString(getString(R.string.pref_proxy_key) + i, prefs.getString(getString(R.string.pref_proxy_key) + (i+1), null));
+ editor.putBoolean(getString(R.string.pref_enable_outbound_proxy_key) + i, prefs.getBoolean(getString(R.string.pref_enable_outbound_proxy_key) + (i+1), false));
+ }
+
+ int lastAccount = nbAccounts - 1;
+ editor.putString(getString(R.string.pref_username_key) + lastAccount, null);
+ editor.putString(getString(R.string.pref_passwd_key) + lastAccount, null);
+ editor.putString(getString(R.string.pref_domain_key) + lastAccount, null);
+ editor.putString(getString(R.string.pref_proxy_key) + lastAccount, null);
+ editor.putBoolean(getString(R.string.pref_enable_outbound_proxy_key) + lastAccount, false);
+
+ int defaultAccount = prefs.getInt(getString(R.string.pref_default_account), 0);
+ if (defaultAccount > n) {
+ Log.e("Default Account : ", defaultAccount + " => " + (defaultAccount - 1));
+ editor.putInt(getString(R.string.pref_default_account), defaultAccount - 1);
+ }
+
+ editor.putInt(getString(R.string.pref_extra_accounts), nbAccounts - 1);
+ editor.commit();
+ LinphonePreferencesSIPAccountActivity.this.finish();
+ return true;
+ }
+ });
+
+ CheckBoxPreference mainAccount = new CheckBoxPreference(this);
+ mainAccount.setTitle("Use as default");
+ mainAccount.setOnPreferenceClickListener(new OnPreferenceClickListener()
+ {
+ public boolean onPreferenceClick(Preference preference) {
+
+ SharedPreferences.Editor editor = prefs.edit();
+ editor.putInt(getString(R.string.pref_default_account), n);
+ editor.commit();
+ delete.setEnabled(false);
+ preference.setEnabled(false);
+ return true;
+ }
+ });
+
+ mainAccount.setChecked(prefs.getInt(getString(R.string.pref_default_account), 0) == n);
+ mainAccount.setEnabled(!mainAccount.isChecked());
+ delete.setEnabled(prefs.getInt(getString(R.string.pref_default_account), 0) != n);
+
+ parent.addPreference(category);
+ category.addPreference(username);
+ category.addPreference(password);
+ category.addPreference(domain);
+ category.addPreference(proxy);
+ category.addPreference(outboundProxy);
+ category.addPreference(mainAccount);
+ category.addPreference(delete);
+ }
+
+ private String getAccountNumber(int n) {
+ if (n > 0)
+ return n + "";
+ else
+ return "";
+ }
+}
\ No newline at end of file