Feature/release 4.1 new settings

This commit is contained in:
Sylvain Berfini 2019-04-05 17:09:10 +02:00
parent 6fe7d87ac4
commit 08a6375a65
62 changed files with 4334 additions and 3885 deletions

View file

@ -110,7 +110,8 @@ import org.linphone.history.HistoryDetailFragment;
import org.linphone.history.HistoryFragment; import org.linphone.history.HistoryFragment;
import org.linphone.purchase.InAppPurchaseActivity; import org.linphone.purchase.InAppPurchaseActivity;
import org.linphone.recording.RecordingsFragment; import org.linphone.recording.RecordingsFragment;
import org.linphone.settings.AccountPreferencesFragment; import org.linphone.settings.AccountSettingsFragment;
import org.linphone.settings.AudioSettingsFragment;
import org.linphone.settings.LinphonePreferences; import org.linphone.settings.LinphonePreferences;
import org.linphone.settings.SettingsFragment; import org.linphone.settings.SettingsFragment;
import org.linphone.utils.DeviceUtils; import org.linphone.utils.DeviceUtils;
@ -431,8 +432,11 @@ public class LinphoneActivity extends LinphoneGenericActivity
case SETTINGS: case SETTINGS:
mFragment = new SettingsFragment(); mFragment = new SettingsFragment();
break; break;
case SETTINGS_SUBLEVEL:
mFragment = new AudioSettingsFragment();
break;
case ACCOUNT_SETTINGS: case ACCOUNT_SETTINGS:
mFragment = new AccountPreferencesFragment(); mFragment = new AccountSettingsFragment();
break; break;
case ABOUT: case ABOUT:
mFragment = new AboutFragment(); mFragment = new AboutFragment();
@ -469,6 +473,15 @@ public class LinphoneActivity extends LinphoneGenericActivity
break; break;
} }
applyFragmentChanges(newFragmentType, extras);
}
private void changeSettingsFragment(Fragment fragment) {
mFragment = fragment;
applyFragmentChanges(FragmentsAvailable.SETTINGS_SUBLEVEL, null);
}
private void applyFragmentChanges(FragmentsAvailable newFragmentType, Bundle extras) {
if (mFragment != null) { if (mFragment != null) {
mFragment.setArguments(extras); mFragment.setArguments(extras);
if (isTablet()) { if (isTablet()) {
@ -560,6 +573,7 @@ public class LinphoneActivity extends LinphoneGenericActivity
if (newFragmentType == FragmentsAvailable.DIALER if (newFragmentType == FragmentsAvailable.DIALER
|| newFragmentType == FragmentsAvailable.ABOUT || newFragmentType == FragmentsAvailable.ABOUT
|| newFragmentType == FragmentsAvailable.SETTINGS || newFragmentType == FragmentsAvailable.SETTINGS
|| newFragmentType == FragmentsAvailable.SETTINGS_SUBLEVEL
|| newFragmentType == FragmentsAvailable.ACCOUNT_SETTINGS || newFragmentType == FragmentsAvailable.ACCOUNT_SETTINGS
|| newFragmentType == FragmentsAvailable.CREATE_CHAT || newFragmentType == FragmentsAvailable.CREATE_CHAT
|| newFragmentType == FragmentsAvailable.INFO_GROUP_CHAT) { || newFragmentType == FragmentsAvailable.INFO_GROUP_CHAT) {
@ -688,6 +702,10 @@ public class LinphoneActivity extends LinphoneGenericActivity
changeCurrentFragment(FragmentsAvailable.RECORDING_LIST, null); changeCurrentFragment(FragmentsAvailable.RECORDING_LIST, null);
} }
public void displaySubSettings(Fragment fragment) {
changeSettingsFragment(fragment);
}
public void displayContactsForEdition(String sipAddress, String displayName) { public void displayContactsForEdition(String sipAddress, String displayName) {
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putBoolean("EditOnClick", true); extras.putBoolean("EditOnClick", true);
@ -834,7 +852,11 @@ public class LinphoneActivity extends LinphoneGenericActivity
mChatSelected.setVisibility(View.VISIBLE); mChatSelected.setVisibility(View.VISIBLE);
} else if (id == R.id.cancel) { } else if (id == R.id.cancel) {
hideTopBar(); hideTopBar();
displayDialer(); if (mCurrentFragment == FragmentsAvailable.SETTINGS_SUBLEVEL) {
popBackStack();
} else {
displayDialer();
}
} }
} }
@ -867,8 +889,12 @@ public class LinphoneActivity extends LinphoneGenericActivity
mTopBarTitle.setText(title); mTopBarTitle.setText(title);
} }
@SuppressWarnings("incomplete-switch")
public void selectMenu(FragmentsAvailable menuToSelect) { public void selectMenu(FragmentsAvailable menuToSelect) {
selectMenu(menuToSelect, null);
}
@SuppressWarnings("incomplete-switch")
public void selectMenu(FragmentsAvailable menuToSelect, String customTitle) {
mCurrentFragment = menuToSelect; mCurrentFragment = menuToSelect;
resetSelection(); resetSelection();
boolean hideBottomBar = boolean hideBottomBar =
@ -899,7 +925,12 @@ public class LinphoneActivity extends LinphoneGenericActivity
case SETTINGS: case SETTINGS:
case ACCOUNT_SETTINGS: case ACCOUNT_SETTINGS:
hideTabBar(hideBottomBar); hideTabBar(hideBottomBar);
showTopBarWithTitle(getString(R.string.settings)); case SETTINGS_SUBLEVEL:
if (customTitle == null) {
showTopBarWithTitle(getString(R.string.settings));
} else {
showTopBarWithTitle(customTitle);
}
break; break;
case ABOUT: case ABOUT:
showTopBarWithTitle(getString(R.string.about)); showTopBarWithTitle(getString(R.string.about));
@ -1286,9 +1317,7 @@ public class LinphoneActivity extends LinphoneGenericActivity
break; break;
case PERMISSIONS_RECORD_AUDIO_ECHO_CANCELLER: case PERMISSIONS_RECORD_AUDIO_ECHO_CANCELLER:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
((SettingsFragment) mFragment).startEchoCancellerCalibration(); ((AudioSettingsFragment) mFragment).startEchoCancellerCalibration();
} else {
((SettingsFragment) mFragment).echoCalibrationFail();
} }
break; break;
case PERMISSIONS_READ_EXTERNAL_STORAGE_DEVICE_RINGTONE: case PERMISSIONS_READ_EXTERNAL_STORAGE_DEVICE_RINGTONE:
@ -1299,7 +1328,7 @@ public class LinphoneActivity extends LinphoneGenericActivity
break; break;
case PERMISSIONS_RECORD_AUDIO_ECHO_TESTER: case PERMISSIONS_RECORD_AUDIO_ECHO_TESTER:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
((SettingsFragment) mFragment).startEchoTester(); ((AudioSettingsFragment) mFragment).startEchoTester();
break; break;
} }
} }
@ -1389,6 +1418,7 @@ public class LinphoneActivity extends LinphoneGenericActivity
if (mCurrentFragment == FragmentsAvailable.DIALER if (mCurrentFragment == FragmentsAvailable.DIALER
|| mCurrentFragment == FragmentsAvailable.ABOUT || mCurrentFragment == FragmentsAvailable.ABOUT
|| mCurrentFragment == FragmentsAvailable.SETTINGS || mCurrentFragment == FragmentsAvailable.SETTINGS
|| mCurrentFragment == FragmentsAvailable.SETTINGS_SUBLEVEL
|| mCurrentFragment == FragmentsAvailable.ACCOUNT_SETTINGS) { || mCurrentFragment == FragmentsAvailable.ACCOUNT_SETTINGS) {
ll.setVisibility(View.GONE); ll.setVisibility(View.GONE);
} }
@ -1437,11 +1467,11 @@ public class LinphoneActivity extends LinphoneGenericActivity
protected void onNewIntent(Intent intent) { protected void onNewIntent(Intent intent) {
super.onNewIntent(intent); super.onNewIntent(intent);
if (getCurrentFragment() == FragmentsAvailable.SETTINGS) { /*if (getCurrentFragment() == FragmentsAvailable.SETTINGS) {
if (mFragment instanceof SettingsFragment) { if (mFragment instanceof SettingsFragment) {
((SettingsFragment) mFragment).closePreferenceScreen(); ((SettingsFragment) mFragment).closePreferenceScreen();
} }
} }*/
Bundle extras = intent.getExtras(); Bundle extras = intent.getExtras();
if (extras != null) { if (extras != null) {

View file

@ -36,7 +36,6 @@ import android.content.res.Configuration;
import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
@ -66,7 +65,6 @@ import org.linphone.core.Address;
import org.linphone.core.AuthInfo; import org.linphone.core.AuthInfo;
import org.linphone.core.ConfiguringState; import org.linphone.core.ConfiguringState;
import org.linphone.core.Core; import org.linphone.core.Core;
import org.linphone.core.CoreException;
import org.linphone.core.CoreListenerStub; import org.linphone.core.CoreListenerStub;
import org.linphone.core.DialPlan; import org.linphone.core.DialPlan;
import org.linphone.core.Factory; import org.linphone.core.Factory;
@ -78,7 +76,6 @@ import org.linphone.core.tools.OpenH264DownloadHelper;
import org.linphone.fragments.StatusFragment; import org.linphone.fragments.StatusFragment;
import org.linphone.mediastream.Version; import org.linphone.mediastream.Version;
import org.linphone.settings.LinphonePreferences; import org.linphone.settings.LinphonePreferences;
import org.linphone.settings.LinphonePreferences.AccountBuilder;
import org.linphone.utils.LinphoneUtils; import org.linphone.utils.LinphoneUtils;
import org.linphone.utils.ThemableActivity; import org.linphone.utils.ThemableActivity;
@ -515,8 +512,31 @@ public class AssistantActivity extends ThemableActivity
String prefix, String prefix,
String domain, String domain,
TransportType transport) { TransportType transport) {
saveCreatedAccount( Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
username, userid, password, displayname, null, prefix, domain, transport); if (core == null) return;
AuthInfo authInfo =
Factory.instance().createAuthInfo(username, userid, password, null, null, domain);
core.addAuthInfo(authInfo);
ProxyConfig proxyConfig = core.createProxyConfig();
String identity = "sip:" + username + "@" + domain;
Address identityAddr = Factory.instance().createAddress(identity);
if (identityAddr != null) {
identityAddr.setDisplayName(displayname);
proxyConfig.setIdentityAddress(identityAddr);
}
String proxy = "<sip:" + domain + ";transport=" + transport.name().toLowerCase() + ">";
proxyConfig.setServerAddr(proxy);
proxyConfig.setDialPrefix(prefix);
core.addProxyConfig(proxyConfig);
core.setDefaultProxyConfig(proxyConfig);
mAccountCreated = true;
success();
} }
private void display(AssistantFragmentsEnum fragment) { private void display(AssistantFragmentsEnum fragment) {
@ -618,54 +638,6 @@ public class AssistantActivity extends ThemableActivity
goToLinphoneActivity(); goToLinphoneActivity();
} }
private void saveCreatedAccount(
String username,
String userid,
String password,
String displayname,
String ha1,
String prefix,
String domain,
TransportType transport) {
username = LinphoneUtils.getDisplayableUsernameFromAddress(username);
domain = LinphoneUtils.getDisplayableUsernameFromAddress(domain);
String identity = "sip:" + username + "@" + domain;
mAddress = Factory.instance().createAddress(identity);
AccountBuilder builder =
new AccountBuilder(LinphoneManager.getLc())
.setUsername(username)
.setDomain(domain)
.setHa1(ha1)
.setUserid(userid)
.setDisplayName(displayname)
.setPassword(password);
if (prefix != null) {
builder.setPrefix(prefix);
}
String forcedProxy = "";
if (!TextUtils.isEmpty(forcedProxy)) {
builder.setServerAddr(forcedProxy).setOutboundProxyEnabled(true).setAvpfRrInterval(5);
}
if (transport != null) {
builder.setTransport(transport);
}
try {
builder.saveNewAccount();
if (!mNewAccount) {
displayRegistrationInProgressDialog();
}
mAccountCreated = true;
} catch (CoreException e) {
Log.e(e);
}
}
private void displayRegistrationInProgressDialog() { private void displayRegistrationInProgressDialog() {
if (LinphoneManager.getLc().isNetworkReachable()) { if (LinphoneManager.getLc().isNetworkReachable()) {
mProgress = ProgressDialog.show(this, null, null); mProgress = ProgressDialog.show(this, null, null);

View file

@ -31,6 +31,7 @@ public enum FragmentsAvailable {
ABOUT, ABOUT,
ACCOUNT_SETTINGS, ACCOUNT_SETTINGS,
SETTINGS, SETTINGS,
SETTINGS_SUBLEVEL,
CHAT_LIST, CHAT_LIST,
CHAT, CHAT,
CREATE_CHAT, CREATE_CHAT,

View file

@ -1,639 +0,0 @@
package org.linphone.settings;
/*
AccountPreferencesFragment.java
Copyright (C) 2017 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Intent;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.view.WindowManager;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.assistant.AssistantActivity;
import org.linphone.core.AccountCreator;
import org.linphone.core.AccountCreatorListener;
import org.linphone.core.CoreException;
import org.linphone.core.NatPolicy;
import org.linphone.core.ProxyConfig;
import org.linphone.core.tools.Log;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.settings.LinphonePreferences.AccountBuilder;
import org.linphone.utils.LinphoneUtils;
import org.linphone.utils.PushNotificationUtils;
public class AccountPreferencesFragment extends PreferenceFragment
implements AccountCreatorListener {
private int mN;
private final OnPreferenceClickListener linkAccountListener =
new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
Intent assistant = new Intent();
assistant.setClass(LinphoneActivity.instance(), AssistantActivity.class);
assistant.putExtra("LinkPhoneNumber", true);
assistant.putExtra("FromPref", true);
assistant.putExtra("AccountNumber", mN);
startActivity(assistant);
return true;
}
};
private boolean mIsNewAccount = false;
private LinphonePreferences mPrefs;
private final OnPreferenceChangeListener mAvpfRRIntervalChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
try {
int intValue = Integer.parseInt(value);
if ((intValue < 1) || (intValue > 5)) {
return false;
}
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
if (mIsNewAccount) {
// TODO
} else {
mPrefs.setAvpfRrInterval(mN, value);
}
preference.setSummary(value);
return true;
}
};
private final OnPreferenceChangeListener mEscapeChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (mIsNewAccount) {
// TODO
} else {
mPrefs.setReplacePlusByZeroZero(mN, value);
}
return true;
}
};
private final OnPreferenceChangeListener mPushNotificationListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (mIsNewAccount) {
// TODO
} else {
mPrefs.enablePushNotifForProxy(mN, value);
}
return true;
}
};
private final OnPreferenceChangeListener mIceChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (mIsNewAccount) {
} else {
mPrefs.setAccountIce(mN, value);
((CheckBoxPreference) preference).setChecked(mPrefs.getAccountIce(mN));
}
return true;
}
};
private final OnPreferenceChangeListener mStunTurnChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
if (mIsNewAccount) {
} else {
mPrefs.setAccountStunServer(mN, value);
preference.setSummary(value);
}
return true;
}
};
private EditTextPreference mProxyPreference;
private final OnPreferenceChangeListener mTransportChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String key = newValue.toString();
if (mIsNewAccount) {
// TODO
// mBuilder.setTransport(transport);
} else {
mPrefs.setAccountTransport(mN, key);
preference.setSummary(mPrefs.getAccountTransportString(mN));
preference.setDefaultValue(mPrefs.getAccountTransportKey(mN));
if (mProxyPreference != null) {
String newProxy = mPrefs.getAccountProxy(mN);
mProxyPreference.setSummary(newProxy);
mProxyPreference.setText(newProxy);
}
}
return true;
}
};
private ListPreference mTransportPreference;
private AccountBuilder mBuilder;
private final OnPreferenceChangeListener mUsernameChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isEditTextEmpty(newValue.toString())) return false;
if (mIsNewAccount) {
mBuilder.setUsername(newValue.toString());
} else {
mPrefs.setAccountUsername(mN, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
private final OnPreferenceChangeListener mUseridChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (mIsNewAccount) {
mBuilder.setUserid(newValue.toString());
} else {
mPrefs.setAccountUserId(mN, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
private final OnPreferenceChangeListener mPasswordChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isEditTextEmpty(newValue.toString())) return false;
if (mIsNewAccount) {
mBuilder.setPassword(newValue.toString());
} else {
mPrefs.setAccountPassword(mN, newValue.toString());
}
return true;
}
};
private final OnPreferenceChangeListener mDomainChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (isEditTextEmpty(newValue.toString())) return false;
if (mIsNewAccount) {
mBuilder.setDomain(newValue.toString());
} else {
mPrefs.setAccountDomain(mN, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
private final OnPreferenceChangeListener mDisplayNameChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (mIsNewAccount) {
mBuilder.setDisplayName(newValue.toString());
} else {
mPrefs.setAccountDisplayName(mN, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
private final OnPreferenceChangeListener mProxyChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
if (mIsNewAccount) {
mBuilder.setServerAddr(newValue.toString());
preference.setSummary(newValue.toString());
} else {
mPrefs.setAccountProxy(mN, value);
preference.setSummary(mPrefs.getAccountProxy(mN));
if (mTransportPreference != null) {
mTransportPreference.setSummary(mPrefs.getAccountTransportString(mN));
mTransportPreference.setValue(mPrefs.getAccountTransportKey(mN));
}
}
return true;
}
};
private final OnPreferenceChangeListener mOutboundProxyChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (mIsNewAccount) {
mBuilder.setOutboundProxyEnabled((Boolean) newValue);
} else {
mPrefs.setAccountOutboundProxyEnabled(mN, (Boolean) newValue);
}
return true;
}
};
private final OnPreferenceChangeListener mExpiresChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (mIsNewAccount) {
mBuilder.setExpires(newValue.toString());
} else {
mPrefs.setExpires(mN, newValue.toString());
}
preference.setSummary(newValue.toString());
return true;
}
};
private final OnPreferenceChangeListener mPrefixChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String value = newValue.toString();
preference.setSummary(value);
if (mIsNewAccount) {
mBuilder.setPrefix(value);
} else {
mPrefs.setPrefix(mN, value);
}
return true;
}
};
private final OnPreferenceChangeListener mAvpfChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (!mIsNewAccount) {
mPrefs.setAvpfMode(mN, value);
}
return true;
}
};
private final OnPreferenceChangeListener mDisableChangedListener =
new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean value = (Boolean) newValue;
if (mIsNewAccount) {
mBuilder.setEnabled(!value);
} else {
mPrefs.setAccountEnabled(mN, !value);
}
return true;
}
};
private AccountCreator mAccountCreator;
private static boolean isEditTextEmpty(String s) {
return s.equals(""); // really empty.
}
private static void setListPreferenceValues(
ListPreference pref, List<CharSequence> entries, List<CharSequence> values) {
CharSequence[] contents = new CharSequence[entries.size()];
entries.toArray(contents);
pref.setEntries(contents);
contents = new CharSequence[values.size()];
values.toArray(contents);
pref.setEntryValues(contents);
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.account_preferences);
mPrefs = LinphonePreferences.instance();
mN = getArguments().getInt("Account", 0);
if (mN == mPrefs.getAccountCount()) {
mIsNewAccount = true;
mBuilder = new AccountBuilder(LinphoneManager.getLc());
}
initAccountPreferencesFields();
// Force hide keyboard
getActivity()
.getWindow()
.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
private void initAccountPreferencesFields() {
boolean isDefaultAccount = mPrefs.getDefaultAccountIndex() == mN;
NatPolicy natPolicy = null;
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null
&& LinphoneManager.getLc().getProxyConfigList() != null
&& LinphoneManager.getLc().getProxyConfigList().length > mN) {
ProxyConfig proxy = LinphoneManager.getLc().getProxyConfigList()[mN];
natPolicy = proxy.getNatPolicy();
if (natPolicy == null) {
natPolicy = LinphoneManager.getLc().createNatPolicy();
proxy.edit();
proxy.setNatPolicy(natPolicy);
proxy.done();
}
}
mAccountCreator =
LinphoneManager.getLc()
.createAccountCreator(LinphonePreferences.instance().getXmlrpcUrl());
mAccountCreator.setListener(this);
final PreferenceCategory account =
(PreferenceCategory)
getPreferenceScreen()
.findPreference(getString(R.string.pref_sipaccount_key));
EditTextPreference username = (EditTextPreference) account.getPreference(0);
username.setOnPreferenceChangeListener(mUsernameChangedListener);
if (!mIsNewAccount) {
username.setText(mPrefs.getAccountUsername(mN));
username.setSummary(username.getText());
}
EditTextPreference userid = (EditTextPreference) account.getPreference(1);
userid.setOnPreferenceChangeListener(mUseridChangedListener);
if (!mIsNewAccount) {
userid.setText(mPrefs.getAccountUserId(mN));
userid.setSummary(userid.getText());
}
EditTextPreference password = (EditTextPreference) account.getPreference(2);
password.setOnPreferenceChangeListener(mPasswordChangedListener);
if (!mIsNewAccount) {
password.setText(mPrefs.getAccountPassword(mN));
}
EditTextPreference domain = (EditTextPreference) account.getPreference(3);
domain.setOnPreferenceChangeListener(mDomainChangedListener);
if (!mIsNewAccount) {
domain.setText(mPrefs.getAccountDomain(mN));
domain.setSummary(domain.getText());
}
EditTextPreference displayName = (EditTextPreference) account.getPreference(4);
displayName.setOnPreferenceChangeListener(mDisplayNameChangedListener);
if (!mIsNewAccount) {
displayName.setText(mPrefs.getAccountDisplayName(mN));
displayName.setSummary(displayName.getText());
}
PreferenceCategory advanced =
(PreferenceCategory)
getPreferenceScreen().findPreference(getString(R.string.pref_advanced_key));
mTransportPreference = (ListPreference) advanced.getPreference(0);
initializeTransportPreference(mTransportPreference);
mTransportPreference.setOnPreferenceChangeListener(mTransportChangedListener);
if (!mIsNewAccount) {
mTransportPreference.setSummary(mPrefs.getAccountTransportString(mN));
}
CheckBoxPreference ice = (CheckBoxPreference) advanced.getPreference(1);
ice.setOnPreferenceChangeListener(mIceChangedListener);
if (natPolicy != null) ice.setChecked(natPolicy.iceEnabled());
EditTextPreference stunTurn = (EditTextPreference) advanced.getPreference(2);
stunTurn.setOnPreferenceChangeListener(mStunTurnChangedListener);
if (natPolicy != null) {
stunTurn.setText(natPolicy.getStunServer());
stunTurn.setSummary(natPolicy.getStunServer());
}
mProxyPreference = (EditTextPreference) advanced.getPreference(3);
mProxyPreference.setOnPreferenceChangeListener(mProxyChangedListener);
if (!mIsNewAccount) {
mProxyPreference.setText(mPrefs.getAccountProxy(mN));
mProxyPreference.setSummary(
"".equals(mProxyPreference.getText()) || (mProxyPreference.getText() == null)
? getString(R.string.pref_help_proxy)
: mProxyPreference.getText());
}
CheckBoxPreference outboundProxy = (CheckBoxPreference) advanced.getPreference(4);
outboundProxy.setOnPreferenceChangeListener(mOutboundProxyChangedListener);
if (!mIsNewAccount) {
outboundProxy.setChecked(mPrefs.isAccountOutboundProxySet(mN));
}
EditTextPreference expires = (EditTextPreference) advanced.getPreference(5);
expires.setOnPreferenceChangeListener(mExpiresChangedListener);
if (!mIsNewAccount) {
expires.setText(mPrefs.getExpires(mN));
expires.setSummary(mPrefs.getExpires(mN));
}
EditTextPreference prefix = (EditTextPreference) advanced.getPreference(6);
prefix.setOnPreferenceChangeListener(mPrefixChangedListener);
if (!mIsNewAccount) {
String prefixValue = mPrefs.getPrefix(mN);
prefix.setText(prefixValue);
prefix.setSummary(prefixValue);
}
CheckBoxPreference avpf = (CheckBoxPreference) advanced.getPreference(7);
avpf.setOnPreferenceChangeListener(mAvpfChangedListener);
if (!mIsNewAccount) {
avpf.setChecked(mPrefs.avpfEnabled(mN));
}
EditTextPreference avpfRRInterval = (EditTextPreference) advanced.getPreference(8);
avpfRRInterval.setOnPreferenceChangeListener(mAvpfRRIntervalChangedListener);
if (!mIsNewAccount) {
avpfRRInterval.setText(mPrefs.getAvpfRrInterval(mN));
avpfRRInterval.setSummary(mPrefs.getAvpfRrInterval(mN));
}
CheckBoxPreference escape = (CheckBoxPreference) advanced.getPreference(9);
escape.setOnPreferenceChangeListener(mEscapeChangedListener);
if (!mIsNewAccount) {
escape.setChecked(mPrefs.getReplacePlusByZeroZero(mN));
}
Preference linkAccount = advanced.getPreference(10);
linkAccount.setOnPreferenceClickListener(linkAccountListener);
CheckBoxPreference pushNotif = (CheckBoxPreference) advanced.getPreference(11);
pushNotif.setOnPreferenceChangeListener(mPushNotificationListener);
if (!mIsNewAccount) {
pushNotif.setChecked(mPrefs.isPushNotifEnabledForProxy(mN));
}
if (!PushNotificationUtils.isAvailable(getActivity())) {
pushNotif.setLayoutResource(R.layout.hidden);
}
PreferenceCategory manage =
(PreferenceCategory)
getPreferenceScreen().findPreference(getString(R.string.pref_manage_key));
final CheckBoxPreference disable = (CheckBoxPreference) manage.getPreference(0);
disable.setEnabled(true);
disable.setOnPreferenceChangeListener(mDisableChangedListener);
if (!mIsNewAccount) {
disable.setChecked(!mPrefs.isAccountEnabled(mN));
}
CheckBoxPreference mainAccount = (CheckBoxPreference) manage.getPreference(1);
mainAccount.setChecked(isDefaultAccount);
mainAccount.setEnabled(!mainAccount.isChecked());
mainAccount.setOnPreferenceClickListener(
new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
mPrefs.setDefaultAccount(mN);
disable.setEnabled(false);
disable.setChecked(false);
preference.setEnabled(false);
return true;
}
});
if (!mIsNewAccount) {
mainAccount.setEnabled(!mainAccount.isChecked());
}
final Preference changePassword = manage.getPreference(2);
changePassword.setEnabled(false);
final Preference delete = manage.getPreference(3);
delete.setEnabled(!mIsNewAccount);
delete.setOnPreferenceClickListener(
new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
mPrefs.deleteAccount(mN);
LinphoneActivity.instance().displaySettings();
LinphoneActivity.instance().refreshAccounts();
return true;
}
});
}
private void initializeTransportPreference(ListPreference pref) {
List<CharSequence> entries = new ArrayList<>();
List<CharSequence> values = new ArrayList<>();
entries.add(getString(R.string.pref_transport_udp));
values.add(getString(R.string.pref_transport_udp_key));
entries.add(getString(R.string.pref_transport_tcp));
values.add(getString(R.string.pref_transport_tcp_key));
if (!getResources().getBoolean(R.bool.disable_all_security_features_for_markets)) {
entries.add(getString(R.string.pref_transport_tls));
values.add(getString(R.string.pref_transport_tls_key));
}
setListPreferenceValues(pref, entries, values);
if (!mIsNewAccount) {
pref.setSummary(mPrefs.getAccountTransportString(mN));
pref.setDefaultValue(mPrefs.getAccountTransportKey(mN));
pref.setValueIndex(entries.indexOf(mPrefs.getAccountTransportString(mN)));
} else {
pref.setSummary(getString(R.string.pref_transport_udp));
pref.setDefaultValue(getString(R.string.pref_transport_udp));
pref.setValueIndex(entries.indexOf(getString(R.string.pref_transport_udp)));
}
}
@Override
public void onResume() {
super.onResume();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().selectMenu(FragmentsAvailable.ACCOUNT_SETTINGS);
}
}
@Override
public void onPause() {
super.onPause();
if (LinphoneActivity.isInstanciated()) {
try {
if (mIsNewAccount) {
mBuilder.saveNewAccount();
}
} catch (CoreException e) {
Log.e(e);
}
LinphoneActivity.instance().isNewProxyConfig();
LinphoneManager.getLc().refreshRegisters();
LinphoneActivity.instance().hideTopBar();
}
}
@Override
public void onUpdateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {
if (status.equals(AccountCreator.Status.RequestOk)) {
mPrefs.setAccountPassword(mN, accountCreator.getPassword());
PreferenceCategory account =
(PreferenceCategory)
getPreferenceScreen()
.findPreference(getString(R.string.pref_sipaccount_key));
((EditTextPreference) account.getPreference(2)).setText(mPrefs.getAccountPassword(mN));
LinphoneUtils.displayErrorAlert(
getString(R.string.pref_password_changed), LinphoneActivity.instance());
} else {
LinphoneUtils.displayErrorAlert(
LinphoneUtils.errorForStatus(status), LinphoneActivity.instance());
}
}
@Override
public void onIsAccountExist(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onCreateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onLinkAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onActivateAlias(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountActivated(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onRecoverAccount(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAccountLinked(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
@Override
public void onIsAliasUsed(
AccountCreator accountCreator, AccountCreator.Status status, String resp) {}
}

View file

@ -0,0 +1,658 @@
package org.linphone.settings;
/*
AccountSettingsFragment.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.assistant.AssistantActivity;
import org.linphone.core.AVPFMode;
import org.linphone.core.Address;
import org.linphone.core.AuthInfo;
import org.linphone.core.Core;
import org.linphone.core.Factory;
import org.linphone.core.NatPolicy;
import org.linphone.core.ProxyConfig;
import org.linphone.core.TransportType;
import org.linphone.core.tools.Log;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.settings.widget.BasicSetting;
import org.linphone.settings.widget.ListSetting;
import org.linphone.settings.widget.SettingListenerBase;
import org.linphone.settings.widget.SwitchSetting;
import org.linphone.settings.widget.TextSetting;
import org.linphone.utils.PushNotificationUtils;
public class AccountSettingsFragment extends Fragment {
protected View mRootView;
protected LinphonePreferences mPrefs;
private int mAccountIndex;
private ProxyConfig mProxyConfig;
private AuthInfo mAuthInfo;
private boolean mIsNewlyCreatedAccount;
private TextSetting mUsername,
mUserId,
mPassword,
mDomain,
mDisplayName,
mProxy,
mStun,
mExpire,
mPrefix,
mAvpfInterval;
private SwitchSetting mDisable,
mUseAsDefault,
mOutboundProxy,
mIce,
mAvpf,
mReplacePlusBy00,
mPush;
private BasicSetting mChangePassword, mDeleteAccount, mLinkAccount;
private ListSetting mTransport;
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.settings_account, container, false);
loadSettings();
mIsNewlyCreatedAccount = true;
mAccountIndex = getArguments().getInt("Account", -1);
if (mAccountIndex == -1 && savedInstanceState != null) {
mAccountIndex = savedInstanceState.getInt("Account", -1);
}
mProxyConfig = null;
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (mAccountIndex >= 0 && core != null) {
ProxyConfig[] proxyConfigs = core.getProxyConfigList();
if (proxyConfigs.length > mAccountIndex) {
mProxyConfig = proxyConfigs[mAccountIndex];
mIsNewlyCreatedAccount = false;
} else {
Log.e("[Account Settings] Proxy config not found !");
}
}
return mRootView;
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("Account", mAccountIndex);
}
@Override
public void onResume() {
super.onResume();
mPrefs = LinphonePreferences.instance();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance()
.selectMenu(
FragmentsAvailable.SETTINGS_SUBLEVEL,
getString(R.string.pref_sipaccount));
}
updateValues();
}
@Override
public void onPause() {
super.onPause();
if (mIsNewlyCreatedAccount) {
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core != null && mProxyConfig != null && mAuthInfo != null) {
core.addAuthInfo(mAuthInfo);
core.addProxyConfig(mProxyConfig);
if (mUseAsDefault.isChecked()) {
core.setDefaultProxyConfig(mProxyConfig);
}
}
}
}
protected void loadSettings() {
mUsername = mRootView.findViewById(R.id.pref_username);
mUserId = mRootView.findViewById(R.id.pref_auth_userid);
mPassword = mRootView.findViewById(R.id.pref_passwd);
mPassword.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
mDomain = mRootView.findViewById(R.id.pref_domain);
mDisplayName = mRootView.findViewById(R.id.pref_display_name);
mDisplayName.setInputType(
InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PERSON_NAME);
mProxy = mRootView.findViewById(R.id.pref_proxy);
mProxy.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
mStun = mRootView.findViewById(R.id.pref_stun_server);
mStun.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
mExpire = mRootView.findViewById(R.id.pref_expire);
mExpire.setInputType(InputType.TYPE_CLASS_NUMBER);
mPrefix = mRootView.findViewById(R.id.pref_prefix);
mAvpfInterval = mRootView.findViewById(R.id.pref_avpf_rr_interval);
mAvpfInterval.setInputType(InputType.TYPE_CLASS_NUMBER);
mDisable = mRootView.findViewById(R.id.pref_disable_account);
mUseAsDefault = mRootView.findViewById(R.id.pref_default_account);
mOutboundProxy = mRootView.findViewById(R.id.pref_enable_outbound_proxy);
mIce = mRootView.findViewById(R.id.pref_ice_enable);
mAvpf = mRootView.findViewById(R.id.pref_avpf);
mReplacePlusBy00 = mRootView.findViewById(R.id.pref_escape_plus);
mPush = mRootView.findViewById(R.id.pref_push_notification);
mPush.setVisibility(PushNotificationUtils.isAvailable(getActivity()) ? View.VISIBLE : View.GONE);
mChangePassword = mRootView.findViewById(R.id.pref_change_password);
mChangePassword.setVisibility(View.GONE); // TODO
mDeleteAccount = mRootView.findViewById(R.id.pref_delete_account);
mLinkAccount = mRootView.findViewById(R.id.pref_link_account);
mTransport = mRootView.findViewById(R.id.pref_transport);
initTransportList();
}
protected void setListeners() {
mUsername.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mAuthInfo != null) {
mAuthInfo.setUsername(newValue);
} else {
Log.e("[Account Settings] No auth info !");
}
if (mProxyConfig != null) {
mProxyConfig.edit();
Address identity = mProxyConfig.getIdentityAddress();
if (identity != null) {
identity.setUsername(newValue);
}
mProxyConfig.setIdentityAddress(identity);
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mUserId.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mAuthInfo != null) {
mAuthInfo.setUserid(newValue);
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core != null) {
core.refreshRegisters();
}
} else {
Log.e("[Account Settings] No auth info !");
}
}
});
mPassword.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mAuthInfo != null) {
mAuthInfo.setPassword(newValue);
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core != null) {
core.refreshRegisters();
}
} else {
Log.e("[Account Settings] No auth info !");
}
}
});
mDomain.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mAuthInfo != null) {
mAuthInfo.setDomain(newValue);
} else {
Log.e("[Account Settings] No auth info !");
}
if (mProxyConfig != null) {
mProxyConfig.edit();
Address identity = mProxyConfig.getIdentityAddress();
if (identity != null) {
identity.setDomain(newValue);
}
mProxyConfig.setIdentityAddress(identity);
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mDisplayName.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
Address identity = mProxyConfig.getIdentityAddress();
if (identity != null) {
identity.setDisplayName(newValue);
}
mProxyConfig.setIdentityAddress(identity);
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mProxy.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
Address proxy = Factory.instance().createAddress(newValue);
if (proxy != null) {
mProxyConfig.setServerAddr(proxy.asString());
if (mOutboundProxy.isChecked()) {
mProxyConfig.setRoute(proxy.asString());
}
mTransport.setValue(proxy.getTransport().toInt());
}
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mStun.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
NatPolicy natPolicy = mProxyConfig.getNatPolicy();
if (natPolicy != null) {
natPolicy.setStunServer(newValue);
}
if (newValue == null || newValue.isEmpty()) {
mIce.setChecked(false);
}
mIce.setEnabled(newValue != null && !newValue.isEmpty());
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mExpire.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
try {
mProxyConfig.setExpires(Integer.parseInt(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mPrefix.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
mProxyConfig.setDialPrefix(newValue);
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mAvpfInterval.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
try {
mProxyConfig.setAvpfRrInterval(Integer.parseInt(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mDisable.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
mProxyConfig.enableRegister(!newValue);
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mUseAsDefault.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core != null) {
core.setDefaultProxyConfig(mProxyConfig);
}
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mOutboundProxy.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
if (newValue) {
mProxyConfig.setRoute(mProxy.getValue());
} else {
mProxyConfig.setRoute(null);
}
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mIce.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
NatPolicy natPolicy = mProxyConfig.getNatPolicy();
if (natPolicy != null) {
natPolicy.enableIce(newValue);
}
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mAvpf.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
mProxyConfig.setAvpfMode(
newValue ? AVPFMode.Enabled : AVPFMode.Disabled);
mAvpfInterval.setEnabled(mProxyConfig.avpfEnabled());
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mReplacePlusBy00.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
mProxyConfig.setDialEscapePlus(newValue);
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mPush.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
mProxyConfig.setPushNotificationAllowed(newValue);
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
mChangePassword.setListener(
new SettingListenerBase() {
@Override
public void onClicked() {
// TODO
}
});
mDeleteAccount.setListener(
new SettingListenerBase() {
@Override
public void onClicked() {
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core != null) {
if (mProxyConfig != null) {
core.removeProxyConfig(mProxyConfig);
}
if (mAuthInfo != null) {
core.removeAuthInfo(mAuthInfo);
}
}
LinphoneActivity.instance().displaySettings();
LinphoneActivity.instance().refreshAccounts();
}
});
mLinkAccount.setListener(
new SettingListenerBase() {
@Override
public void onClicked() {
Intent assistant = new Intent();
assistant.setClass(LinphoneActivity.instance(), AssistantActivity.class);
assistant.putExtra("LinkPhoneNumber", true);
assistant.putExtra("FromPref", true);
assistant.putExtra("AccountNumber", mAccountIndex);
startActivity(assistant);
}
});
mTransport.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
if (mProxyConfig != null) {
mProxyConfig.edit();
String server = mProxyConfig.getServerAddr();
Address serverAddr = Factory.instance().createAddress(server);
if (serverAddr != null) {
try {
serverAddr.setTransport(
TransportType.fromInt(Integer.parseInt(newValue)));
server = serverAddr.asString();
mProxyConfig.setServerAddr(server);
if (mOutboundProxy.isChecked()) {
mProxyConfig.setRoute(server);
}
mProxy.setValue(server);
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
mProxyConfig.done();
} else {
Log.e("[Account Settings] No proxy config !");
}
}
});
}
protected void updateValues() {
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core == null) return;
// Create a proxy config if there is none
if (mProxyConfig == null) {
// Ensure the default configuration is loaded first
String defaultConfig = LinphoneManager.getInstance().getDefaultDynamicConfigFile();
core.loadConfigFromXml(defaultConfig);
mProxyConfig = core.createProxyConfig();
mAuthInfo = Factory.instance().createAuthInfo(null, null, null, null, null, null);
mIsNewlyCreatedAccount = true;
}
if (mProxyConfig != null) {
Address identityAddress = mProxyConfig.getIdentityAddress();
mAuthInfo = mProxyConfig.findAuthInfo();
NatPolicy natPolicy = mProxyConfig.getNatPolicy();
if (natPolicy == null) {
natPolicy = core.createNatPolicy();
core.setNatPolicy(natPolicy);
}
if (mAuthInfo != null) {
mUserId.setValue(mAuthInfo.getUserid());
// If password is hashed we can't display it
mPassword.setValue(mAuthInfo.getPassword());
}
mUsername.setValue(identityAddress.getUsername());
mDomain.setValue(identityAddress.getDomain());
mDisplayName.setValue(identityAddress.getDisplayName());
mProxy.setValue(mProxyConfig.getServerAddr());
mStun.setValue(natPolicy.getStunServer());
mExpire.setValue(mProxyConfig.getExpires());
mPrefix.setValue(mProxyConfig.getDialPrefix());
mAvpfInterval.setValue(mProxyConfig.getAvpfRrInterval());
mAvpfInterval.setEnabled(mProxyConfig.avpfEnabled());
mDisable.setChecked(!mProxyConfig.registerEnabled());
mUseAsDefault.setChecked(
core != null && mProxyConfig.equals(core.getDefaultProxyConfig()));
mOutboundProxy.setChecked(mProxyConfig.getRoute() != null);
mIce.setChecked(natPolicy.iceEnabled());
mIce.setEnabled(
natPolicy.getStunServer() != null && !natPolicy.getStunServer().isEmpty());
mAvpf.setChecked(mProxyConfig.avpfEnabled());
mReplacePlusBy00.setChecked(mProxyConfig.getDialEscapePlus());
mPush.setChecked(mProxyConfig.isPushNotificationAllowed());
Address proxy = Factory.instance().createAddress(mProxyConfig.getServerAddr());
if (proxy != null) {
mTransport.setValue(proxy.getTransport().toInt());
}
}
setListeners();
}
private void initTransportList() {
List<String> entries = new ArrayList<>();
List<String> values = new ArrayList<>();
entries.add(getString(R.string.pref_transport_udp));
values.add(String.valueOf(TransportType.Udp.toInt()));
entries.add(getString(R.string.pref_transport_tcp));
values.add(String.valueOf(TransportType.Tcp.toInt()));
if (!getResources().getBoolean(R.bool.disable_all_security_features_for_markets)) {
entries.add(getString(R.string.pref_transport_tls));
values.add(String.valueOf(TransportType.Tls.toInt()));
}
mTransport.setItems(entries, values);
}
}

View file

@ -0,0 +1,232 @@
package org.linphone.settings;
/*
AdvancedSettingsFragment.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import org.linphone.LinphoneActivity;
import org.linphone.R;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.settings.widget.BasicSetting;
import org.linphone.settings.widget.SettingListenerBase;
import org.linphone.settings.widget.SwitchSetting;
import org.linphone.settings.widget.TextSetting;
public class AdvancedSettingsFragment extends Fragment {
protected View mRootView;
protected LinphonePreferences mPrefs;
private SwitchSetting mDebug,
mJavaLogger,
mFriendListSubscribe,
mBackgroundMode,
mForegroundService,
mStartAtBoot,
mDarkMode;
private TextSetting mRemoteProvisioningUrl, mDisplayName, mUsername;
private BasicSetting mAndroidAppSettings;
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.settings_advanced, container, false);
loadSettings();
return mRootView;
}
@Override
public void onResume() {
super.onResume();
mPrefs = LinphonePreferences.instance();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance()
.selectMenu(
FragmentsAvailable.SETTINGS_SUBLEVEL,
getString(R.string.pref_advanced_title));
}
updateValues();
}
protected void loadSettings() {
mDebug = mRootView.findViewById(R.id.pref_debug);
mJavaLogger = mRootView.findViewById(R.id.pref_java_debug);
// This is only required for blackberry users for all we know
mJavaLogger.setVisibility(
Build.MANUFACTURER.equals("BlackBerry") ? View.VISIBLE : View.GONE);
mFriendListSubscribe = mRootView.findViewById(R.id.pref_friendlist_subscribe);
mBackgroundMode = mRootView.findViewById(R.id.pref_background_mode);
mForegroundService = mRootView.findViewById(R.id.pref_service_notification);
mStartAtBoot = mRootView.findViewById(R.id.pref_autostart);
mDarkMode = mRootView.findViewById(R.id.pref_dark_mode);
mRemoteProvisioningUrl = mRootView.findViewById(R.id.pref_remote_provisioning);
mRemoteProvisioningUrl.setInputType(
InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
mDisplayName = mRootView.findViewById(R.id.pref_display_name);
mUsername = mRootView.findViewById(R.id.pref_user_name);
mAndroidAppSettings = mRootView.findViewById(R.id.pref_android_app_settings);
}
protected void setListeners() {
mDebug.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setDebugEnabled(newValue);
}
});
mJavaLogger.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setJavaLogger(newValue);
}
});
mFriendListSubscribe.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enabledFriendlistSubscription(newValue);
}
});
mBackgroundMode.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setBackgroundModeEnabled(newValue);
}
});
mForegroundService.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setServiceNotificationVisibility(newValue);
}
});
mStartAtBoot.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setAutoStart(newValue);
}
});
mDarkMode.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enableDarkMode(newValue);
}
});
mRemoteProvisioningUrl.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setRemoteProvisioningUrl(newValue);
}
});
mDisplayName.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setDefaultDisplayName(newValue);
}
});
mUsername.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setDefaultUsername(newValue);
}
});
mAndroidAppSettings.setListener(
new SettingListenerBase() {
@Override
public void onClicked() {
Context context = LinphoneActivity.instance();
Intent i = new Intent();
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.setData(Uri.parse("package:" + context.getPackageName()));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivityForResult(i, LinphoneActivity.ANDROID_APP_SETTINGS_ACTIVITY);
}
});
}
protected void updateValues() {
mDebug.setChecked(mPrefs.isDebugEnabled());
mJavaLogger.setChecked(mPrefs.useJavaLogger());
mFriendListSubscribe.setChecked(mPrefs.isFriendlistsubscriptionEnabled());
mBackgroundMode.setChecked(mPrefs.isBackgroundModeEnabled());
mForegroundService.setChecked(mPrefs.getServiceNotificationVisibility());
mStartAtBoot.setChecked(mPrefs.isAutoStartEnabled());
mDarkMode.setChecked(mPrefs.isDarkModeEnabled());
mRemoteProvisioningUrl.setValue(mPrefs.getRemoteProvisioningUrl());
mDisplayName.setValue(mPrefs.getDefaultDisplayName());
mUsername.setValue(mPrefs.getDefaultUsername());
setListeners();
}
}

View file

@ -0,0 +1,294 @@
package org.linphone.settings;
/*
AudioSettingsFragment.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.Manifest;
import android.app.Fragment;
import android.content.Context;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.core.EcCalibratorStatus;
import org.linphone.core.PayloadType;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.settings.widget.BasicSetting;
import org.linphone.settings.widget.ListSetting;
import org.linphone.settings.widget.SettingListenerBase;
import org.linphone.settings.widget.SwitchSetting;
import org.linphone.settings.widget.TextSetting;
public class AudioSettingsFragment extends Fragment {
protected View mRootView;
protected LinphonePreferences mPrefs;
private SwitchSetting mEchoCanceller, mAdaptiveRateControl;
private TextSetting mMicGain, mSpeakerGain;
private ListSetting mCodecBitrateLimit;
private BasicSetting mEchoCalibration, mEchoTester;
private LinearLayout mAudioCodecs;
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.settings_audio, container, false);
loadSettings();
return mRootView;
}
@Override
public void onResume() {
super.onResume();
mPrefs = LinphonePreferences.instance();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance()
.selectMenu(
FragmentsAvailable.SETTINGS_SUBLEVEL,
getString(R.string.pref_audio_title));
}
updateValues();
}
protected void loadSettings() {
mEchoCanceller = mRootView.findViewById(R.id.pref_echo_cancellation);
mAdaptiveRateControl = mRootView.findViewById(R.id.pref_adaptive_rate_control);
mMicGain = mRootView.findViewById(R.id.pref_mic_gain_db);
mMicGain.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
mSpeakerGain = mRootView.findViewById(R.id.pref_playback_gain_db);
mSpeakerGain.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
mCodecBitrateLimit = mRootView.findViewById(R.id.pref_codec_bitrate_limit);
mEchoCalibration = mRootView.findViewById(R.id.pref_echo_canceller_calibration);
mEchoTester = mRootView.findViewById(R.id.pref_echo_tester);
mAudioCodecs = mRootView.findViewById(R.id.pref_audio_codecs);
}
protected void setListeners() {
mEchoCanceller.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setEchoCancellation(newValue);
}
});
mAdaptiveRateControl.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enableAdaptiveRateControl(newValue);
}
});
mMicGain.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setMicGainDb(Float.valueOf(newValue));
}
});
mSpeakerGain.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setPlaybackGainDb(Float.valueOf(newValue));
}
});
mCodecBitrateLimit.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
int bitrate = Integer.valueOf(newValue);
mPrefs.setCodecBitrateLimit(bitrate);
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
for (final PayloadType pt : core.getAudioPayloadTypes()) {
if (pt.isVbr()) {
pt.setNormalBitrate(bitrate);
}
}
}
});
mEchoCalibration.setListener(
new SettingListenerBase() {
@Override
public void onClicked() {
mEchoCalibration.setSubtitle(getString(R.string.ec_calibrating));
int recordAudio =
getActivity()
.getPackageManager()
.checkPermission(
Manifest.permission.RECORD_AUDIO,
getActivity().getPackageName());
if (recordAudio == PackageManager.PERMISSION_GRANTED) {
startEchoCancellerCalibration();
} else {
LinphoneActivity.instance()
.checkAndRequestRecordAudioPermissionForEchoCanceller();
}
}
});
mEchoTester.setListener(
new SettingListenerBase() {
@Override
public void onClicked() {
int recordAudio =
getActivity()
.getPackageManager()
.checkPermission(
Manifest.permission.RECORD_AUDIO,
getActivity().getPackageName());
if (recordAudio == PackageManager.PERMISSION_GRANTED) {
if (LinphoneManager.getInstance().getEchoTesterStatus()) {
stopEchoTester();
} else {
startEchoTester();
}
} else {
LinphoneActivity.instance()
.checkAndRequestRecordAudioPermissionsForEchoTester();
}
}
});
}
protected void updateValues() {
mEchoCanceller.setChecked(mPrefs.echoCancellationEnabled());
mAdaptiveRateControl.setChecked(mPrefs.adaptiveRateControlEnabled());
mMicGain.setValue(mPrefs.getMicGainDb());
mSpeakerGain.setValue(mPrefs.getPlaybackGainDb());
mCodecBitrateLimit.setValue(mPrefs.getCodecBitrateLimit());
if (mPrefs.echoCancellationEnabled()) {
mEchoCalibration.setSubtitle(
String.format(
getString(R.string.ec_calibrated),
String.valueOf(mPrefs.getEchoCalibration())));
}
populateAudioCodecs();
setListeners();
}
private void populateAudioCodecs() {
mAudioCodecs.removeAllViews();
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core != null) {
for (final PayloadType pt : core.getAudioPayloadTypes()) {
final SwitchSetting codec = new SwitchSetting(getActivity());
codec.setTitle(pt.getMimeType());
/* Special case */
if (pt.getMimeType().equals("mpeg4-generic")) {
codec.setTitle("AAC-ELD");
}
codec.setSubtitle(pt.getClockRate() + " Hz");
if (pt.enabled()) {
// Never use codec.setChecked(pt.enabled) !
codec.setChecked(true);
}
codec.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
pt.enable(newValue);
}
});
mAudioCodecs.addView(codec);
}
}
}
public void startEchoTester() {
if (LinphoneManager.getInstance().startEchoTester() > 0) {
mEchoTester.setSubtitle("Is running");
}
}
private void stopEchoTester() {
if (LinphoneManager.getInstance().stopEchoTester() > 0) {
mEchoTester.setSubtitle("Is stopped");
}
}
public void startEchoCancellerCalibration() {
if (LinphoneManager.getInstance().getEchoTesterStatus()) stopEchoTester();
LinphoneManager.getLc()
.addListener(
new CoreListenerStub() {
@Override
public void onEcCalibrationResult(
Core core, EcCalibratorStatus status, int delayMs) {
if (status == EcCalibratorStatus.InProgress) return;
core.removeListener(this);
LinphoneManager.getInstance().routeAudioToReceiver();
if (status == EcCalibratorStatus.DoneNoEcho) {
mEchoCalibration.setSubtitle(getString(R.string.no_echo));
} else if (status == EcCalibratorStatus.Done) {
mEchoCalibration.setSubtitle(
String.format(
getString(R.string.ec_calibrated),
String.valueOf(delayMs)));
} else if (status == EcCalibratorStatus.Failed) {
mEchoCalibration.setSubtitle(getString(R.string.failed));
}
mEchoCanceller.setChecked(status != EcCalibratorStatus.DoneNoEcho);
((AudioManager)
getActivity()
.getSystemService(Context.AUDIO_SERVICE))
.setMode(AudioManager.MODE_NORMAL);
}
});
LinphoneManager.getInstance().startEcCalibration();
}
}

View file

@ -0,0 +1,252 @@
package org.linphone.settings;
/*
CallSettingsFragment.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Fragment;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.core.Core;
import org.linphone.core.MediaEncryption;
import org.linphone.core.tools.Log;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.settings.widget.ListSetting;
import org.linphone.settings.widget.SettingListenerBase;
import org.linphone.settings.widget.SwitchSetting;
import org.linphone.settings.widget.TextSetting;
public class CallSettingsFragment extends Fragment {
protected View mRootView;
protected LinphonePreferences mPrefs;
private SwitchSetting mDeviceRingtone,
mVibrateIncomingCall,
mDtmfSipInfo,
mDtmfRfc2833,
mAutoAnswer;
private ListSetting mMediaEncryption;
private TextSetting mAutoAnswerTime, mIncomingCallTimeout, mVoiceMailUri;
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.settings_call, container, false);
loadSettings();
return mRootView;
}
@Override
public void onResume() {
super.onResume();
mPrefs = LinphonePreferences.instance();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance()
.selectMenu(
FragmentsAvailable.SETTINGS_SUBLEVEL,
getString(R.string.pref_call_title));
}
updateValues();
}
protected void loadSettings() {
mDeviceRingtone = mRootView.findViewById(R.id.pref_device_ringtone);
mVibrateIncomingCall = mRootView.findViewById(R.id.pref_vibrate_on_incoming_calls);
mDtmfSipInfo = mRootView.findViewById(R.id.pref_sipinfo_dtmf);
mDtmfRfc2833 = mRootView.findViewById(R.id.pref_rfc2833_dtmf);
mAutoAnswer = mRootView.findViewById(R.id.pref_auto_answer);
mMediaEncryption = mRootView.findViewById(R.id.pref_media_encryption);
initMediaEncryptionList();
mAutoAnswerTime = mRootView.findViewById(R.id.pref_auto_answer_time);
mAutoAnswerTime.setInputType(InputType.TYPE_CLASS_NUMBER);
mIncomingCallTimeout = mRootView.findViewById(R.id.pref_incoming_call_timeout);
mAutoAnswerTime.setInputType(InputType.TYPE_CLASS_NUMBER);
mVoiceMailUri = mRootView.findViewById(R.id.pref_voice_mail);
mAutoAnswerTime.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
}
protected void setListeners() {
mDeviceRingtone.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enableDeviceRingtone(newValue);
}
});
mVibrateIncomingCall.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enableIncomingCallVibration(newValue);
}
});
mDtmfSipInfo.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (newValue) mDtmfRfc2833.setChecked(false);
mPrefs.sendDTMFsAsSipInfo(newValue);
}
});
mDtmfRfc2833.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (newValue) mDtmfSipInfo.setChecked(false);
mPrefs.sendDtmfsAsRfc2833(newValue);
}
});
mAutoAnswer.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enableAutoAnswer(newValue);
mAutoAnswerTime.setEnabled(mPrefs.isAutoAnswerEnabled());
}
});
mMediaEncryption.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
try {
mPrefs.setMediaEncryption(
MediaEncryption.fromInt(Integer.parseInt(newValue)));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
mAutoAnswerTime.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
try {
mPrefs.setAutoAnswerTime(Integer.parseInt(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
mIncomingCallTimeout.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
try {
mPrefs.setIncTimeout(Integer.parseInt(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
mVoiceMailUri.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setVoiceMailUri(newValue);
}
});
}
protected void updateValues() {
mDeviceRingtone.setChecked(mPrefs.isDeviceRingtoneEnabled());
mVibrateIncomingCall.setChecked(mPrefs.isIncomingCallVibrationEnabled());
mDtmfSipInfo.setChecked(mPrefs.useSipInfoDtmfs());
mDtmfRfc2833.setChecked(mPrefs.useRfc2833Dtmfs());
mAutoAnswer.setChecked(mPrefs.isAutoAnswerEnabled());
mMediaEncryption.setValue(mPrefs.getMediaEncryption().toInt());
mAutoAnswerTime.setValue(mPrefs.getAutoAnswerTime());
mAutoAnswerTime.setEnabled(mPrefs.isAutoAnswerEnabled());
mIncomingCallTimeout.setValue(mPrefs.getIncTimeout());
mVoiceMailUri.setValue(mPrefs.getVoiceMailUri());
setListeners();
}
private void initMediaEncryptionList() {
List<String> entries = new ArrayList<>();
List<String> values = new ArrayList<>();
entries.add(getString(R.string.pref_none));
values.add(String.valueOf(MediaEncryption.None.toInt()));
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core != null
&& !getResources().getBoolean(R.bool.disable_all_security_features_for_markets)) {
boolean hasZrtp = core.mediaEncryptionSupported(MediaEncryption.ZRTP);
boolean hasSrtp = core.mediaEncryptionSupported(MediaEncryption.SRTP);
boolean hasDtls = core.mediaEncryptionSupported(MediaEncryption.DTLS);
if (!hasSrtp && !hasZrtp && !hasDtls) {
mMediaEncryption.setEnabled(false);
} else {
if (hasSrtp) {
entries.add("SRTP");
values.add(String.valueOf(MediaEncryption.SRTP.toInt()));
}
if (hasZrtp) {
entries.add("ZRTP");
values.add(String.valueOf(MediaEncryption.ZRTP.toInt()));
}
if (hasDtls) {
entries.add("DTLS");
values.add(String.valueOf(MediaEncryption.DTLS.toInt()));
}
}
}
mMediaEncryption.setItems(entries, values);
}
}

View file

@ -0,0 +1,172 @@
package org.linphone.settings;
/*
ChatSettingsFragment.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import org.linphone.LinphoneActivity;
import org.linphone.R;
import org.linphone.core.tools.Log;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.mediastream.Version;
import org.linphone.settings.widget.BasicSetting;
import org.linphone.settings.widget.ListSetting;
import org.linphone.settings.widget.SettingListenerBase;
import org.linphone.settings.widget.TextSetting;
public class ChatSettingsFragment extends Fragment {
protected View mRootView;
protected LinphonePreferences mPrefs;
private TextSetting mSharingServer, mMaxSizeForAutoDownloadIncomingFiles;
private BasicSetting mAndroidNotificationSettings;
private ListSetting mAutoDownloadIncomingFilesPolicy;
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.settings_chat, container, false);
loadSettings();
return mRootView;
}
@Override
public void onResume() {
super.onResume();
mPrefs = LinphonePreferences.instance();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance()
.selectMenu(
FragmentsAvailable.SETTINGS_SUBLEVEL,
getString(R.string.pref_chat_title));
}
updateValues();
}
protected void loadSettings() {
mSharingServer = mRootView.findViewById(R.id.pref_image_sharing_server);
mSharingServer.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
mMaxSizeForAutoDownloadIncomingFiles =
mRootView.findViewById(R.id.pref_auto_download_max_size);
mAutoDownloadIncomingFilesPolicy = mRootView.findViewById(R.id.pref_auto_download_policy);
mAndroidNotificationSettings = mRootView.findViewById(R.id.pref_android_app_notif_settings);
}
protected void setListeners() {
mSharingServer.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setSharingPictureServerUrl(newValue);
}
});
mAutoDownloadIncomingFilesPolicy.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
try {
int max_size = Integer.valueOf(newValue);
mPrefs.setAutoDownloadFileMaxSize(max_size);
updateAutoDownloadSettingsFromValue(max_size);
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
mMaxSizeForAutoDownloadIncomingFiles.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
try {
mPrefs.setAutoDownloadFileMaxSize(Integer.valueOf(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
mAndroidNotificationSettings.setListener(
new SettingListenerBase() {
@Override
public void onClicked() {
if (Build.VERSION.SDK_INT >= Version.API26_O_80) {
Context context = LinphoneActivity.instance();
Intent i = new Intent();
i.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
i.putExtra(Settings.EXTRA_APP_PACKAGE, context.getPackageName());
i.putExtra(
Settings.EXTRA_CHANNEL_ID,
context.getString(R.string.notification_channel_id));
i.addCategory(Intent.CATEGORY_DEFAULT);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
startActivity(i);
}
}
});
}
protected void updateValues() {
mSharingServer.setValue(mPrefs.getSharingPictureServerUrl());
updateAutoDownloadSettingsFromValue(mPrefs.getAutoDownloadFileMaxSize());
if (Version.sdkStrictlyBelow(Version.API26_O_80)) {
mAndroidNotificationSettings.setVisibility(View.GONE);
}
setListeners();
}
private void updateAutoDownloadSettingsFromValue(int max_size) {
if (max_size == -1) {
mAutoDownloadIncomingFilesPolicy.setValue(
getString(R.string.pref_auto_download_policy_disabled_key));
} else if (max_size == 0) {
mAutoDownloadIncomingFilesPolicy.setValue(
getString(R.string.pref_auto_download_policy_always_key));
} else {
mAutoDownloadIncomingFilesPolicy.setValue(
getString(R.string.pref_auto_download_policy_size_key));
}
mMaxSizeForAutoDownloadIncomingFiles.setValue(max_size);
mMaxSizeForAutoDownloadIncomingFiles.setVisibility(max_size > 0 ? View.VISIBLE : View.GONE);
}
}

View file

@ -29,19 +29,17 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.util.ArrayList; import java.util.ArrayList;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager; import org.linphone.LinphoneManager;
import org.linphone.R; import org.linphone.R;
import org.linphone.core.AVPFMode;
import org.linphone.core.Address; import org.linphone.core.Address;
import org.linphone.core.AuthInfo; import org.linphone.core.AuthInfo;
import org.linphone.core.Config; import org.linphone.core.Config;
import org.linphone.core.Core; import org.linphone.core.Core;
import org.linphone.core.CoreException;
import org.linphone.core.Factory; import org.linphone.core.Factory;
import org.linphone.core.MediaEncryption; import org.linphone.core.MediaEncryption;
import org.linphone.core.NatPolicy; import org.linphone.core.NatPolicy;
import org.linphone.core.ProxyConfig; import org.linphone.core.ProxyConfig;
import org.linphone.core.TransportType;
import org.linphone.core.Transports; import org.linphone.core.Transports;
import org.linphone.core.Tunnel; import org.linphone.core.Tunnel;
import org.linphone.core.TunnelConfig; import org.linphone.core.TunnelConfig;
@ -150,311 +148,21 @@ public class LinphonePreferences {
return getLc().findAuthInfo(null, addr.getUsername(), addr.getDomain()); return getLc().findAuthInfo(null, addr.getUsername(), addr.getDomain());
} }
/**
* Removes a authInfo from the core and returns a copy of it. Useful to edit a authInfo (you
* should call saveAuthInfo after the modifications to save them).
*/
private AuthInfo getClonedAuthInfo(int n) {
if (getLc() == null) return null;
AuthInfo authInfo = getAuthInfo(n);
if (authInfo == null) return null;
AuthInfo cloneAuthInfo = authInfo.clone();
getLc().removeAuthInfo(authInfo);
return cloneAuthInfo;
}
/** Saves a authInfo into the core. Useful to save the changes made to a cloned authInfo. */
private void saveAuthInfo(AuthInfo authInfo) {
if (getLc() == null) return;
getLc().addAuthInfo(authInfo);
}
public void setAccountTransport(int n, String transport) {
ProxyConfig proxyConfig = getProxyConfig(n);
if (proxyConfig != null && transport != null) {
Address proxyAddr;
proxyAddr = Factory.instance().createAddress(proxyConfig.getServerAddr());
int port = 0;
if (transport.equals(getString(R.string.pref_transport_udp_key))) {
proxyAddr.setTransport(TransportType.Udp);
} else if (transport.equals(getString(R.string.pref_transport_tcp_key))) {
proxyAddr.setTransport(TransportType.Tcp);
} else if (transport.equals(getString(R.string.pref_transport_tls_key))) {
proxyAddr.setTransport(TransportType.Tls);
port = 5223;
}
/* 3G mobile firewall might block random TLS port, so we force use of 5223.
* However we must NOT use this port when changing to TCP/UDP because otherwise
* REGISTER (and everything actually) will fail...
* */
if ("sip.linphone.org".equals(proxyConfig.getDomain())) {
proxyAddr.setPort(port);
}
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
prxCfg.setServerAddr(proxyAddr.asStringUriOnly());
prxCfg.done();
if (isAccountOutboundProxySet(n)) {
setAccountOutboundProxyEnabled(n, true);
}
}
}
private TransportType getAccountTransport(int n) {
TransportType transport = null;
ProxyConfig proxyConfig = getProxyConfig(n);
if (proxyConfig != null) {
Address proxyAddr;
proxyAddr = Factory.instance().createAddress(proxyConfig.getServerAddr());
transport = proxyAddr.getTransport();
}
return transport;
}
public String getAccountTransportKey(int n) {
TransportType transport = getAccountTransport(n);
String key = getString(R.string.pref_transport_udp_key);
if (transport != null && transport == TransportType.Tcp)
key = getString(R.string.pref_transport_tcp_key);
else if (transport != null && transport == TransportType.Tls)
key = getString(R.string.pref_transport_tls_key);
return key;
}
public String getAccountTransportString(int n) {
TransportType transport = getAccountTransport(n);
if (transport != null && transport == TransportType.Tcp)
return getString(R.string.pref_transport_tcp);
else if (transport != null && transport == TransportType.Tls)
return getString(R.string.pref_transport_tls);
return getString(R.string.pref_transport_udp);
}
public void setAccountUsername(int n, String username) {
String identity = "sip:" + username + "@" + getAccountDomain(n);
AuthInfo old_info = getAuthInfo(n);
ProxyConfig prxCfg = getProxyConfig(n);
if (prxCfg == null) {
Log.e("Error, no proxy config at index " + n);
return;
}
prxCfg.edit();
prxCfg.setIdentityAddress(Factory.instance().createAddress(identity));
prxCfg.enableRegister(true);
prxCfg.done();
if (old_info != null) {
// We have to remove the previous auth info after otherwise we can't unregister the
// previous proxy config
AuthInfo new_info = old_info.clone();
getLc().removeAuthInfo(old_info);
new_info.setUsername(username);
saveAuthInfo(new_info);
}
}
public String getAccountUsername(int n) { public String getAccountUsername(int n) {
AuthInfo authInfo = getAuthInfo(n); AuthInfo authInfo = getAuthInfo(n);
return authInfo == null ? null : authInfo.getUsername(); return authInfo == null ? null : authInfo.getUsername();
} }
public void setAccountDisplayName(int n, String displayName) {
try {
ProxyConfig prxCfg = getProxyConfig(n);
Address addr = prxCfg.getIdentityAddress();
addr.setDisplayName(displayName);
prxCfg.edit();
prxCfg.setIdentityAddress(addr);
prxCfg.done();
} catch (Exception e) {
Log.e(e);
}
}
public String getAccountDisplayName(int n) {
if (getProxyConfig(n) == null || getProxyConfig(n).getIdentityAddress() == null)
return null;
return getProxyConfig(n).getIdentityAddress().getDisplayName();
}
public void setAccountUserId(int n, String userId) {
AuthInfo info = getClonedAuthInfo(n);
if (info != null) {
info.setUserid(userId);
saveAuthInfo(info);
}
}
public String getAccountUserId(int n) {
AuthInfo authInfo = getAuthInfo(n);
return authInfo == null ? null : authInfo.getUserid();
}
private String getAccountRealm(int n) {
AuthInfo authInfo = getAuthInfo(n);
return authInfo == null ? null : authInfo.getRealm();
}
public void setAccountPassword(int n, String password) {
if (getLc() == null) return;
String user = getAccountUsername(n);
String domain = getAccountDomain(n);
String userid = null;
String realm = null;
if (user != null && domain != null) {
if (LinphoneManager.getLc().getAuthInfoList().length > n
&& LinphoneManager.getLc().getAuthInfoList()[n] != null) {
userid = getAccountUserId(n);
realm = getAccountRealm(n);
LinphoneManager.getLc()
.removeAuthInfo(LinphoneManager.getLc().getAuthInfoList()[n]);
}
AuthInfo authInfo =
Factory.instance().createAuthInfo(user, userid, password, null, realm, domain);
LinphoneManager.getLc().addAuthInfo(authInfo);
}
}
public String getAccountPassword(int n) {
AuthInfo authInfo = getAuthInfo(n);
return authInfo == null ? null : authInfo.getPassword();
}
public String getAccountHa1(int n) { public String getAccountHa1(int n) {
AuthInfo authInfo = getAuthInfo(n); AuthInfo authInfo = getAuthInfo(n);
return authInfo == null ? null : authInfo.getHa1(); return authInfo == null ? null : authInfo.getHa1();
} }
public void setAccountIce(int n, boolean ice) {
try {
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
prxCfg.getNatPolicy().enableIce(ice);
prxCfg.getNatPolicy().enableStun(ice);
prxCfg.done();
} catch (Exception e) {
Log.e(e);
}
}
public boolean getAccountIce(int n) {
if (getProxyConfig(n) == null || getProxyConfig(n).getNatPolicy() == null) return false;
return getProxyConfig(n).getNatPolicy().iceEnabled();
}
public void setAccountStunServer(int n, String stun) {
try {
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
NatPolicy np = prxCfg.getNatPolicy();
np.setStunServer(stun);
prxCfg.done();
} catch (Exception e) {
Log.e(e);
}
}
public void setAccountDomain(int n, String domain) {
String identity = "sip:" + getAccountUsername(n) + "@" + domain;
AuthInfo old_info = getAuthInfo(n);
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
prxCfg.setIdentityAddress(Factory.instance().createAddress(identity));
prxCfg.enableRegister(true);
prxCfg.done();
if (old_info != null) {
// We have to remove the previous auth info after otherwise we can't unregister the
// previous proxy config
AuthInfo new_info = old_info.clone();
getLc().removeAuthInfo(old_info);
new_info.setDomain(domain);
saveAuthInfo(new_info);
}
}
public String getAccountDomain(int n) { public String getAccountDomain(int n) {
ProxyConfig proxyConf = getProxyConfig(n); ProxyConfig proxyConf = getProxyConfig(n);
return (proxyConf != null) ? proxyConf.getDomain() : ""; return (proxyConf != null) ? proxyConf.getDomain() : "";
} }
public void setAccountProxy(int n, String proxy) {
if (proxy == null || proxy.length() <= 0) {
proxy = getAccountDomain(n);
}
if (!proxy.contains("sip:")) {
proxy = "sip:" + proxy;
}
Address proxyAddr = Factory.instance().createAddress(proxy);
if (proxyAddr == null) return;
if (!proxy.contains("transport=")) {
proxyAddr.setTransport(getAccountTransport(n));
}
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
prxCfg.setServerAddr(proxyAddr.asStringUriOnly());
prxCfg.done();
if (isAccountOutboundProxySet(n)) {
setAccountOutboundProxyEnabled(n, true);
}
}
public String getAccountProxy(int n) {
return getProxyConfig(n).getServerAddr();
}
public void setAccountOutboundProxyEnabled(int n, boolean enabled) {
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
if (enabled) {
String route = prxCfg.getServerAddr();
prxCfg.setRoute(route);
} else {
prxCfg.setRoute(null);
}
prxCfg.done();
}
public boolean isAccountOutboundProxySet(int n) {
return getProxyConfig(n).getRoute() != null;
}
public String getExpires(int n) {
return String.valueOf(getProxyConfig(n).getExpires());
}
public void setExpires(int n, String expire) {
try {
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
prxCfg.setExpires(Integer.parseInt(expire));
prxCfg.done();
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
public String getPrefix(int n) {
return getProxyConfig(n).getDialPrefix();
}
public void setPrefix(int n, String prefix) { public void setPrefix(int n, String prefix) {
ProxyConfig prxCfg = getProxyConfig(n); ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit(); prxCfg.edit();
@ -462,57 +170,6 @@ public class LinphonePreferences {
prxCfg.done(); prxCfg.done();
} }
public boolean avpfEnabled(int n) {
return getProxyConfig(n).avpfEnabled();
}
public void setAvpfMode(int n, boolean enable) {
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
prxCfg.setAvpfMode(enable ? AVPFMode.Enabled : AVPFMode.Disabled);
prxCfg.done();
}
public String getAvpfRrInterval(int n) {
return String.valueOf(getProxyConfig(n).getAvpfRrInterval());
}
public void setAvpfRrInterval(int n, String interval) {
try {
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
prxCfg.setAvpfRrInterval(Integer.parseInt(interval));
prxCfg.done();
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
public boolean getReplacePlusByZeroZero(int n) {
return getProxyConfig(n).getDialEscapePlus();
}
public void setReplacePlusByZeroZero(int n, boolean replace) {
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
prxCfg.setDialEscapePlus(replace);
prxCfg.done();
}
public void enablePushNotifForProxy(int n, boolean enable) {
ProxyConfig prxCfg = getProxyConfig(n);
prxCfg.edit();
prxCfg.setPushNotificationAllowed(enable);
prxCfg.done();
setPushNotificationEnabled(isPushNotificationEnabled());
}
public boolean isPushNotifEnabledForProxy(int n) {
ProxyConfig prxCfg = getProxyConfig(n);
return prxCfg.isPushNotificationAllowed();
}
public boolean isFriendlistsubscriptionEnabled() { public boolean isFriendlistsubscriptionEnabled() {
if (getConfig().getBool("app", "friendlist_subscription_enabled", false)) { if (getConfig().getBool("app", "friendlist_subscription_enabled", false)) {
// Old setting, do migration // Old setting, do migration
@ -526,13 +183,6 @@ public class LinphonePreferences {
getLc().enableFriendListSubscription(enabled); getLc().enableFriendListSubscription(enabled);
} }
public void setDefaultAccount(int accountIndex) {
if (getLc() == null) return;
ProxyConfig[] prxCfgs = getLc().getProxyConfigList();
if (accountIndex >= 0 && accountIndex < prxCfgs.length)
getLc().setDefaultProxyConfig(prxCfgs[accountIndex]);
}
public int getDefaultAccountIndex() { public int getDefaultAccountIndex() {
if (getLc() == null) return -1; if (getLc() == null) return -1;
ProxyConfig defaultPrxCfg = getLc().getDefaultProxyConfig(); ProxyConfig defaultPrxCfg = getLc().getDefaultProxyConfig();
@ -599,24 +249,6 @@ public class LinphonePreferences {
getLc().setDefaultProxyConfig(getProxyConfig(0)); getLc().setDefaultProxyConfig(getProxyConfig(0));
} }
} }
public void deleteAccount(int n) {
if (getLc() == null) return;
ProxyConfig proxyCfg = getProxyConfig(n);
if (proxyCfg != null) getLc().removeProxyConfig(proxyCfg);
if (getLc().getProxyConfigList().length != 0) {
resetDefaultProxyConfig();
} else {
getLc().setDefaultProxyConfig(null);
}
AuthInfo authInfo = getAuthInfo(n);
if (authInfo != null) {
getLc().removeAuthInfo(authInfo);
}
getLc().refreshRegisters();
}
// End of accounts settings // End of accounts settings
// Audio settings // Audio settings
@ -871,13 +503,6 @@ public class LinphonePreferences {
getLc().setNatPolicy(nat); getLc().setNatPolicy(nat);
} }
public void setUpnpEnabled(boolean enabled) {
if (getLc() == null) return;
NatPolicy nat = getOrCreateNatPolicy();
nat.enableUpnp(enabled);
getLc().setNatPolicy(nat);
}
public boolean isIceEnabled() { public boolean isIceEnabled() {
NatPolicy nat = getOrCreateNatPolicy(); NatPolicy nat = getOrCreateNatPolicy();
return nat.iceEnabled(); return nat.iceEnabled();
@ -1338,7 +963,13 @@ public class LinphonePreferences {
} }
public void enableOverlay(boolean enable) { public void enableOverlay(boolean enable) {
getConfig().setBool("app", "display_overlay", enable); getConfig()
.setBool(
"app",
"display_overlay",
enable
&& LinphoneActivity.isInstanciated()
&& LinphoneActivity.instance().checkAndRequestOverlayPermission());
} }
public boolean isDeviceRingtoneEnabled() { public boolean isDeviceRingtoneEnabled() {
@ -1426,188 +1057,8 @@ public class LinphonePreferences {
public void enableDarkMode(boolean enable) { public void enableDarkMode(boolean enable) {
getConfig().setBool("app", "dark_mode", enable); getConfig().setBool("app", "dark_mode", enable);
} if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance().recreate();
public static class AccountBuilder {
private final Core lc;
private String tempUsername;
private String tempDisplayName;
private String tempUserId;
private String tempPassword;
private String tempHa1;
private String tempDomain;
private String tempProxy;
private String tempPrefix;
private boolean tempOutboundProxy;
private String tempExpire;
private TransportType tempTransport;
private int tempAvpfRRInterval = 0;
private final boolean tempQualityReportingEnabled = false;
private final int tempQualityReportingInterval = 0;
private boolean tempEnabled = true;
private final boolean tempNoDefault = false;
public AccountBuilder(Core lc) {
this.lc = lc;
}
public AccountBuilder setTransport(TransportType transport) {
tempTransport = transport;
return this;
}
public AccountBuilder setUsername(String username) {
tempUsername = username;
return this;
}
public AccountBuilder setDisplayName(String displayName) {
tempDisplayName = displayName;
return this;
}
public AccountBuilder setPassword(String password) {
tempPassword = password;
return this;
}
public AccountBuilder setHa1(String ha1) {
tempHa1 = ha1;
return this;
}
public AccountBuilder setDomain(String domain) {
tempDomain = domain;
return this;
}
public AccountBuilder setServerAddr(String proxy) {
tempProxy = proxy;
return this;
}
public AccountBuilder setOutboundProxyEnabled(boolean enabled) {
tempOutboundProxy = enabled;
return this;
}
public AccountBuilder setExpires(String expire) {
tempExpire = expire;
return this;
}
public AccountBuilder setUserid(String userId) {
tempUserId = userId;
return this;
}
public AccountBuilder setAvpfRrInterval(int interval) {
tempAvpfRRInterval = interval;
return this;
}
public AccountBuilder setPrefix(String prefix) {
tempPrefix = prefix;
return this;
}
public AccountBuilder setEnabled(boolean enable) {
tempEnabled = enable;
return this;
}
/**
* Creates a new account
*
* @throws CoreException
*/
public void saveNewAccount() throws CoreException {
if (tempUsername == null
|| tempUsername.length() < 1
|| tempDomain == null
|| tempDomain.length() < 1) {
Log.w("Skipping account save: username or domain not provided");
return;
}
String identity = "sip:" + tempUsername + "@" + tempDomain;
String proxy = "sip:";
if (tempProxy == null) {
proxy += tempDomain;
} else {
if (!tempProxy.startsWith("sip:")
&& !tempProxy.startsWith("<sip:")
&& !tempProxy.startsWith("sips:")
&& !tempProxy.startsWith("<sips:")) {
proxy += tempProxy;
} else {
proxy = tempProxy;
}
}
Address proxyAddr = Factory.instance().createAddress(proxy);
Address identityAddr = Factory.instance().createAddress(identity);
if (proxyAddr == null || identityAddr == null) {
throw new CoreException("Proxy or Identity address is null !");
}
if (tempDisplayName != null) {
identityAddr.setDisplayName(tempDisplayName);
}
if (tempTransport != null) {
proxyAddr.setTransport(tempTransport);
}
String route = tempOutboundProxy ? proxyAddr.asStringUriOnly() : null;
ProxyConfig prxCfg = lc.createProxyConfig();
prxCfg.setIdentityAddress(identityAddr);
prxCfg.setServerAddr(proxyAddr.asStringUriOnly());
prxCfg.setRoute(route);
prxCfg.enableRegister(tempEnabled);
if (tempExpire != null) {
prxCfg.setExpires(Integer.parseInt(tempExpire));
}
prxCfg.setAvpfMode(AVPFMode.Enabled);
prxCfg.setAvpfRrInterval(tempAvpfRRInterval);
prxCfg.enableQualityReporting(tempQualityReportingEnabled);
prxCfg.setQualityReportingInterval(tempQualityReportingInterval);
String regId = LinphonePreferences.instance().getPushNotificationRegistrationID();
String appId = LinphonePreferences.instance().getString(R.string.gcm_defaultSenderId);
if (regId != null && LinphonePreferences.instance().isPushNotificationEnabled()) {
String contactInfos =
"app-id="
+ appId
+ ";pn-type="
+ LinphonePreferences.instance().getString(R.string.push_type)
+ ";pn-tok="
+ regId
+ ";pn-silent=1";
prxCfg.setContactUriParameters(contactInfos);
}
if (tempPrefix != null) {
prxCfg.setDialPrefix(tempPrefix);
}
AuthInfo authInfo =
Factory.instance()
.createAuthInfo(
tempUsername,
tempUserId,
tempPassword,
tempHa1,
null,
tempDomain);
lc.addProxyConfig(prxCfg);
lc.addAuthInfo(authInfo);
if (!tempNoDefault) lc.setDefaultProxyConfig(prxCfg);
} }
} }
} }

View file

@ -0,0 +1,242 @@
package org.linphone.settings;
/*
NetworkSettingsFragment.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import org.linphone.LinphoneActivity;
import org.linphone.R;
import org.linphone.core.tools.Log;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.settings.widget.BasicSetting;
import org.linphone.settings.widget.SettingListenerBase;
import org.linphone.settings.widget.SwitchSetting;
import org.linphone.settings.widget.TextSetting;
import org.linphone.utils.DeviceUtils;
import org.linphone.utils.PushNotificationUtils;
public class NetworkSettingsFragment extends Fragment {
protected View mRootView;
protected LinphonePreferences mPrefs;
private SwitchSetting mWifiOnly, mIpv6, mPush, mRandomPorts, mIce, mTurn;
private TextSetting mSipPort, mStunServer, mTurnUsername, mTurnPassword;
private BasicSetting mAndroidBatterySaverSettings;
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.settings_network, container, false);
loadSettings();
return mRootView;
}
@Override
public void onResume() {
super.onResume();
mPrefs = LinphonePreferences.instance();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance()
.selectMenu(
FragmentsAvailable.SETTINGS_SUBLEVEL,
getString(R.string.pref_network_title));
}
updateValues();
}
protected void loadSettings() {
mWifiOnly = mRootView.findViewById(R.id.pref_wifi_only);
mIpv6 = mRootView.findViewById(R.id.pref_ipv6);
mPush = mRootView.findViewById(R.id.pref_push_notification);
mPush.setVisibility(PushNotificationUtils.isAvailable(getActivity()) ? View.VISIBLE : View.GONE);
mRandomPorts = mRootView.findViewById(R.id.pref_transport_use_random_ports);
mIce = mRootView.findViewById(R.id.pref_ice_enable);
mTurn = mRootView.findViewById(R.id.pref_turn_enable);
mSipPort = mRootView.findViewById(R.id.pref_sip_port);
mSipPort.setInputType(InputType.TYPE_CLASS_NUMBER);
mStunServer = mRootView.findViewById(R.id.pref_stun_server);
mStunServer.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_URI);
mTurnUsername = mRootView.findViewById(R.id.pref_turn_username);
mTurnPassword = mRootView.findViewById(R.id.pref_turn_passwd);
mTurnPassword.setInputType(
InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD);
mAndroidBatterySaverSettings =
mRootView.findViewById(R.id.pref_android_battery_protected_settings);
}
protected void setListeners() {
mWifiOnly.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setWifiOnlyEnabled(newValue);
}
});
mIpv6.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.useIpv6(newValue);
}
});
mPush.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setPushNotificationEnabled(newValue);
}
});
mRandomPorts.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.useRandomPort(newValue);
mSipPort.setEnabled(!mPrefs.isUsingRandomPort());
}
});
mIce.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setIceEnabled(newValue);
}
});
mTurn.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setTurnEnabled(newValue);
mTurnUsername.setEnabled(mPrefs.isTurnEnabled());
mTurnPassword.setEnabled(mPrefs.isTurnEnabled());
}
});
mSipPort.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
try {
mPrefs.setSipPort(Integer.valueOf(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
mStunServer.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setStunServer(newValue);
mIce.setEnabled(
mPrefs.getStunServer() != null
&& !mPrefs.getStunServer().isEmpty());
mTurn.setEnabled(
mPrefs.getStunServer() != null
&& !mPrefs.getStunServer().isEmpty());
if (newValue == null || newValue.isEmpty()) {
mIce.setChecked(false);
mTurn.setChecked(false);
}
}
});
mTurnUsername.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setTurnUsername(newValue);
}
});
mTurnPassword.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setTurnPassword(newValue);
}
});
mAndroidBatterySaverSettings.setListener(
new SettingListenerBase() {
@Override
public void onClicked() {
mPrefs.powerSaverDialogPrompted(true);
Intent intent =
DeviceUtils.getDevicePowerManagerIntent(
LinphoneActivity.instance());
startActivity(intent);
}
});
}
protected void updateValues() {
mWifiOnly.setChecked(mPrefs.isWifiOnlyEnabled());
mIpv6.setChecked(mPrefs.isUsingIpv6());
mPush.setChecked(mPrefs.isPushNotificationEnabled());
mRandomPorts.setChecked(mPrefs.isUsingRandomPort());
mIce.setChecked(mPrefs.isIceEnabled());
mIce.setEnabled(mPrefs.getStunServer() != null && !mPrefs.getStunServer().isEmpty());
mTurn.setChecked(mPrefs.isTurnEnabled());
mTurn.setEnabled(mPrefs.getStunServer() != null && !mPrefs.getStunServer().isEmpty());
mSipPort.setValue(mPrefs.getSipPort());
mSipPort.setEnabled(!mPrefs.isUsingRandomPort());
mStunServer.setValue(mPrefs.getStunServer());
mTurnUsername.setValue(mPrefs.getTurnUsername());
mTurnUsername.setEnabled(mPrefs.isTurnEnabled());
mTurnPassword.setEnabled(mPrefs.isTurnEnabled());
setListeners();
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,118 @@
package org.linphone.settings;
/*
TunnelSettingsFragment.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Fragment;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.Nullable;
import org.linphone.LinphoneActivity;
import org.linphone.R;
import org.linphone.core.tools.Log;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.settings.widget.ListSetting;
import org.linphone.settings.widget.SettingListenerBase;
import org.linphone.settings.widget.TextSetting;
public class TunnelSettingsFragment extends Fragment {
protected View mRootView;
protected LinphonePreferences mPrefs;
private TextSetting mHost, mPort;
private ListSetting mMode;
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.settings_tunnel, container, false);
loadSettings();
return mRootView;
}
@Override
public void onResume() {
super.onResume();
mPrefs = LinphonePreferences.instance();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance()
.selectMenu(
FragmentsAvailable.SETTINGS_SUBLEVEL,
getString(R.string.pref_tunnel_title));
}
updateValues();
}
protected void loadSettings() {
mHost = mRootView.findViewById(R.id.pref_tunnel_host);
mPort = mRootView.findViewById(R.id.pref_tunnel_port);
mPort.setInputType(InputType.TYPE_CLASS_NUMBER);
mMode = mRootView.findViewById(R.id.pref_tunnel_mode);
}
protected void setListeners() {
mHost.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
mPrefs.setTunnelHost(newValue);
}
});
mPort.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
try {
mPrefs.setTunnelPort(Integer.valueOf(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
mMode.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
mPrefs.setTunnelMode(newValue);
}
});
}
protected void updateValues() {
mHost.setValue(mPrefs.getTunnelHost());
mPort.setValue(mPrefs.getTunnelPort());
mMode.setValue(mPrefs.getTunnelMode());
setListeners();
}
}

View file

@ -0,0 +1,276 @@
package org.linphone.settings;
/*
VideoSettingsFragment.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Fragment;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneActivity;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.core.Core;
import org.linphone.core.Factory;
import org.linphone.core.PayloadType;
import org.linphone.core.VideoDefinition;
import org.linphone.core.tools.Log;
import org.linphone.fragments.FragmentsAvailable;
import org.linphone.settings.widget.ListSetting;
import org.linphone.settings.widget.SettingListenerBase;
import org.linphone.settings.widget.SwitchSetting;
import org.linphone.settings.widget.TextSetting;
public class VideoSettingsFragment extends Fragment {
protected View mRootView;
protected LinphonePreferences mPrefs;
private SwitchSetting mEnable, mAutoInitiate, mAutoAccept, mOverlay;
private ListSetting mPreset, mSize, mFps;
private TextSetting mBandwidth;
private LinearLayout mVideoCodecs;
private TextView mVideoCodecsHeader;
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.settings_video, container, false);
loadSettings();
return mRootView;
}
@Override
public void onResume() {
super.onResume();
mPrefs = LinphonePreferences.instance();
if (LinphoneActivity.isInstanciated()) {
LinphoneActivity.instance()
.selectMenu(
FragmentsAvailable.SETTINGS_SUBLEVEL,
getString(R.string.pref_video_title));
}
updateValues();
}
protected void loadSettings() {
mEnable = mRootView.findViewById(R.id.pref_video_enable);
mAutoInitiate = mRootView.findViewById(R.id.pref_video_initiate_call_with_video);
mAutoAccept = mRootView.findViewById(R.id.pref_video_automatically_accept_video);
mOverlay = mRootView.findViewById(R.id.pref_overlay);
mPreset = mRootView.findViewById(R.id.pref_video_preset);
mSize = mRootView.findViewById(R.id.pref_preferred_video_size);
initVideoSizeList();
mFps = mRootView.findViewById(R.id.pref_preferred_fps);
initFpsList();
mBandwidth = mRootView.findViewById(R.id.pref_bandwidth_limit);
mBandwidth.setInputType(InputType.TYPE_CLASS_NUMBER);
mVideoCodecs = mRootView.findViewById(R.id.pref_video_codecs);
mVideoCodecsHeader = mRootView.findViewById(R.id.pref_video_codecs_header);
}
protected void setListeners() {
mEnable.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enableVideo(newValue);
if (!newValue) {
mAutoAccept.setChecked(false);
mAutoInitiate.setChecked(false);
}
updateVideoSettingsVisibility(newValue);
}
});
mAutoInitiate.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setInitiateVideoCall(newValue);
}
});
mAutoAccept.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setAutomaticallyAcceptVideoRequests(newValue);
}
});
mOverlay.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enableOverlay(newValue);
}
});
mPreset.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
mPrefs.setVideoPreset(newValue);
mFps.setEnabled(newValue.equals("custom"));
mBandwidth.setEnabled(newValue.equals("custom"));
}
});
mSize.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
mPrefs.setPreferredVideoSize(newValue);
}
});
mFps.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
try {
mPrefs.setPreferredVideoFps(Integer.valueOf(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
mBandwidth.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
try {
mPrefs.setBandwidthLimit(Integer.valueOf(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
}
protected void updateValues() {
mEnable.setChecked(mPrefs.isVideoEnabled());
updateVideoSettingsVisibility(mPrefs.isVideoEnabled());
mAutoInitiate.setChecked(mPrefs.shouldInitiateVideoCall());
mAutoAccept.setChecked(mPrefs.shouldAutomaticallyAcceptVideoRequests());
mOverlay.setChecked(mPrefs.isOverlayEnabled());
mBandwidth.setValue(mPrefs.getBandwidthLimit());
mBandwidth.setEnabled(mPrefs.getVideoPreset().equals("custom"));
mPreset.setValue(mPrefs.getVideoPreset());
mSize.setValue(mPrefs.getPreferredVideoSize());
mFps.setValue(mPrefs.getPreferredVideoFps());
mFps.setEnabled(mPrefs.getVideoPreset().equals("custom"));
populateVideoCodecs();
setListeners();
}
private void initVideoSizeList() {
List<String> entries = new ArrayList<>();
List<String> values = new ArrayList<>();
for (VideoDefinition vd : Factory.instance().getSupportedVideoDefinitions()) {
entries.add(vd.getName());
values.add(vd.getName());
}
mSize.setItems(entries, values);
}
private void initFpsList() {
List<String> entries = new ArrayList<>();
List<String> values = new ArrayList<>();
entries.add(getString(R.string.pref_none));
values.add("0");
for (int i = 5; i <= 30; i += 5) {
String str = Integer.toString(i);
entries.add(str);
values.add(str);
}
mFps.setItems(entries, values);
}
private void populateVideoCodecs() {
mVideoCodecs.removeAllViews();
Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
if (core != null) {
for (final PayloadType pt : core.getVideoPayloadTypes()) {
final SwitchSetting codec = new SwitchSetting(getActivity());
codec.setTitle(pt.getMimeType());
if (pt.enabled()) {
// Never use codec.setChecked(pt.enabled) !
codec.setChecked(true);
}
codec.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
pt.enable(newValue);
}
});
mVideoCodecs.addView(codec);
}
}
}
private void updateVideoSettingsVisibility(boolean show) {
mAutoInitiate.setVisibility(show ? View.VISIBLE : View.GONE);
mAutoAccept.setVisibility(show ? View.VISIBLE : View.GONE);
mOverlay.setVisibility(show ? View.VISIBLE : View.GONE);
mBandwidth.setVisibility(show ? View.VISIBLE : View.GONE);
mPreset.setVisibility(show ? View.VISIBLE : View.GONE);
mSize.setVisibility(show ? View.VISIBLE : View.GONE);
mFps.setVisibility(show ? View.VISIBLE : View.GONE);
mVideoCodecs.setVisibility(show ? View.VISIBLE : View.GONE);
mVideoCodecsHeader.setVisibility(show ? View.VISIBLE : View.GONE);
}
}

View file

@ -0,0 +1,127 @@
package org.linphone.settings.widget;
/*
BasicSetting.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import org.linphone.R;
public class BasicSetting extends LinearLayout {
protected Context mContext;
protected View mView;
protected TextView mTitle, mSubtitle;
protected SettingListener mListener;
public BasicSetting(Context context) {
super(context);
mContext = context;
init(null, 0, 0);
}
public BasicSetting(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
mContext = context;
init(attrs, 0, 0);
}
public BasicSetting(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
init(attrs, defStyleAttr, 0);
}
public BasicSetting(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
mContext = context;
init(attrs, defStyleAttr, defStyleRes);
}
protected void inflateView() {
mView = LayoutInflater.from(mContext).inflate(R.layout.settings_widget_basic, this, true);
}
public void setListener(SettingListener listener) {
mListener = listener;
}
protected void init(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
inflateView();
mTitle = mView.findViewById(R.id.setting_title);
mSubtitle = mView.findViewById(R.id.setting_subtitle);
RelativeLayout rlayout = mView.findViewById(R.id.setting_layout);
rlayout.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
if (mTitle.isEnabled() && mListener != null) {
mListener.onClicked();
}
}
});
if (attrs != null) {
TypedArray a =
mContext.getTheme()
.obtainStyledAttributes(
attrs, R.styleable.Settings, defStyleAttr, defStyleRes);
try {
String title = a.getString(R.styleable.Settings_title);
if (title != null) {
mTitle.setText(title);
} else {
mTitle.setVisibility(GONE);
}
String subtitle = a.getString(R.styleable.Settings_subtitle);
if (subtitle != null) {
mSubtitle.setText(subtitle);
} else {
mSubtitle.setVisibility(GONE);
}
} finally {
a.recycle();
}
}
}
public void setTitle(String title) {
mTitle.setText(title);
mTitle.setVisibility(title == null || title.isEmpty() ? GONE : VISIBLE);
}
public void setSubtitle(String subtitle) {
mSubtitle.setText(subtitle);
mSubtitle.setVisibility(subtitle == null || subtitle.isEmpty() ? GONE : VISIBLE);
}
public void setEnabled(boolean enabled) {
mTitle.setEnabled(enabled);
mSubtitle.setEnabled(enabled);
}
}

View file

@ -0,0 +1,99 @@
package org.linphone.settings.widget;
/*
CheckBoxSetting.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RelativeLayout;
import androidx.annotation.Nullable;
import org.linphone.R;
public class CheckBoxSetting extends BasicSetting {
protected CheckBox mCheckBox;
public CheckBoxSetting(Context context) {
super(context);
}
public CheckBoxSetting(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public CheckBoxSetting(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CheckBoxSetting(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
protected void inflateView() {
mView =
LayoutInflater.from(mContext)
.inflate(R.layout.settings_widget_checkbox, this, true);
}
protected void init(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super.init(attrs, defStyleAttr, defStyleRes);
mCheckBox = mView.findViewById(R.id.setting_checkbox);
mCheckBox.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mListener != null) {
mListener.onBoolValueChanged(isChecked);
}
}
});
RelativeLayout rlayout = mView.findViewById(R.id.setting_layout);
rlayout.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
if (mCheckBox.isEnabled()) {
toggle();
}
}
});
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
mCheckBox.setEnabled(enabled);
}
public void setChecked(boolean checked) {
mCheckBox.setChecked(checked);
}
public boolean isChecked() {
return mCheckBox.isChecked();
}
public void toggle() {
mCheckBox.toggle();
}
}

View file

@ -0,0 +1,81 @@
package org.linphone.settings.widget;
/*
LedSetting.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import org.linphone.R;
public class LedSetting extends BasicSetting {
public enum Color {
GRAY,
GREEN,
ORANGE,
RED
}
protected ImageView mLed;
public LedSetting(Context context) {
super(context);
}
public LedSetting(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public LedSetting(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public LedSetting(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
protected void inflateView() {
mView = LayoutInflater.from(mContext).inflate(R.layout.settings_widget_led, this, true);
}
protected void init(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super.init(attrs, defStyleAttr, defStyleRes);
mLed = mView.findViewById(R.id.setting_led);
}
public void setColor(Color color) {
switch (color) {
case GRAY:
mLed.setImageResource(R.drawable.led_disconnected);
break;
case GREEN:
mLed.setImageResource(R.drawable.led_connected);
break;
case ORANGE:
mLed.setImageResource(R.drawable.led_inprogress);
break;
case RED:
mLed.setImageResource(R.drawable.led_error);
break;
}
}
}

View file

@ -0,0 +1,140 @@
package org.linphone.settings.widget;
/*
ListSetting.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import org.linphone.R;
public class ListSetting extends BasicSetting implements AdapterView.OnItemSelectedListener {
protected Spinner mSpinner;
protected List<String> mItems;
protected List<String> mItemsValues;
public ListSetting(Context context) {
super(context);
}
public ListSetting(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ListSetting(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public ListSetting(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
protected void inflateView() {
mView = LayoutInflater.from(mContext).inflate(R.layout.settings_widget_list, this, true);
}
protected void init(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super.init(attrs, defStyleAttr, defStyleRes);
mItems = new ArrayList<>();
mItemsValues = new ArrayList<>();
mSpinner = mView.findViewById(R.id.setting_spinner);
mSpinner.setOnItemSelectedListener(this);
if (attrs != null) {
TypedArray a =
mContext.getTheme()
.obtainStyledAttributes(
attrs, R.styleable.Settings, defStyleAttr, defStyleRes);
try {
CharSequence[] names = a.getTextArray(R.styleable.Settings_list_items_names);
CharSequence[] values = a.getTextArray(R.styleable.Settings_list_items_values);
if (values != null && names != null) {
for (CharSequence cs : names) {
mItems.add(cs.toString());
}
for (CharSequence cs : values) {
mItemsValues.add(cs.toString());
}
setItems(mItems, mItemsValues);
}
} finally {
a.recycle();
}
}
}
public void setItems(List<String> list, List<String> valuesList) {
mItems = list;
mItemsValues = valuesList;
ArrayAdapter<String> dataAdapter =
new ArrayAdapter<>(mContext, android.R.layout.simple_spinner_item, list);
dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
mSpinner.setAdapter(dataAdapter);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (mListener != null && position < mItems.size()) {
String itemValue = null;
if (mItemsValues != null && position < mItemsValues.size()) {
itemValue = mItemsValues.get(position);
}
mListener.onListValueChanged(position, mItems.get(position), itemValue);
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {}
public void setValue(String value) {
int index = mItemsValues.indexOf(value);
if (index == -1) {
index = mItems.indexOf(value);
}
if (index != -1) {
mSpinner.setSelection(index);
}
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
mSpinner.setEnabled(enabled);
}
public void setValue(int value) {
setValue(String.valueOf(value));
}
public void setValue(float value) {
setValue(String.valueOf(value));
}
public void setValue(double value) {
setValue(String.valueOf(value));
}
}

View file

@ -0,0 +1,30 @@
package org.linphone.settings.widget;
/*
SettingListener.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
public interface SettingListener {
void onClicked();
void onTextValueChanged(String newValue);
void onBoolValueChanged(boolean newValue);
void onListValueChanged(int position, String newLabel, String newValue);
}

View file

@ -0,0 +1,30 @@
package org.linphone.settings.widget;
/*
SettingListenerBase.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
public class SettingListenerBase implements SettingListener {
public void onClicked() {}
public void onTextValueChanged(String newValue) {}
public void onBoolValueChanged(boolean newValue) {}
public void onListValueChanged(int position, String newLabel, String newValue) {}
}

View file

@ -0,0 +1,97 @@
package org.linphone.settings.widget;
/*
SwitchSetting.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.RelativeLayout;
import android.widget.Switch;
import androidx.annotation.Nullable;
import org.linphone.R;
public class SwitchSetting extends BasicSetting {
protected Switch mSwitch;
public SwitchSetting(Context context) {
super(context);
}
public SwitchSetting(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public SwitchSetting(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public SwitchSetting(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
protected void inflateView() {
mView = LayoutInflater.from(mContext).inflate(R.layout.settings_widget_switch, this, true);
}
protected void init(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super.init(attrs, defStyleAttr, defStyleRes);
mSwitch = mView.findViewById(R.id.setting_switch);
mSwitch.setOnCheckedChangeListener(
new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mListener != null) {
mListener.onBoolValueChanged(isChecked);
}
}
});
RelativeLayout rlayout = mView.findViewById(R.id.setting_layout);
rlayout.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View v) {
if (mSwitch.isEnabled()) {
toggle();
}
}
});
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
mSwitch.setEnabled(enabled);
}
public void setChecked(boolean checked) {
mSwitch.setChecked(checked);
}
public boolean isChecked() {
return mSwitch.isChecked();
}
public void toggle() {
mSwitch.toggle();
}
}

View file

@ -0,0 +1,117 @@
package org.linphone.settings.widget;
/*
TextSetting.java
Copyright (C) 2019 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.widget.EditText;
import androidx.annotation.Nullable;
import org.linphone.R;
public class TextSetting extends BasicSetting implements TextWatcher {
protected EditText mInput;
public TextSetting(Context context) {
super(context);
}
public TextSetting(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public TextSetting(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public TextSetting(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
protected void inflateView() {
mView = LayoutInflater.from(mContext).inflate(R.layout.settings_widget_text, this, true);
}
protected void init(@Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super.init(attrs, defStyleAttr, defStyleRes);
mInput = mView.findViewById(R.id.setting_input);
if (attrs != null) {
TypedArray a =
mContext.getTheme()
.obtainStyledAttributes(
attrs, R.styleable.Settings, defStyleAttr, defStyleRes);
try {
String hint = a.getString(R.styleable.Settings_hint);
mInput.setHint(hint);
} finally {
a.recycle();
}
}
mInput.addTextChangedListener(this);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {}
@Override
public void afterTextChanged(Editable s) {
if (mListener != null) {
mListener.onTextValueChanged(mInput.getText().toString());
}
}
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
mInput.setEnabled(enabled);
}
public void setInputType(int inputType) {
mInput.setInputType(inputType);
}
public void setValue(String value) {
mInput.setText(value);
}
public void setValue(int value) {
setValue(String.valueOf(value));
}
public void setValue(float value) {
setValue(String.valueOf(value));
}
public void setValue(double value) {
setValue(String.valueOf(value));
}
public String getValue() {
return mInput.getText().toString();
}
}

View file

@ -101,7 +101,7 @@
android:iconifiedByDefault="false" android:iconifiedByDefault="false"
android:inputType="textPersonName" android:inputType="textPersonName"
android:paddingRight="5dp" android:paddingRight="5dp"
android:queryBackground="@android:color/transparent" android:queryBackground="@color/transparent_color"
android:queryHint="@string/chat_room_creation_filter_hint"/> android:queryHint="@string/chat_room_creation_filter_hint"/>
</RelativeLayout> </RelativeLayout>

View file

@ -1,15 +1,83 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/topLayout" xmlns:linphone="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:background="?attr/backgroundColor">
<ListView <LinearLayout
android:id="@+id/list"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:cacheColorHint="@color/transparent_color" android:paddingTop="5dp"
android:drawSelectorOnTop="false" android:paddingBottom="5dp"
android:scrollbarAlwaysDrawVerticalTrack="true" /> android:orientation="vertical">
</RelativeLayout> <TextView
android:id="@+id/accounts_settings_list_header"
style="@style/settings_category_font"
android:text="@string/pref_sipaccounts"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/accounts_settings_list"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
style="@style/settings_category_font"
android:text="@string/pref_preferences_title"
android:paddingTop="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_tunnel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_tunnel_title"/>
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_audio"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_audio_title"/>
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_video"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_video_title"/>
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_call"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_call_title"/>
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_chat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_chat_title"/>
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_network"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_network_title"/>
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_advanced"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_advanced_title"/>
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:linphone="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="vertical">
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_help_username"
linphone:hint="@string/pref_username"
linphone:title="@string/pref_username" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_auth_userid"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_help_auth_userid"
linphone:hint="@string/pref_auth_userid"
linphone:title="@string/pref_auth_userid" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_passwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_help_password"
linphone:hint="@string/pref_passwd"
linphone:title="@string/pref_passwd" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_domain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_help_domain"
linphone:hint="@string/pref_domain"
linphone:title="@string/pref_domain" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_display_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_help_display_name"
linphone:hint="@string/pref_display_name"
linphone:title="@string/pref_display_name" />
<TextView
style="@style/settings_category_font"
android:text="@string/pref_manage_title"
android:paddingTop="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_disable_account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_disable_account" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_default_account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_default_account" />
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_change_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_change_password" />
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_delete_account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_delete_account" />
<TextView
style="@style/settings_category_font"
android:text="@string/pref_advanced_title"
android:paddingTop="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<org.linphone.settings.widget.ListSetting
android:id="@+id/pref_transport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_transport" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_proxy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_proxy"
linphone:title="@string/pref_proxy" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_enable_outbound_proxy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_help_outbound_proxy"
linphone:title="@string/pref_enable_outbound_proxy" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_stun_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_stun_server"
linphone:title="@string/pref_stun_server" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_ice_enable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_ice_enable" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_expire"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_expire_title"
linphone:title="@string/pref_expire_title" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_prefix"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_prefix"
linphone:title="@string/pref_prefix" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_avpf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_avpf" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_avpf_rr_interval"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_avpf_rr_interval"
linphone:title="@string/pref_avpf_rr_interval" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_escape_plus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_escape_plus" />
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_link_account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_link_account" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_push_notification"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_proxy_push_notif" />
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:linphone="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="vertical">
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_debug"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_debug" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_java_debug"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_java_debug" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_friendlist_subscribe"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_friendlist_subscribe" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_background_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_background_mode" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_service_notification"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_service_notification" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_autostart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_autostart" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_dark_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_dark_mode" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_remote_provisioning"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_remote_provisioning_title"
linphone:title="@string/pref_remote_provisioning_title" />
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_android_app_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_android_app_settings_title" />
<TextView
style="@style/settings_category_font"
android:text="@string/pref_primary_account_title"
android:paddingTop="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_display_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_display_name_title"
linphone:title="@string/pref_display_name_title" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_user_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_user_name_title"
linphone:title="@string/pref_user_name_title" />
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,79 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:linphone="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="vertical">
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_echo_cancellation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_echo_cancellation_summary"
linphone:title="@string/pref_echo_cancellation" />
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_echo_canceller_calibration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_echo_canceller_calibration"/>
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_echo_tester"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_echo_tester"/>
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_adaptive_rate_control"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_adaptive_rate_control" />
<org.linphone.settings.widget.ListSetting
android:id="@+id/pref_codec_bitrate_limit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:list_items_names="@array/limit_bitrate_entries"
linphone:list_items_values="@array/limit_bitrate_entry_values"
linphone:title="@string/pref_codec_bitrate_limit" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_mic_gain_db"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_mic_gain_db"
linphone:title="@string/pref_mic_gain_db" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_playback_gain_db"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_playback_gain_db"
linphone:title="@string/pref_playback_gain_db" />
<TextView
style="@style/settings_category_font"
android:text="@string/pref_codecs"
android:paddingTop="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/pref_audio_codecs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:linphone="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="vertical">
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_device_ringtone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_device_ringtone" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_vibrate_on_incoming_calls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_vibrate_on_incoming_calls" />
<org.linphone.settings.widget.ListSetting
android:id="@+id/pref_media_encryption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_media_encryption" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_sipinfo_dtmf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_sipinfo_dtmf" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_rfc2833_dtmf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_rfc2833_dtmf" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_auto_answer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_auto_answer" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_auto_answer_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_auto_answer_time"
linphone:title="@string/pref_auto_answer_time" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_incoming_call_timeout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_incoming_call_timeout_title"
linphone:title="@string/pref_incoming_call_timeout_title" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_voice_mail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_voice_mail"
linphone:title="@string/pref_voice_mail" />
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:linphone="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="vertical">
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_image_sharing_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_image_sharing_server_title"
linphone:subtitle="@string/pref_image_sharing_server_desc"
linphone:title="@string/pref_image_sharing_server_title" />
<org.linphone.settings.widget.ListSetting
android:id="@+id/pref_auto_download_policy"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_auto_download_policy_title"
linphone:list_items_names="@array/pref_auto_download_policy_entries_labels"
linphone:list_items_values="@array/pref_auto_download_policy_entries_values"/>
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_auto_download_max_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_auto_download_max_size_title"
linphone:title="@string/pref_auto_download_max_size_title" />
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_android_app_notif_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_android_app_notif_settings_title"/>
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:linphone="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="vertical">
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_wifi_only"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_wifi_only" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_ipv6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_ipv6_title" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_push_notification"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_push_notification" />
<org.linphone.settings.widget.BasicSetting
android:id="@+id/pref_android_battery_protected_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_protected_settings_desc"
linphone:title="@string/pref_protected_settings_title" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_transport_use_random_ports"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_transport_use_random_ports" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_sip_port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_sip_port_title"
linphone:title="@string/pref_sip_port_title" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_stun_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_stun_server"
linphone:title="@string/pref_stun_server" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_ice_enable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_ice_enable" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_turn_enable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_turn_enable" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_turn_username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_turn_username_title"
linphone:title="@string/pref_turn_username_title" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_turn_passwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_turn_passwd_title"
linphone:title="@string/pref_turn_passwd_title" />
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:linphone="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="vertical">
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_tunnel_host"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_tunnel_host"
linphone:title="@string/pref_tunnel_host" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_tunnel_port"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_tunnel_port"
linphone:title="@string/pref_tunnel_port" />
<org.linphone.settings.widget.ListSetting
android:id="@+id/pref_tunnel_mode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:list_items_names="@array/tunnel_mode_entries"
linphone:list_items_values="@array/tunnel_mode_entry_values"
linphone:title="@string/pref_tunnel_mode" />
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:linphone="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/backgroundColor">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:orientation="vertical">
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_video_enable"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_video_enable_title" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_video_initiate_call_with_video"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_video_initiate_call_with_video"
linphone:title="@string/pref_video_initiate_call_with_video_title" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_video_automatically_accept_video"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_video_automatically_accept_video"
linphone:title="@string/pref_video_automatically_accept_video_title" />
<org.linphone.settings.widget.SwitchSetting
android:id="@+id/pref_overlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:subtitle="@string/pref_overlay_summary"
linphone:title="@string/pref_overlay" />
<org.linphone.settings.widget.ListSetting
android:id="@+id/pref_video_preset"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:list_items_names="@array/video_preset_entries"
linphone:list_items_values="@array/video_preset_entries"
linphone:title="@string/pref_video_preset" />
<org.linphone.settings.widget.ListSetting
android:id="@+id/pref_preferred_video_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_preferred_video_size" />
<org.linphone.settings.widget.ListSetting
android:id="@+id/pref_preferred_fps"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:title="@string/pref_preferred_fps" />
<org.linphone.settings.widget.TextSetting
android:id="@+id/pref_bandwidth_limit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
linphone:hint="@string/pref_bandwidth_limit"
linphone:title="@string/pref_bandwidth_limit" />
<TextView
style="@style/settings_category_font"
android:id="@+id/pref_video_codecs_header"
android:text="@string/pref_codecs"
android:paddingTop="15dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<LinearLayout
android:id="@+id/pref_video_codecs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</LinearLayout>
</ScrollView>

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical|left">
<RelativeLayout
android:id="@+id/setting_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:paddingTop="15dp"
android:paddingBottom="15dp">
<TextView
android:id="@+id/setting_title"
android:singleLine="true"
android:ellipsize="marquee"
style="@style/settings_item_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/setting_subtitle"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_below="@id/setting_title"
style="@style/settings_item_subtitle_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor" />
</LinearLayout>

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical|left">
<RelativeLayout
android:id="@+id/setting_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:paddingTop="15dp"
android:paddingBottom="15dp">
<TextView
android:id="@+id/setting_title"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_toLeftOf="@id/setting_checkbox"
android:paddingRight="5dp"
style="@style/settings_item_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/setting_subtitle"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_toLeftOf="@id/setting_checkbox"
android:paddingRight="5dp"
android:layout_below="@id/setting_title"
style="@style/settings_item_subtitle_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<CheckBox
android:id="@+id/setting_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor" />
</LinearLayout>

View file

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical|left">
<RelativeLayout
android:id="@+id/setting_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:paddingTop="15dp"
android:paddingBottom="15dp">
<TextView
android:id="@+id/setting_title"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_toLeftOf="@id/setting_led"
android:paddingRight="5dp"
style="@style/settings_item_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/setting_subtitle"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_toLeftOf="@id/setting_led"
android:paddingRight="5dp"
android:layout_below="@id/setting_title"
style="@style/settings_item_subtitle_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<ImageView
android:id="@+id/setting_led"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="@drawable/led_disconnected" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor" />
</LinearLayout>

View file

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical|left">
<RelativeLayout
android:id="@+id/setting_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:paddingTop="15dp"
android:paddingBottom="15dp">
<TextView
android:id="@+id/setting_title"
android:singleLine="true"
android:ellipsize="marquee"
style="@style/settings_item_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/setting_subtitle"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_below="@id/setting_title"
style="@style/settings_item_subtitle_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Spinner
android:id="@+id/setting_spinner"
android:layout_below="@id/setting_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor" />
</LinearLayout>

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical|left">
<RelativeLayout
android:id="@+id/setting_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:paddingTop="15dp"
android:paddingBottom="15dp">
<TextView
android:id="@+id/setting_title"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_toLeftOf="@id/setting_switch"
android:paddingRight="5dp"
style="@style/settings_item_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/setting_subtitle"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_toLeftOf="@id/setting_switch"
android:paddingRight="5dp"
android:layout_below="@id/setting_title"
style="@style/settings_item_subtitle_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Switch
android:id="@+id/setting_switch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true" />
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor" />
</LinearLayout>

View file

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:gravity="center_vertical|left">
<RelativeLayout
android:id="@+id/setting_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:paddingTop="15dp"
android:paddingBottom="15dp">
<TextView
android:id="@+id/setting_title"
android:singleLine="true"
android:ellipsize="marquee"
style="@style/settings_item_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/setting_subtitle"
android:singleLine="true"
android:ellipsize="marquee"
android:layout_below="@id/setting_title"
style="@style/settings_item_subtitle_font"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<EditText
android:id="@+id/setting_input"
android:textColor="?attr/primaryTextColor"
android:layout_below="@id/setting_subtitle"
android:background="@color/transparent_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="?attr/dividerColor" />
</LinearLayout>

View file

@ -280,7 +280,7 @@
<string name="default_account_flag">الحساب الافتراضي</string> <string name="default_account_flag">الحساب الافتراضي</string>
<string name="pref_add_account">إضافة حساب</string> <string name="pref_add_account">إضافة حساب</string>
<string name="pref_in_app_store">متجر التبضع المحمول</string> <string name="pref_in_app_store">متجر التبضع المحمول</string>
<string name="pref_tunnel">النفق</string> <string name="pref_tunnel_title">النفق</string>
<string name="pref_tunnel_host">إسم المضيف</string> <string name="pref_tunnel_host">إسم المضيف</string>
<string name="pref_tunnel_port">المنفذ</string> <string name="pref_tunnel_port">المنفذ</string>
<string name="pref_tunnel_mode">الوضع</string> <string name="pref_tunnel_mode">الوضع</string>

View file

@ -329,7 +329,7 @@
<string name="default_account_flag">Standardkonto</string> <string name="default_account_flag">Standardkonto</string>
<string name="pref_add_account">Konto hinzufügen</string> <string name="pref_add_account">Konto hinzufügen</string>
<string name="pref_in_app_store">In-App Store</string> <string name="pref_in_app_store">In-App Store</string>
<string name="pref_tunnel">Tunnel</string> <string name="pref_tunnel_title">Tunnel</string>
<string name="pref_tunnel_host">Hostname</string> <string name="pref_tunnel_host">Hostname</string>
<string name="pref_tunnel_port">Port</string> <string name="pref_tunnel_port">Port</string>
<string name="pref_tunnel_mode">Modus</string> <string name="pref_tunnel_mode">Modus</string>

View file

@ -152,7 +152,7 @@
<string name="pref_sipaccounts">Cuentas SIP</string> <string name="pref_sipaccounts">Cuentas SIP</string>
<string name="default_account_flag">Cuenta por defecto</string> <string name="default_account_flag">Cuenta por defecto</string>
<string name="pref_add_account">Añadir cuenta</string> <string name="pref_add_account">Añadir cuenta</string>
<string name="pref_tunnel">Túnel</string> <string name="pref_tunnel_title">Túnel</string>
<string name="pref_tunnel_host">Nombre del servidor</string> <string name="pref_tunnel_host">Nombre del servidor</string>
<string name="pref_tunnel_port">Puerto</string> <string name="pref_tunnel_port">Puerto</string>
<string name="pref_tunnel_mode">Modo</string> <string name="pref_tunnel_mode">Modo</string>

View file

@ -183,7 +183,7 @@
<string name="pref_sipaccounts">SIP Tilit</string> <string name="pref_sipaccounts">SIP Tilit</string>
<string name="default_account_flag">Vakio tili</string> <string name="default_account_flag">Vakio tili</string>
<string name="pref_add_account">Lisää tili</string> <string name="pref_add_account">Lisää tili</string>
<string name="pref_tunnel">Tunneli</string> <string name="pref_tunnel_title">Tunneli</string>
<string name="pref_tunnel_host">Hostname \'eli verkkotunnuksen etunimi\'</string> <string name="pref_tunnel_host">Hostname \'eli verkkotunnuksen etunimi\'</string>
<string name="pref_tunnel_port">Portti</string> <string name="pref_tunnel_port">Portti</string>
<string name="pref_tunnel_mode">Tila</string> <string name="pref_tunnel_mode">Tila</string>

View file

@ -358,7 +358,7 @@ Disponible gratuitement ici : http://www.linphone.org/technical-corner/linphone/
<string name="default_account_flag">Compte par défaut</string> <string name="default_account_flag">Compte par défaut</string>
<string name="pref_add_account">Ajouter un compte</string> <string name="pref_add_account">Ajouter un compte</string>
<string name="pref_in_app_store">Magasin</string> <string name="pref_in_app_store">Magasin</string>
<string name="pref_tunnel">Tunnel</string> <string name="pref_tunnel_title">Tunnel</string>
<string name="pref_tunnel_host">Hôte</string> <string name="pref_tunnel_host">Hôte</string>
<string name="pref_tunnel_port">Port</string> <string name="pref_tunnel_port">Port</string>
<string name="pref_tunnel_mode">Mode</string> <string name="pref_tunnel_mode">Mode</string>

View file

@ -317,7 +317,7 @@
<string name="default_account_flag">Account predefinito</string> <string name="default_account_flag">Account predefinito</string>
<string name="pref_add_account">Aggiungi account</string> <string name="pref_add_account">Aggiungi account</string>
<string name="pref_in_app_store">In-app Store</string> <string name="pref_in_app_store">In-app Store</string>
<string name="pref_tunnel">Tunnel</string> <string name="pref_tunnel_title">Tunnel</string>
<string name="pref_tunnel_host">Nome host</string> <string name="pref_tunnel_host">Nome host</string>
<string name="pref_tunnel_port">Porta</string> <string name="pref_tunnel_port">Porta</string>
<string name="pref_tunnel_mode">Modalità</string> <string name="pref_tunnel_mode">Modalità</string>

View file

@ -267,7 +267,7 @@
<string name="default_account_flag">デフォルトのアカウント</string> <string name="default_account_flag">デフォルトのアカウント</string>
<string name="pref_add_account">アカウントを追加する</string> <string name="pref_add_account">アカウントを追加する</string>
<string name="pref_in_app_store">アプリストアで</string> <string name="pref_in_app_store">アプリストアで</string>
<string name="pref_tunnel">トンネル</string> <string name="pref_tunnel_title">トンネル</string>
<string name="pref_tunnel_host">ホスト名</string> <string name="pref_tunnel_host">ホスト名</string>
<string name="pref_tunnel_port">ポート</string> <string name="pref_tunnel_port">ポート</string>
<string name="pref_tunnel_mode">モード</string> <string name="pref_tunnel_mode">モード</string>

View file

@ -308,7 +308,7 @@
<string name="default_account_flag">ნაგულისხმევი ანგარიში</string> <string name="default_account_flag">ნაგულისხმევი ანგარიში</string>
<string name="pref_add_account">ანგარიშის დამატება</string> <string name="pref_add_account">ანგარიშის დამატება</string>
<string name="pref_in_app_store">პროგრამის-შიდა მაღაზია</string> <string name="pref_in_app_store">პროგრამის-შიდა მაღაზია</string>
<string name="pref_tunnel">გვირაბი</string> <string name="pref_tunnel_title">გვირაბი</string>
<string name="pref_tunnel_host">ჰოსტის სახელ</string> <string name="pref_tunnel_host">ჰოსტის სახელ</string>
<string name="pref_tunnel_port">პორტი</string> <string name="pref_tunnel_port">პორტი</string>
<string name="pref_tunnel_mode">რეჟიმი</string> <string name="pref_tunnel_mode">რეჟიმი</string>

View file

@ -134,7 +134,7 @@
<string name="pref_sipaccounts">SIP-accounts</string> <string name="pref_sipaccounts">SIP-accounts</string>
<string name="default_account_flag">Standaard account</string> <string name="default_account_flag">Standaard account</string>
<string name="pref_add_account">Account toevoegen</string> <string name="pref_add_account">Account toevoegen</string>
<string name="pref_tunnel">Tunnel</string> <string name="pref_tunnel_title">Tunnel</string>
<string name="pref_tunnel_host">Hostnaam</string> <string name="pref_tunnel_host">Hostnaam</string>
<string name="pref_tunnel_port">Poort</string> <string name="pref_tunnel_port">Poort</string>
<string name="pref_tunnel_mode">Modus</string> <string name="pref_tunnel_mode">Modus</string>

View file

@ -258,7 +258,7 @@ Wpisz wyświetlaną nazwę (opcjonalnie)</string>
<string name="default_account_flag">Domyślne konto</string> <string name="default_account_flag">Domyślne konto</string>
<string name="pref_add_account">Dodaj konto</string> <string name="pref_add_account">Dodaj konto</string>
<string name="pref_in_app_store">W aplikacji Store</string> <string name="pref_in_app_store">W aplikacji Store</string>
<string name="pref_tunnel">Tunel</string> <string name="pref_tunnel_title">Tunel</string>
<string name="pref_tunnel_host">Nazwa hosta</string> <string name="pref_tunnel_host">Nazwa hosta</string>
<string name="pref_tunnel_port">Port</string> <string name="pref_tunnel_port">Port</string>
<string name="pref_tunnel_mode">Tryb</string> <string name="pref_tunnel_mode">Tryb</string>

View file

@ -315,7 +315,7 @@
<string name="default_account_flag">Conta padrão</string> <string name="default_account_flag">Conta padrão</string>
<string name="pref_add_account">Adicionar Conta</string> <string name="pref_add_account">Adicionar Conta</string>
<string name="pref_in_app_store">In-app Store</string> <string name="pref_in_app_store">In-app Store</string>
<string name="pref_tunnel">Túnel</string> <string name="pref_tunnel_title">Túnel</string>
<string name="pref_tunnel_host">Hostname</string> <string name="pref_tunnel_host">Hostname</string>
<string name="pref_tunnel_port">Porta</string> <string name="pref_tunnel_port">Porta</string>
<string name="pref_tunnel_mode">Modo</string> <string name="pref_tunnel_mode">Modo</string>

View file

@ -355,7 +355,7 @@
<string name="default_account_flag">Аккаунт по умолчанию</string> <string name="default_account_flag">Аккаунт по умолчанию</string>
<string name="pref_add_account">Добавить аккаунт</string> <string name="pref_add_account">Добавить аккаунт</string>
<string name="pref_in_app_store">Магазин в приложении</string> <string name="pref_in_app_store">Магазин в приложении</string>
<string name="pref_tunnel">Туннель</string> <string name="pref_tunnel_title">Туннель</string>
<string name="pref_tunnel_host">Сервер</string> <string name="pref_tunnel_host">Сервер</string>
<string name="pref_tunnel_port">Порт</string> <string name="pref_tunnel_port">Порт</string>
<string name="pref_tunnel_mode">Режим</string> <string name="pref_tunnel_mode">Режим</string>

View file

@ -133,7 +133,7 @@
<string name="pref_sipaccounts">СИП налози</string> <string name="pref_sipaccounts">СИП налози</string>
<string name="default_account_flag">Основни налог</string> <string name="default_account_flag">Основни налог</string>
<string name="pref_add_account">Додај налог</string> <string name="pref_add_account">Додај налог</string>
<string name="pref_tunnel">Тунел</string> <string name="pref_tunnel_title">Тунел</string>
<string name="pref_tunnel_host">Домаћин</string> <string name="pref_tunnel_host">Домаћин</string>
<string name="pref_tunnel_port">Прикључник</string> <string name="pref_tunnel_port">Прикључник</string>
<string name="pref_tunnel_mode">Режим</string> <string name="pref_tunnel_mode">Режим</string>

View file

@ -355,7 +355,7 @@
<string name="default_account_flag">Standardkonto</string> <string name="default_account_flag">Standardkonto</string>
<string name="pref_add_account">Lägg till konto</string> <string name="pref_add_account">Lägg till konto</string>
<string name="pref_in_app_store">Butik inom app</string> <string name="pref_in_app_store">Butik inom app</string>
<string name="pref_tunnel">Tunnel</string> <string name="pref_tunnel_title">Tunnel</string>
<string name="pref_tunnel_host">Värdnamn</string> <string name="pref_tunnel_host">Värdnamn</string>
<string name="pref_tunnel_port">Port</string> <string name="pref_tunnel_port">Port</string>
<string name="pref_tunnel_mode">Läge</string> <string name="pref_tunnel_mode">Läge</string>

View file

@ -310,7 +310,7 @@
<string name="default_account_flag">Öntanımlı hesap</string> <string name="default_account_flag">Öntanımlı hesap</string>
<string name="pref_add_account">Hesap ekle</string> <string name="pref_add_account">Hesap ekle</string>
<string name="pref_in_app_store">Uygulama İçi Mağaza</string> <string name="pref_in_app_store">Uygulama İçi Mağaza</string>
<string name="pref_tunnel">Tünel</string> <string name="pref_tunnel_title">Tünel</string>
<string name="pref_tunnel_host">Makine Adı</string> <string name="pref_tunnel_host">Makine Adı</string>
<string name="pref_tunnel_port">Bağlanma Noktası</string> <string name="pref_tunnel_port">Bağlanma Noktası</string>
<string name="pref_tunnel_mode">Kip</string> <string name="pref_tunnel_mode">Kip</string>

View file

@ -343,7 +343,7 @@
<string name="default_account_flag">Типова обліківка</string> <string name="default_account_flag">Типова обліківка</string>
<string name="pref_add_account">Додати обліківку</string> <string name="pref_add_account">Додати обліківку</string>
<string name="pref_in_app_store">In-app Store</string> <string name="pref_in_app_store">In-app Store</string>
<string name="pref_tunnel">Тунель</string> <string name="pref_tunnel_title">Тунель</string>
<string name="pref_tunnel_host">Сервер</string> <string name="pref_tunnel_host">Сервер</string>
<string name="pref_tunnel_port">Порт</string> <string name="pref_tunnel_port">Порт</string>
<string name="pref_tunnel_mode">Режим</string> <string name="pref_tunnel_mode">Режим</string>

View file

@ -269,7 +269,7 @@
<string name="default_account_flag">默认账户</string> <string name="default_account_flag">默认账户</string>
<string name="pref_add_account">添加帐户</string> <string name="pref_add_account">添加帐户</string>
<string name="pref_in_app_store">内购商店</string> <string name="pref_in_app_store">内购商店</string>
<string name="pref_tunnel">Tunnel隧道</string> <string name="pref_tunnel_title">Tunnel隧道</string>
<string name="pref_tunnel_host">主机名</string> <string name="pref_tunnel_host">主机名</string>
<string name="pref_tunnel_port">端口</string> <string name="pref_tunnel_port">端口</string>
<string name="pref_tunnel_mode">模式</string> <string name="pref_tunnel_mode">模式</string>

View file

@ -315,7 +315,7 @@
<string name="default_account_flag">預設帳號</string> <string name="default_account_flag">預設帳號</string>
<string name="pref_add_account">加入帳號</string> <string name="pref_add_account">加入帳號</string>
<string name="pref_in_app_store">應用程式內的商店</string> <string name="pref_in_app_store">應用程式內的商店</string>
<string name="pref_tunnel">隧道(Tunnel)</string> <string name="pref_tunnel_title">隧道(Tunnel)</string>
<string name="pref_tunnel_host">主機名稱</string> <string name="pref_tunnel_host">主機名稱</string>
<string name="pref_tunnel_port">連接埠</string> <string name="pref_tunnel_port">連接埠</string>
<string name="pref_tunnel_mode">模式</string> <string name="pref_tunnel_mode">模式</string>

View file

@ -27,4 +27,12 @@
<attr name="button_background_drawable" format="reference" /> <attr name="button_background_drawable" format="reference" />
</declare-styleable> </declare-styleable>
<declare-styleable name="Settings">
<attr name="title" format="string" />
<attr name="subtitle" format="string" />
<attr name="hint" format="string" />
<attr name="list_items_names" format="reference" />
<attr name="list_items_values" format="reference" />
</declare-styleable>
</resources> </resources>

View file

@ -5,193 +5,14 @@
<string name="dummy_group_chat_subject" translatable="false">dummy subject</string> <string name="dummy_group_chat_subject" translatable="false">dummy subject</string>
<string name="pref_dark_mode_key" translatable="false">pref_dark_mode_key</string> <string-array name="popup_enable_log">
<item>@string/debug_popup_enable_logs</item>
<item name="contact_search_name" type="id" /> <item>@string/cancel</item>
<string name="pref_disable_account_key" translatable="false">pref_disable_account_key</string>
<string name="pref_extra_accounts" translatable="false">pref_nb_accounts_extra</string>
<string name="pref_default_account_key" translatable="false">pref_default_account</string>
<string name="pref_tunnel_key" translatable="false">pref_tunnel_key</string>
<string name="pref_tunnel_mode_key" translatable="false">pref_tunnel_mode_key</string>
<string name="tunnel_mode_entry_value_disabled" translatable="false">disabled</string>
<string name="tunnel_mode_entry_value_3G_only" translatable="false">3G_only</string>
<string name="tunnel_mode_entry_value_always" translatable="false">always</string>
<string-array name="tunnel_mode_entry_values">
<item>@string/tunnel_mode_entry_value_disabled</item>
<item>@string/tunnel_mode_entry_value_3G_only</item>
<item>@string/tunnel_mode_entry_value_always</item>
<item>@string/tunnel_mode_entry_value_auto</item>
</string-array> </string-array>
<string name="pref_tunnel_host_key" translatable="false">pref_tunnel_host_key</string> <string-array name="popup_send_log">
<string name="pref_tunnel_port_key" translatable="false">pref_tunnel_port_key</string> <item>@string/debug_popup_disable_logs</item>
<string name="tunnel_mode_entry_value_auto" translatable="false">auto</string> <item>@string/debug_popup_send_logs</item>
<item>@string/cancel</item>
<string name="pref_audio_use_specific_mode_key" translatable="false">pref_audio_use_specific_mode_key</string>
<string name="pref_audio_hacks_use_galaxys_hack_key" translatable="false">pref_audio_hacks_use_galaxys_hack_key</string>
<string name="pref_audio_hacks_use_routing_api_key" translatable="false">pref_audio_hacks_use_routing_api_key</string>
<string name="pref_audio_soft_volume_key" translatable="false">pref_audio_soft_volume_key</string>
<string name="pref_audio_ringtone" translatable="false">pref_audio_ringtone</string>
<string name="pref_incoming_call_vibration_key" translatable="false">pref_incoming_call_vibration_key</string>
<string name="pref_mic_gain_db_key" translatable="false">pref_mic_gain_db_key</string>
<string name="pref_playback_gain_db_key" translatable="false">pref_playback_gain_db_key</string>
<string name="pref_ipv6_key" translatable="false">pref_ipv6_key</string>
<string name="menu_about_key" translatable="false">menu_about_key</string>
<string name="pref_sipaccounts_key" translatable="false">pref_sipaccounts_key</string>
<string name="setup_key" translatable="false">setup_key</string>
<string name="pref_add_account_key" translatable="false">pref_add_account_key</string>
<string name="pref_in_app_store_key" translatable="false">pref_in_app_store_key</string>
<string name="pref_video_key" translatable="false">pref_video_key</string>
<string name="pref_video_codecs_key" translatable="false">pref_video_codecs_key</string>
<string name="pref_transport_key" translatable="false">pref_transport_key</string>
<string name="pref_transport_udp_key" translatable="false">pref_transport_udp_key</string>
<string name="pref_transport_tcp_key" translatable="false">pref_transport_tcp_key</string>
<string name="pref_transport_tls_key" translatable="false">pref_transport_tls_key</string>
<string name="pref_transport_use_random_ports_key" translatable="false">pref_transport_use_random_ports_key</string>
<string name="pref_sip_port_key" translatable="false">pref_sip_port_key</string>
<string name="pref_echo_canceller_calibration_key" translatable="false">pref_echo_canceller_calibration_key</string>
<string name="pref_prefix_key" translatable="false">pref_prefix_key</string>
<string name="pref_proxy_key" translatable="false">pref_proxy_key</string>
<string name="pref_domain_key" translatable="false">pref_domain_key</string>
<string name="pref_passwd_key" translatable="false">pref_passwd_key</string>
<string name="pref_username_key" translatable="false">pref_username_key</string>
<string name="pref_auth_userid_key" translatable="false">pref_auth_userid_key</string>
<string name="pref_wizard_key" translatable="false">pref_wizard_key</string>
<string name="pref_activated_key" translatable="false">pref_activated_key</string>
<string name="pref_debug_key" translatable="false">pref_debug_key</string>
<string name="pref_java_debug_key" translatable="false">pref_java_debug_key</string>
<string name="first_launch_succeeded_once_key" translatable="false">first_launch_succeeded_once_key</string>
<string name="pref_wifi_only_key" translatable="false">pref_wifi_only_key</string>
<string name="pref_doze_mode_key" translatable="false">pref_doze_mode_key</string>
<string name="pref_overlay_key" translatable="false">pref_overlay_key</string>
<string name="pref_video_use_front_camera_key" translatable="false">pref_video_use_front_camera_key</string>
<string name="pref_video_codec_h263_key" translatable="false">pref_video_codec_h263_key</string>
<string name="pref_video_codec_mpeg4_key" translatable="false">pref_video_codec_mpeg4_key</string>
<string name="pref_video_codec_h264_key" translatable="false">pref_video_codec_h264_key</string>
<string name="pref_video_automatically_accept_video_key" translatable="false">pref_video_automatically_accept_video_key</string>
<string name="pref_video_initiate_call_with_video_key" translatable="false">pref_video_initiate_call_with_video_key</string>
<string name="pref_video_enable_key" translatable="false">pref_video_enable_key</string>
<string name="pref_video_preset_key" translatable="false">pref_video_preset_key</string>
<string name="pref_preferred_video_size_key" translatable="false">pref_preferred_video_size_key</string>
<string name="pref_preferred_video_fps_key" translatable="false">pref_preferred_video_fps_key</string>
<string name="pref_bandwidth_limit_key" translatable="false">pref_bandwidth_limit_key</string>
<string name="pref_animation_enable_key" translatable="false">pref_animation_enable_key</string>
<string name="pref_service_notification_key" translatable="false">pref_service_notification_key</string>
<string name="pref_escape_plus_key" translatable="false">pref_escape_plus_key</string>
<string name="pref_friendlist_subscribe_key" translatable="false">pref_friendlist_subscribe_key</string>
<string name="pref_link_account_key" translatable="false">pref_link_account_key</string>
<string name="pref_proxy_push_notif_key" translatable="false">pref_proxy_push_notif_key</string>
<string name="pref_device_power_saver_settings_key" translatable="false">pref_device_power_saver_settings_key</string>
<string name="pref_echo_cancellation_key" translatable="false">pref_echo_cancellation_key</string>
<string name="pref_autostart_key" translatable="false">pref_autostart_key</string>
<string name="pref_enable_outbound_proxy_key" translatable="false">Outbound proxy</string>
<string name="pref_codec_pcma_key" translatable="false">pref_codec_pcma_key</string>
<string name="pref_codec_pcmu_key" translatable="false">pref_codec_pcmu_key</string>
<string name="pref_codec_gsm_key" translatable="false">pref_codec_gsm_key</string>
<string name="pref_codec_g722_key" translatable="false">pref_codec_g722_key</string>
<string name="pref_codec_g729_key" translatable="false">pref_codec_g729_key</string>
<string name="pref_codec_amr_key" translatable="false">pref_codec_amr_key</string>
<string name="pref_codec_amrwb_key" translatable="false">pref_codec_amrwb_key</string>
<string name="pref_codec_ilbc_key" translatable="false">pref_codec_ilbc_key</string>
<string name="pref_codec_speex8_key" translatable="false">pref_codec_speex8_key</string>
<string name="pref_codec_speex16_key" translatable="false">pref_codec_speex16_key</string>
<string name="pref_codec_speex32_key" translatable="false">pref_codec_speex32_key</string>
<string name="pref_codec_silk8_key" translatable="false">pref_codec_silk8_key</string>
<string name="pref_codec_silk12_key" translatable="false">pref_codec_silk12_key</string>
<string name="pref_codec_silk16_key" translatable="false">pref_codec_silk16_key</string>
<string name="pref_codec_silk24_key" translatable="false">pref_codec_silk24_key</string>
<string name="pref_codec_opus_key" translatable="false">pref_codec_opus_key</string>
<string name="pref_codecs_key" translatable="false">pref_codecs_key</string>
<string name="pref_stun_server_key" translatable="false">pref_stun_server_key</string>
<string name="pref_ice_enable_key" translatable="false">pref_ice_enable_key</string>
<string name="pref_turn_enable_key" translatable="false">pref_turn_enable_key</string>
<string name="pref_video_codec_vp8_key" translatable="false">pref_video_codec_vp8_key</string>
<string name="pref_media_encryption_key" translatable="false">pref_media_encryption_key</string>
<string name="pref_media_encryption_key_none" translatable="false">none</string>
<string name="pref_media_encryption_key_srtp" translatable="false">srtp</string>
<string name="pref_media_encryption_key_zrtp" translatable="false">zrtp</string>
<string name="pref_media_encryption_key_dtls" translatable="false">dtls</string>
<string name="pref_background_mode_key" translatable="false">pref_background_mode_key</string>
<string name="pref_codec_bitrate_limit_key" translatable="false">pref_codec_bitrate_limit_key</string>
<string name="pref_adaptive_rate_control_key" translatable="false">pref_adaptive_rate_control_key</string>
<string name="pref_echo_tester_key" translatable="false">pref_echo_tester_key</string>
<string name="pref_auto_download_policy_key" translatable="false">pref_auto_download_policy_key</string>
<string name="pref_auto_download_max_size_key" translatable="false">pref_auto_download_max_size_key</string>
<string name="pref_auto_download_policy_disabled_key" translatable="false">-1</string>
<string name="pref_auto_download_policy_always_key" translatable="false">0</string>
<string name="pref_auto_download_policy_size_key" translatable="false">10000000</string>
<string-array name="pref_auto_download_policy_entries_values">
<item>@string/pref_auto_download_policy_disabled_key</item>
<item>@string/pref_auto_download_policy_always_key</item>
<item>@string/pref_auto_download_policy_size_key</item>
</string-array>
<string name="pref_accept_early_media_key">pref_accept_early_media_key</string>
<string name="push_reg_id_key" translatable="false">push_reg_id_key</string>
<string name="push_sender_id_key" translatable="false">push_sender_id_key</string>
<string name="pref_push_notification_key" translatable="false">pref_push_notification_key</string>
<string name="pref_auto_accept_friends_key" translatable="false">pref_auto_accept_friends_key</string>
<string name="pref_image_sharing_server_key" translatable="false">pref_image_sharing_server_key</string>
<string name="pref_remote_provisioning_key" translatable="false">pref_remote_provisioning_key</string>
<string name="pref_video_port_key" translatable="false">pref_video_port_key</string>
<string name="pref_audio_port_key" translatable="false">pref_audio_port_key</string>
<string name="pref_incoming_call_timeout_key" translatable="false">pref_incoming_expire_key</string>
<string name="pref_call_timeout_key" translatable="false">pref_call_timeout_key</string>
<string name="pref_auto_answer_time_key" translatable="false">pref_auto_answer_time_key</string>
<string name="pref_display_name_key" translatable="false">pref_display_name_key</string>
<string name="pref_user_name_key" translatable="false">pref_user_name_key</string>
<string name="pref_expire_key" translatable="false">pref_expire_key</string>
<string name="pref_avpf_key" translatable="false">pref_avpf_key</string>
<string name="pref_avpf_rr_interval_key" translatable="false">pref_avpf_rr_interval_key</string>
<string name="pref_rfc2833_dtmf_key" translatable="false">pref_rfc2833_dtmf_key</string>
<string name="pref_sipinfo_dtmf_key" translatable="false">pref_sipinfo_dtmf_key</string>
<string name="pref_voice_mail_key" translatable="false">pref_voice_mail_key</string>
<string name="pref_dialer_call_key" translatable="false">pref_dialer_call_key</string>
<string name="pref_upnp_enable_key" translatable="false">pref_upnp_enable_key</string>
<string name="pref_first_time_linphone_chat_storage" translatable="false">pref_first_time_linphone_chat_storage</string>
<string name="pref_sipaccount_key" translatable="false">pref_sipaccount_key</string>
<string name="pref_audio_key" translatable="false">pref_audio_key</string>
<string name="pref_call_key" translatable="false">pref_call_key</string>
<string name="pref_chat_key" translatable="false">pref_chat_key</string>
<string name="pref_network_key" translatable="false">pref_network_key</string>
<string name="pref_advanced_key" translatable="false">pref_advanced_key</string>
<string name="pref_manage_key" translatable="false">pref_manage_key</string>
<string name="pref_video_codec_h263_title" translatable="false">H263</string>
<string name="pref_video_codec_mpeg4_title" translatable="false">MP4V-ES</string>
<string name="pref_video_codec_h264_title" translatable="false">H264</string>
<string name="pref_codec_pcma" translatable="false">pcma</string>
<string name="pref_codec_pcmu" translatable="false">pcmu</string>
<string name="pref_codec_gsm" translatable="false">gsm</string>
<string name="pref_codec_g722" translatable="false">g722</string>
<string name="pref_codec_amr" translatable="false">amr</string>
<string name="pref_codec_amrwb" translatable="false">amr-wb</string>
<string name="pref_codec_ilbc" translatable="false">ilbc</string>
<string name="pref_codec_speex8" translatable="false">speex 8 Khz</string>
<string name="pref_codec_speex16" translatable="false">speex 16 Khz</string>
<string name="pref_codec_opus" translatable="false">opus 48Khz</string>
<string name="pref_codec_silk8" translatable="false">silk 8 Khz</string>
<string name="pref_codec_silk12" translatable="false">silk 12 Khz</string>
<string name="pref_codec_silk16" translatable="false">silk 16 Khz</string>
<string name="pref_codec_silk24" translatable="false">silk 24 Khz</string>
<string name="pref_codec_g729" translatable="false">g729</string>
<string-array name="adaptive_rate_algorithm_entries">
<item>Simple</item>
<item>Stateful</item>
</string-array> </string-array>
<string-array name="limit_bitrate_entry_values"> <string-array name="limit_bitrate_entry_values">
@ -217,33 +38,28 @@
<item>custom</item> <item>custom</item>
</string-array> </string-array>
<string name="pref_video_codec_vp8_title" translatable="false">VP8</string> <string name="pref_auto_download_policy_disabled_key" translatable="false">-1</string>
<string name="media_encryption_srtp" translatable="false">SRTP</string> <string name="pref_auto_download_policy_always_key" translatable="false">0</string>
<string name="media_encryption_zrtp" translatable="false">ZRTP</string> <string name="pref_auto_download_policy_size_key" translatable="false">10000000</string>
<string name="media_encryption_dtls" translatable="false">DTLS</string> <string-array name="pref_auto_download_policy_entries_values">
<item>@string/pref_auto_download_policy_disabled_key</item>
<string name="debug_popup_title" translatable="false">Debug</string> <item>@string/pref_auto_download_policy_always_key</item>
<string-array name="popup_enable_log"> <item>@string/pref_auto_download_policy_size_key</item>
<item>Enable logs</item>
<item>Cancel</item>
</string-array> </string-array>
<string-array name="popup_send_log">
<item>Disable logs</item>
<item>Send logs</item>
<item>Cancel</item>
</string-array>
<string name="pref_use_lime_encryption_key" translatable="false">pref_use_lime_encryption_key</string>
<string name="pref_device_ringtone_key" translatable="false">pref_device_ringtone_key</string>
<string name="pref_auto_answer_key" translatable="false">pref_auto_answer_key</string>
<string name="pref_android_app_settings_key" translatable="false">pref_android_app_settings_key</string>
<string name="pref_android_app_notif_settings_key" translatable="false">pref_android_app_notif_settings_key</string>
<string name="pref_turn_username_key" translatable="false">pref_turn_username_key</string>
<string name="pref_turn_passwd_key" translatable="false">pref_turn_passwd_key</string>
<string-array name="pref_auto_download_policy_entries_labels"> <string-array name="pref_auto_download_policy_entries_labels">
<item>@string/pref_auto_download_disabled</item> <item>@string/pref_auto_download_disabled</item>
<item>@string/pref_auto_download_always</item> <item>@string/pref_auto_download_always</item>
<item>@string/pref_auto_download_under_size</item> <item>@string/pref_auto_download_under_size</item>
</string-array> </string-array>
<string name="tunnel_mode_entry_value_disabled" translatable="false">disabled</string>
<string name="tunnel_mode_entry_value_3G_only" translatable="false">3G_only</string>
<string name="tunnel_mode_entry_value_always" translatable="false">always</string>
<string name="tunnel_mode_entry_value_auto" translatable="false">auto</string>
<string-array name="tunnel_mode_entry_values">
<item>@string/tunnel_mode_entry_value_disabled</item>
<item>@string/tunnel_mode_entry_value_3G_only</item>
<item>@string/tunnel_mode_entry_value_always</item>
<item>@string/tunnel_mode_entry_value_auto</item>
</string-array>
</resources> </resources>

View file

@ -377,7 +377,7 @@
<string name="default_account_flag">Default account</string> <string name="default_account_flag">Default account</string>
<string name="pref_add_account">Add account</string> <string name="pref_add_account">Add account</string>
<string name="pref_in_app_store">In-app Store</string> <string name="pref_in_app_store">In-app Store</string>
<string name="pref_tunnel">Tunnel</string> <string name="pref_tunnel_title">Tunnel</string>
<string name="pref_tunnel_host">Hostname</string> <string name="pref_tunnel_host">Hostname</string>
<string name="pref_tunnel_port">Port</string> <string name="pref_tunnel_port">Port</string>
<string name="pref_tunnel_mode">Mode</string> <string name="pref_tunnel_mode">Mode</string>
@ -506,6 +506,12 @@
<string name="device_power_saver_dialog_button_go_to_settings">Settings</string> <string name="device_power_saver_dialog_button_go_to_settings">Settings</string>
<string name="device_power_saver_dialog_button_later">Later</string> <string name="device_power_saver_dialog_button_later">Later</string>
<!-- Debug popup -->
<string name="debug_popup_title">Debug</string>
<string name="debug_popup_enable_logs">Enable logs</string>
<string name="debug_popup_disable_logs">Disable logs</string>
<string name="debug_popup_send_logs">Send logs</string>
<!-- Content description --> <!-- Content description -->
<string name="content_description_back">Back</string> <string name="content_description_back">Back</string>
<string name="content_description_dialer">Dialer</string> <string name="content_description_dialer">Dialer</string>

View file

@ -308,6 +308,25 @@
<item name="android:textSize">28sp</item> <item name="android:textSize">28sp</item>
</style> </style>
<!-- Settings -->
<style name="settings_category_font" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">?attr/accentColor</item>
<item name="android:textAllCaps">true</item>
<item name="android:textStyle">bold</item>
<item name="android:textSize">12sp</item>
</style>
<style name="settings_item_font" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">?attr/primaryTextColor</item>
<item name="android:textSize">18sp</item>
</style>
<style name="settings_item_subtitle_font" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">?attr/primarySubtextLightColor</item>
<item name="android:textSize">12sp</item>
</style>
<!-- UI various fonts --> <!-- UI various fonts -->
<style name="status_bar_font" parent="@android:style/TextAppearance.Small"> <style name="status_bar_font" parent="@android:style/TextAppearance.Small">

View file

@ -1,136 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="@string/pref_sipaccount_key"
android:persistent="false"
android:title="@string/pref_sipaccount">
<EditTextPreference
android:dialogMessage="@string/pref_help_username"
android:inputType="text|textNoSuggestions"
android:persistent="false"
android:title="@string/pref_username" />
<EditTextPreference
android:dialogMessage="@string/pref_help_auth_userid"
android:inputType="text|textNoSuggestions"
android:persistent="false"
android:title="@string/pref_auth_userid" />
<EditTextPreference
android:dialogMessage="@string/pref_help_password"
android:inputType="textPassword"
android:persistent="false"
android:title="@string/pref_passwd" />
<EditTextPreference
android:dialogMessage="@string/pref_help_domain"
android:inputType="textUri"
android:persistent="false"
android:title="@string/pref_domain" />
<EditTextPreference
android:dialogMessage="@string/pref_help_display_name"
android:inputType="textPersonName"
android:persistent="false"
android:title="@string/pref_display_name" />
</PreferenceCategory>
<PreferenceCategory
android:key="@string/pref_advanced_key"
android:persistent="false"
android:title="@string/pref_advanced_title">
<ListPreference
android:key="@string/pref_transport_key"
android:persistent="false"
android:title="@string/pref_transport" />
<CheckBoxPreference
android:key="@string/pref_ice_enable_key"
android:persistent="false"
android:title="@string/pref_ice_enable" />
<EditTextPreference
android:inputType="textUri"
android:key="@string/pref_stun_server_key"
android:persistent="false"
android:title="@string/pref_stun_server" />
<EditTextPreference
android:inputType="textUri"
android:persistent="false"
android:summary="@string/pref_help_proxy"
android:title="@string/pref_proxy" />
<CheckBoxPreference
android:dialogMessage="@string/pref_help_outbound_proxy"
android:persistent="false"
android:summary="@string/pref_help_outbound_proxy"
android:title="@string/pref_enable_outbound_proxy" />
<EditTextPreference
android:key="@string/pref_expire_key"
android:numeric="integer"
android:persistent="false"
android:title="@string/pref_expire_title" />
<EditTextPreference
android:key="@string/pref_prefix_key"
android:persistent="false"
android:title="@string/pref_prefix" />
<CheckBoxPreference
android:key="@string/pref_avpf_key"
android:persistent="false"
android:title="@string/pref_avpf" />
<EditTextPreference
android:key="@string/pref_avpf_rr_interval_key"
android:numeric="integer"
android:persistent="false"
android:title="@string/pref_avpf_rr_interval" />
<CheckBoxPreference
android:key="@string/pref_escape_plus_key"
android:persistent="false"
android:title="@string/pref_escape_plus" />
<Preference
android:key="@string/pref_link_account_key"
android:persistent="false"
android:title="@string/pref_link_account" />
<CheckBoxPreference
android:key="@string/pref_proxy_push_notif_key"
android:persistent="false"
android:title="@string/pref_proxy_push_notif" />
</PreferenceCategory>
<PreferenceCategory
android:key="@string/pref_manage_key"
android:persistent="false"
android:title="@string/pref_manage_title">
<CheckBoxPreference
android:persistent="false"
android:title="@string/pref_disable_account" />
<CheckBoxPreference
android:persistent="false"
android:title="@string/pref_default_account" />
<Preference
android:persistent="false"
android:title="@string/pref_change_password" />
<Preference
android:persistent="false"
android:title="@string/pref_delete_account" />
</PreferenceCategory>
</PreferenceScreen>

View file

@ -1,473 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<!-- DO NOT PUT A PreferenceCategory INSIDE ANOTHER ONE EVER ! -->
<!-- It will trigger [PreferencesListFragment] addPreferencesFromResource TargetInvocationException error -->
<PreferenceCategory
android:key="@string/pref_sipaccounts_key"
android:persistent="false"
android:title="@string/pref_sipaccounts" />
<Preference
android:key="@string/pref_add_account_key"
android:persistent="false"
android:title="@string/pref_add_account" />
<PreferenceCategory android:title="@string/pref_preferences_title">
<PreferenceScreen
android:key="@string/pref_tunnel_key"
android:persistent="false"
android:title="@string/pref_tunnel">
<PreferenceCategory android:title="@string/pref_tunnel">
<EditTextPreference
android:inputType="textUri"
android:key="@string/pref_tunnel_host_key"
android:persistent="false"
android:title="@string/pref_tunnel_host" />
<EditTextPreference
android:key="@string/pref_tunnel_port_key"
android:numeric="integer"
android:persistent="false"
android:title="@string/pref_tunnel_port" />
<ListPreference
android:entries="@array/tunnel_mode_entries"
android:entryValues="@array/tunnel_mode_entry_values"
android:key="@string/pref_tunnel_mode_key"
android:persistent="false"
android:title="@string/pref_tunnel_mode" />
</PreferenceCategory>
</PreferenceScreen>
<PreferenceScreen
android:key="@string/pref_audio_key"
android:title="@string/pref_audio_title">
<PreferenceCategory android:title="@string/pref_audio_title">
<CheckBoxPreference
android:key="@string/pref_echo_cancellation_key"
android:persistent="false"
android:summary="@string/pref_echo_cancellation_summary"
android:title="@string/pref_echo_cancellation" />
<Preference
android:key="@string/pref_echo_canceller_calibration_key"
android:persistent="false"
android:title="@string/pref_echo_canceller_calibration" />
<Preference
android:key="@string/pref_echo_tester_key"
android:persistent="false"
android:title="@string/pref_echo_tester" />
<CheckBoxPreference
android:key="@string/pref_adaptive_rate_control_key"
android:persistent="false"
android:title="@string/pref_adaptive_rate_control" />
<ListPreference
android:entries="@array/limit_bitrate_entries"
android:entryValues="@array/limit_bitrate_entry_values"
android:key="@string/pref_codec_bitrate_limit_key"
android:persistent="false"
android:title="@string/pref_codec_bitrate_limit" />
<EditTextPreference
android:key="@string/pref_mic_gain_db_key"
android:persistent="false"
android:inputType="numberSigned|numberDecimal"
android:title="@string/pref_mic_gain_db" />
<EditTextPreference
android:key="@string/pref_playback_gain_db_key"
android:persistent="false"
android:inputType="numberSigned|numberDecimal"
android:title="@string/pref_playback_gain_db" />
</PreferenceCategory>
<PreferenceCategory
android:key="@string/pref_codecs_key"
android:persistent="false"
android:title="@string/pref_codecs" />
</PreferenceScreen>
<PreferenceScreen
android:key="@string/pref_video_key"
android:persistent="false"
android:title="@string/pref_video_title">
<PreferenceCategory android:title="@string/pref_video_title">
<CheckBoxPreference
android:key="@string/pref_video_enable_key"
android:persistent="false"
android:title="@string/pref_video_enable_title" />
<CheckBoxPreference
android:dependency="@string/pref_video_enable_key"
android:key="@string/pref_video_use_front_camera_key"
android:layout="@layout/hidden"
android:persistent="false"
android:title="@string/pref_video_use_front_camera_title" />
<CheckBoxPreference
android:dependency="@string/pref_video_enable_key"
android:key="@string/pref_video_initiate_call_with_video_key"
android:persistent="false"
android:summary="@string/pref_video_initiate_call_with_video"
android:title="@string/pref_video_initiate_call_with_video_title" />
<CheckBoxPreference
android:dependency="@string/pref_video_enable_key"
android:key="@string/pref_video_automatically_accept_video_key"
android:persistent="false"
android:summary="@string/pref_video_automatically_accept_video"
android:title="@string/pref_video_automatically_accept_video_title" />
<CheckBoxPreference
android:dependency="@string/pref_video_enable_key"
android:key="@string/pref_overlay_key"
android:persistent="false"
android:shouldDisableView="true"
android:summary="@string/pref_overlay_summary"
android:title="@string/pref_overlay" />
<ListPreference
android:dependency="@string/pref_video_enable_key"
android:entries="@array/video_preset_entries"
android:entryValues="@array/video_preset_entries"
android:key="@string/pref_video_preset_key"
android:persistent="false"
android:shouldDisableView="true"
android:title="@string/pref_video_preset" />
<ListPreference
android:dependency="@string/pref_video_enable_key"
android:key="@string/pref_preferred_video_size_key"
android:persistent="false"
android:shouldDisableView="true"
android:title="@string/pref_preferred_video_size" />
<ListPreference
android:dependency="@string/pref_video_enable_key"
android:key="@string/pref_preferred_video_fps_key"
android:persistent="false"
android:shouldDisableView="true"
android:title="@string/pref_preferred_fps" />
<EditTextPreference
android:dependency="@string/pref_video_enable_key"
android:key="@string/pref_bandwidth_limit_key"
android:numeric="integer"
android:persistent="false"
android:shouldDisableView="true"
android:title="@string/pref_bandwidth_limit" />
</PreferenceCategory>
<PreferenceCategory
android:dependency="@string/pref_video_enable_key"
android:key="@string/pref_video_codecs_key"
android:persistent="false"
android:shouldDisableView="true"
android:title="@string/pref_video_codecs_title" />
</PreferenceScreen>
<PreferenceScreen
android:key="@string/pref_call_key"
android:title="@string/pref_call_title">
<PreferenceCategory android:title="@string/pref_call_title">
<CheckBoxPreference
android:key="@string/pref_device_ringtone_key"
android:persistent="false"
android:title="@string/pref_device_ringtone" />
<CheckBoxPreference
android:key="@string/pref_incoming_call_vibration_key"
android:persistent="false"
android:title="@string/pref_vibrate_on_incoming_calls" />
<ListPreference
android:key="@string/pref_media_encryption_key"
android:persistent="false"
android:title="@string/pref_media_encryption" />
<CheckBoxPreference
android:key="@string/pref_sipinfo_dtmf_key"
android:persistent="false"
android:title="@string/pref_sipinfo_dtmf" />
<CheckBoxPreference
android:key="@string/pref_rfc2833_dtmf_key"
android:persistent="false"
android:title="@string/pref_rfc2833_dtmf" />
<CheckBoxPreference
android:key="@string/pref_auto_answer_key"
android:persistent="false"
android:title="@string/pref_auto_answer" />
<EditTextPreference
android:key="@string/pref_auto_answer_time_key"
android:numeric="integer"
android:persistent="false"
android:title="@string/pref_auto_answer_time" />
<EditTextPreference
android:key="@string/pref_incoming_call_timeout_key"
android:numeric="integer"
android:persistent="false"
android:title="@string/pref_incoming_call_timeout_title" />
<CheckBoxPreference
android:key="@string/pref_accept_early_media_key"
android:persistent="false"
android:layout="@layout/hidden"
android:title="@string/pref_accept_early_media" />
<EditTextPreference
android:key="@string/pref_voice_mail_key"
android:persistent="false"
android:title="@string/pref_voice_mail" />
<CheckBoxPreference
android:key="@string/pref_dialer_call_key"
android:persistent="false"
android:title="@string/pref_dialer_call" />
</PreferenceCategory>
</PreferenceScreen>
<PreferenceScreen
android:key="@string/pref_chat_key"
android:title="@string/pref_chat_title">
<PreferenceCategory android:title="@string/pref_chat_title">
<EditTextPreference
android:inputType="textUri"
android:key="@string/pref_image_sharing_server_key"
android:persistent="false"
android:summary="@string/pref_image_sharing_server_desc"
android:title="@string/pref_image_sharing_server_title" />
<ListPreference
android:entries="@array/pref_auto_download_policy_entries_labels"
android:entryValues="@array/pref_auto_download_policy_entries_values"
android:key="@string/pref_auto_download_policy_key"
android:persistent="false"
android:title="@string/pref_auto_download_policy_title" />
<EditTextPreference
android:inputType="numberSigned"
android:key="@string/pref_auto_download_max_size_key"
android:persistent="false"
android:title="@string/pref_auto_download_max_size_title" />
<Preference
android:key="@string/pref_android_app_notif_settings_key"
android:persistent="false"
android:title="@string/pref_android_app_notif_settings_title" />
</PreferenceCategory>
</PreferenceScreen>
<PreferenceScreen
android:key="@string/pref_network_key"
android:title="@string/pref_network_title">
<PreferenceCategory android:title="@string/pref_network_title">
<CheckBoxPreference
android:key="@string/pref_wifi_only_key"
android:persistent="false"
android:title="@string/pref_wifi_only" />
<CheckBoxPreference
android:key="@string/pref_ipv6_key"
android:persistent="false"
android:title="@string/pref_ipv6_title" />
<CheckBoxPreference
android:key="@string/pref_push_notification_key"
android:persistent="false"
android:title="@string/pref_push_notification" />
<Preference
android:key="@string/pref_device_power_saver_settings_key"
android:persistent="false"
android:summary="@string/pref_protected_settings_desc"
android:title="@string/pref_protected_settings_title" />
<CheckBoxPreference
android:key="@string/pref_transport_use_random_ports_key"
android:persistent="false"
android:title="@string/pref_transport_use_random_ports" />
<EditTextPreference
android:key="@string/pref_sip_port_key"
android:numeric="integer"
android:persistent="false"
android:title="@string/pref_sip_port_title" />
<EditTextPreference
android:inputType="textUri"
android:key="@string/pref_stun_server_key"
android:persistent="false"
android:title="@string/pref_stun_server" />
<CheckBoxPreference
android:key="@string/pref_ice_enable_key"
android:persistent="false"
android:title="@string/pref_ice_enable" />
<CheckBoxPreference
android:key="@string/pref_turn_enable_key"
android:persistent="false"
android:title="@string/pref_turn_enable" />
<EditTextPreference
android:inputType="text|textNoSuggestions"
android:key="@string/pref_turn_username_key"
android:persistent="false"
android:title="@string/pref_turn_username_title" />
<EditTextPreference
android:inputType="textPassword"
android:key="@string/pref_turn_passwd_key"
android:persistent="false"
android:title="@string/pref_turn_passwd_title" />
<EditTextPreference
android:key="@string/pref_audio_port_key"
android:layout="@layout/hidden"
android:persistent="false"
android:summary="@string/pref_audio_port_description"
android:title="@string/pref_audio_port_title" />
<EditTextPreference
android:key="@string/pref_video_port_key"
android:layout="@layout/hidden"
android:persistent="false"
android:summary="@string/pref_video_port_description"
android:title="@string/pref_video_port_title" />
</PreferenceCategory>
</PreferenceScreen>
<PreferenceScreen
android:key="@string/pref_advanced_key"
android:title="@string/pref_advanced_title">
<PreferenceCategory android:title="@string/pref_debug_title">
<CheckBoxPreference
android:key="@string/pref_debug_key"
android:persistent="false"
android:title="@string/pref_debug" />
<CheckBoxPreference
android:key="@string/pref_java_debug_key"
android:persistent="false"
android:title="@string/pref_java_debug" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_advanced_title">
<CheckBoxPreference
android:key="@string/pref_friendlist_subscribe_key"
android:persistent="false"
android:title="@string/pref_friendlist_subscribe" />
<CheckBoxPreference
android:key="@string/pref_background_mode_key"
android:persistent="false"
android:title="@string/pref_background_mode" />
<CheckBoxPreference
android:key="@string/pref_service_notification_key"
android:persistent="false"
android:title="@string/pref_service_notification" />
<CheckBoxPreference
android:key="@string/pref_autostart_key"
android:persistent="false"
android:title="@string/pref_autostart" />
<CheckBoxPreference
android:key="@string/pref_dark_mode_key"
android:persistent="false"
android:title="@string/pref_dark_mode" />
<EditTextPreference
android:inputType="textUri"
android:key="@string/pref_remote_provisioning_key"
android:persistent="false"
android:title="@string/pref_remote_provisioning_title" />
<Preference
android:key="@string/pref_android_app_settings_key"
android:persistent="false"
android:title="@string/pref_android_app_settings_title" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_primary_account_title">
<EditTextPreference
android:inputType="textPersonName"
android:key="@string/pref_display_name_key"
android:persistent="false"
android:title="@string/pref_display_name_title" />
<EditTextPreference
android:key="@string/pref_user_name_key"
android:persistent="false"
android:title="@string/pref_user_name_title" />
</PreferenceCategory>
<PreferenceScreen
android:layout="@layout/hidden"
android:title="@string/pref_audio_hacks_title">
<CheckBoxPreference
android:key="@string/pref_audio_hacks_use_routing_api_key"
android:persistent="false"
android:title="@string/pref_audio_hacks_use_routing_api_title" />
<CheckBoxPreference
android:key="@string/pref_audio_hacks_use_galaxys_hack_key"
android:persistent="false"
android:title="@string/pref_audio_hacks_use_galaxys_hack_title" />
<EditTextPreference
android:key="@string/pref_audio_use_specific_mode_key"
android:numeric="integer"
android:persistent="false"
android:summary="@string/pref_audio_use_specific_mode_summary"
android:title="@string/pref_audio_use_specific_mode_title" />
</PreferenceScreen>
</PreferenceScreen>
</PreferenceCategory>
</PreferenceScreen>