diff --git a/app/src/main/java/org/linphone/LinphoneActivity.java b/app/src/main/java/org/linphone/LinphoneActivity.java index b28b22018..58740245d 100644 --- a/app/src/main/java/org/linphone/LinphoneActivity.java +++ b/app/src/main/java/org/linphone/LinphoneActivity.java @@ -110,7 +110,8 @@ import org.linphone.history.HistoryDetailFragment; import org.linphone.history.HistoryFragment; import org.linphone.purchase.InAppPurchaseActivity; 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.SettingsFragment; import org.linphone.utils.DeviceUtils; @@ -431,8 +432,11 @@ public class LinphoneActivity extends LinphoneGenericActivity case SETTINGS: mFragment = new SettingsFragment(); break; + case SETTINGS_SUBLEVEL: + mFragment = new AudioSettingsFragment(); + break; case ACCOUNT_SETTINGS: - mFragment = new AccountPreferencesFragment(); + mFragment = new AccountSettingsFragment(); break; case ABOUT: mFragment = new AboutFragment(); @@ -469,6 +473,15 @@ public class LinphoneActivity extends LinphoneGenericActivity 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) { mFragment.setArguments(extras); if (isTablet()) { @@ -560,6 +573,7 @@ public class LinphoneActivity extends LinphoneGenericActivity if (newFragmentType == FragmentsAvailable.DIALER || newFragmentType == FragmentsAvailable.ABOUT || newFragmentType == FragmentsAvailable.SETTINGS + || newFragmentType == FragmentsAvailable.SETTINGS_SUBLEVEL || newFragmentType == FragmentsAvailable.ACCOUNT_SETTINGS || newFragmentType == FragmentsAvailable.CREATE_CHAT || newFragmentType == FragmentsAvailable.INFO_GROUP_CHAT) { @@ -688,6 +702,10 @@ public class LinphoneActivity extends LinphoneGenericActivity changeCurrentFragment(FragmentsAvailable.RECORDING_LIST, null); } + public void displaySubSettings(Fragment fragment) { + changeSettingsFragment(fragment); + } + public void displayContactsForEdition(String sipAddress, String displayName) { Bundle extras = new Bundle(); extras.putBoolean("EditOnClick", true); @@ -834,7 +852,11 @@ public class LinphoneActivity extends LinphoneGenericActivity mChatSelected.setVisibility(View.VISIBLE); } else if (id == R.id.cancel) { hideTopBar(); - displayDialer(); + if (mCurrentFragment == FragmentsAvailable.SETTINGS_SUBLEVEL) { + popBackStack(); + } else { + displayDialer(); + } } } @@ -867,8 +889,12 @@ public class LinphoneActivity extends LinphoneGenericActivity mTopBarTitle.setText(title); } - @SuppressWarnings("incomplete-switch") public void selectMenu(FragmentsAvailable menuToSelect) { + selectMenu(menuToSelect, null); + } + + @SuppressWarnings("incomplete-switch") + public void selectMenu(FragmentsAvailable menuToSelect, String customTitle) { mCurrentFragment = menuToSelect; resetSelection(); boolean hideBottomBar = @@ -899,7 +925,12 @@ public class LinphoneActivity extends LinphoneGenericActivity case SETTINGS: case ACCOUNT_SETTINGS: hideTabBar(hideBottomBar); - showTopBarWithTitle(getString(R.string.settings)); + case SETTINGS_SUBLEVEL: + if (customTitle == null) { + showTopBarWithTitle(getString(R.string.settings)); + } else { + showTopBarWithTitle(customTitle); + } break; case ABOUT: showTopBarWithTitle(getString(R.string.about)); @@ -1286,9 +1317,7 @@ public class LinphoneActivity extends LinphoneGenericActivity break; case PERMISSIONS_RECORD_AUDIO_ECHO_CANCELLER: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { - ((SettingsFragment) mFragment).startEchoCancellerCalibration(); - } else { - ((SettingsFragment) mFragment).echoCalibrationFail(); + ((AudioSettingsFragment) mFragment).startEchoCancellerCalibration(); } break; case PERMISSIONS_READ_EXTERNAL_STORAGE_DEVICE_RINGTONE: @@ -1299,7 +1328,7 @@ public class LinphoneActivity extends LinphoneGenericActivity break; case PERMISSIONS_RECORD_AUDIO_ECHO_TESTER: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) - ((SettingsFragment) mFragment).startEchoTester(); + ((AudioSettingsFragment) mFragment).startEchoTester(); break; } } @@ -1389,6 +1418,7 @@ public class LinphoneActivity extends LinphoneGenericActivity if (mCurrentFragment == FragmentsAvailable.DIALER || mCurrentFragment == FragmentsAvailable.ABOUT || mCurrentFragment == FragmentsAvailable.SETTINGS + || mCurrentFragment == FragmentsAvailable.SETTINGS_SUBLEVEL || mCurrentFragment == FragmentsAvailable.ACCOUNT_SETTINGS) { ll.setVisibility(View.GONE); } @@ -1437,11 +1467,11 @@ public class LinphoneActivity extends LinphoneGenericActivity protected void onNewIntent(Intent intent) { super.onNewIntent(intent); - if (getCurrentFragment() == FragmentsAvailable.SETTINGS) { + /*if (getCurrentFragment() == FragmentsAvailable.SETTINGS) { if (mFragment instanceof SettingsFragment) { ((SettingsFragment) mFragment).closePreferenceScreen(); } - } + }*/ Bundle extras = intent.getExtras(); if (extras != null) { diff --git a/app/src/main/java/org/linphone/assistant/AssistantActivity.java b/app/src/main/java/org/linphone/assistant/AssistantActivity.java index c6e778fe5..083d93eb5 100644 --- a/app/src/main/java/org/linphone/assistant/AssistantActivity.java +++ b/app/src/main/java/org/linphone/assistant/AssistantActivity.java @@ -36,7 +36,6 @@ import android.content.res.Configuration; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; -import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; @@ -66,7 +65,6 @@ import org.linphone.core.Address; import org.linphone.core.AuthInfo; import org.linphone.core.ConfiguringState; import org.linphone.core.Core; -import org.linphone.core.CoreException; import org.linphone.core.CoreListenerStub; import org.linphone.core.DialPlan; import org.linphone.core.Factory; @@ -78,7 +76,6 @@ import org.linphone.core.tools.OpenH264DownloadHelper; import org.linphone.fragments.StatusFragment; import org.linphone.mediastream.Version; import org.linphone.settings.LinphonePreferences; -import org.linphone.settings.LinphonePreferences.AccountBuilder; import org.linphone.utils.LinphoneUtils; import org.linphone.utils.ThemableActivity; @@ -515,8 +512,31 @@ public class AssistantActivity extends ThemableActivity String prefix, String domain, TransportType transport) { - saveCreatedAccount( - username, userid, password, displayname, null, prefix, domain, transport); + Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + 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 = ""; + proxyConfig.setServerAddr(proxy); + + proxyConfig.setDialPrefix(prefix); + + core.addProxyConfig(proxyConfig); + core.setDefaultProxyConfig(proxyConfig); + + mAccountCreated = true; + success(); } private void display(AssistantFragmentsEnum fragment) { @@ -618,54 +638,6 @@ public class AssistantActivity extends ThemableActivity 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() { if (LinphoneManager.getLc().isNetworkReachable()) { mProgress = ProgressDialog.show(this, null, null); diff --git a/app/src/main/java/org/linphone/fragments/FragmentsAvailable.java b/app/src/main/java/org/linphone/fragments/FragmentsAvailable.java index db9ff7aec..bc75e1ca6 100644 --- a/app/src/main/java/org/linphone/fragments/FragmentsAvailable.java +++ b/app/src/main/java/org/linphone/fragments/FragmentsAvailable.java @@ -31,6 +31,7 @@ public enum FragmentsAvailable { ABOUT, ACCOUNT_SETTINGS, SETTINGS, + SETTINGS_SUBLEVEL, CHAT_LIST, CHAT, CREATE_CHAT, diff --git a/app/src/main/java/org/linphone/settings/AccountPreferencesFragment.java b/app/src/main/java/org/linphone/settings/AccountPreferencesFragment.java deleted file mode 100644 index 753aa85cd..000000000 --- a/app/src/main/java/org/linphone/settings/AccountPreferencesFragment.java +++ /dev/null @@ -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 entries, List 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 entries = new ArrayList<>(); - List 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) {} -} diff --git a/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java b/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java new file mode 100644 index 000000000..97f82535d --- /dev/null +++ b/app/src/main/java/org/linphone/settings/AccountSettingsFragment.java @@ -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 entries = new ArrayList<>(); + List 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); + } +} diff --git a/app/src/main/java/org/linphone/settings/AdvancedSettingsFragment.java b/app/src/main/java/org/linphone/settings/AdvancedSettingsFragment.java new file mode 100644 index 000000000..96f907e5b --- /dev/null +++ b/app/src/main/java/org/linphone/settings/AdvancedSettingsFragment.java @@ -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(); + } +} diff --git a/app/src/main/java/org/linphone/settings/AudioSettingsFragment.java b/app/src/main/java/org/linphone/settings/AudioSettingsFragment.java new file mode 100644 index 000000000..4348fa8ce --- /dev/null +++ b/app/src/main/java/org/linphone/settings/AudioSettingsFragment.java @@ -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(); + } +} diff --git a/app/src/main/java/org/linphone/settings/CallSettingsFragment.java b/app/src/main/java/org/linphone/settings/CallSettingsFragment.java new file mode 100644 index 000000000..fb6172151 --- /dev/null +++ b/app/src/main/java/org/linphone/settings/CallSettingsFragment.java @@ -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 entries = new ArrayList<>(); + List 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); + } +} diff --git a/app/src/main/java/org/linphone/settings/ChatSettingsFragment.java b/app/src/main/java/org/linphone/settings/ChatSettingsFragment.java new file mode 100644 index 000000000..25db7cde1 --- /dev/null +++ b/app/src/main/java/org/linphone/settings/ChatSettingsFragment.java @@ -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); + } +} diff --git a/app/src/main/java/org/linphone/settings/LinphonePreferences.java b/app/src/main/java/org/linphone/settings/LinphonePreferences.java index e080dd166..4ba635d55 100644 --- a/app/src/main/java/org/linphone/settings/LinphonePreferences.java +++ b/app/src/main/java/org/linphone/settings/LinphonePreferences.java @@ -29,19 +29,17 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; +import org.linphone.LinphoneActivity; import org.linphone.LinphoneManager; import org.linphone.R; -import org.linphone.core.AVPFMode; import org.linphone.core.Address; import org.linphone.core.AuthInfo; import org.linphone.core.Config; import org.linphone.core.Core; -import org.linphone.core.CoreException; import org.linphone.core.Factory; import org.linphone.core.MediaEncryption; import org.linphone.core.NatPolicy; import org.linphone.core.ProxyConfig; -import org.linphone.core.TransportType; import org.linphone.core.Transports; import org.linphone.core.Tunnel; import org.linphone.core.TunnelConfig; @@ -150,311 +148,21 @@ public class LinphonePreferences { 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) { AuthInfo authInfo = getAuthInfo(n); 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) { AuthInfo authInfo = getAuthInfo(n); 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) { ProxyConfig proxyConf = getProxyConfig(n); 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) { ProxyConfig prxCfg = getProxyConfig(n); prxCfg.edit(); @@ -462,57 +170,6 @@ public class LinphonePreferences { 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() { if (getConfig().getBool("app", "friendlist_subscription_enabled", false)) { // Old setting, do migration @@ -526,13 +183,6 @@ public class LinphonePreferences { 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() { if (getLc() == null) return -1; ProxyConfig defaultPrxCfg = getLc().getDefaultProxyConfig(); @@ -599,24 +249,6 @@ public class LinphonePreferences { 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 // Audio settings @@ -871,13 +503,6 @@ public class LinphonePreferences { getLc().setNatPolicy(nat); } - public void setUpnpEnabled(boolean enabled) { - if (getLc() == null) return; - NatPolicy nat = getOrCreateNatPolicy(); - nat.enableUpnp(enabled); - getLc().setNatPolicy(nat); - } - public boolean isIceEnabled() { NatPolicy nat = getOrCreateNatPolicy(); return nat.iceEnabled(); @@ -1338,7 +963,13 @@ public class LinphonePreferences { } 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() { @@ -1426,188 +1057,8 @@ public class LinphonePreferences { public void enableDarkMode(boolean enable) { getConfig().setBool("app", "dark_mode", enable); - } - - 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(" entries, List 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 closePreferenceScreen() { - if (mCurrentPreferenceScreen != null && mCurrentPreferenceScreen.getDialog() != null) { - mCurrentPreferenceScreen.getDialog().dismiss(); - mCurrentPreferenceScreen = null; - } - } - - @Override - public void onStart() { - super.onStart(); - addPreferencesFromResource(R.xml.preferences); - - mPrefs = LinphonePreferences.instance(); - removePreviousPreferencesFile(); // Required when updating the preferences order - - mListener = - new CoreListenerStub() { - @Override - public void onEcCalibrationResult( - Core lc, EcCalibratorStatus status, int delayMs) { - lc.removeListener(mListener); - LinphoneManager.getInstance().routeAudioToReceiver(); - - CheckBoxPreference echoCancellation = - (CheckBoxPreference) - findPreference( - getString(R.string.pref_echo_cancellation_key)); - Preference echoCancellerCalibration = - findPreference( - getString(R.string.pref_echo_canceller_calibration_key)); - - if (status == EcCalibratorStatus.DoneNoEcho) { - echoCancellerCalibration.setSummary(R.string.no_echo); - echoCancellation.setChecked(false); - LinphonePreferences.instance().setEchoCancellation(false); - ((AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE)) - .setMode(AudioManager.MODE_NORMAL); - Log.i("Set audio mode on 'Normal'"); - } else if (status == EcCalibratorStatus.Done) { - echoCancellerCalibration.setSummary( - String.format( - getString(R.string.ec_calibrated), - String.valueOf(delayMs))); - echoCancellation.setChecked(true); - LinphonePreferences.instance().setEchoCancellation(true); - ((AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE)) - .setMode(AudioManager.MODE_NORMAL); - Log.i("Set audio mode on 'Normal'"); - } else if (status == EcCalibratorStatus.Failed) { - echoCancellerCalibration.setSummary(R.string.failed); - echoCancellation.setChecked(true); - LinphonePreferences.instance().setEchoCancellation(true); - ((AudioManager) getActivity().getSystemService(Context.AUDIO_SERVICE)) - .setMode(AudioManager.MODE_NORMAL); - Log.i("Set audio mode on 'Normal'"); - } - } - }; - - initSettings(); + loadSettings(); setListeners(); - hideSettings(); + + return mRootView; } @Override public void onResume() { super.onResume(); - // Init the settings page interface - initAccounts(); - if (LinphoneActivity.isInstanciated()) { LinphoneActivity.instance().selectMenu(FragmentsAvailable.SETTINGS); } + + updateValues(); } - @Override - public void onPause() { - if (LinphoneActivity.isInstanciated() && LinphoneManager.isInstanciated()) { - if (LinphoneManager.getInstance().getEchoTesterStatus()) stopEchoTester(); - LinphoneActivity.instance().hideTopBar(); - } - super.onPause(); + protected void loadSettings() { + mAccounts = mRootView.findViewById(R.id.accounts_settings_list); + mAccountsHeader = mRootView.findViewById(R.id.accounts_settings_list_header); + + mTunnel = mRootView.findViewById(R.id.pref_tunnel); + + mAudio = mRootView.findViewById(R.id.pref_audio); + + mVideo = mRootView.findViewById(R.id.pref_video); + + mCall = mRootView.findViewById(R.id.pref_call); + + mChat = mRootView.findViewById(R.id.pref_chat); + + mNetwork = mRootView.findViewById(R.id.pref_network); + + mAdvanced = mRootView.findViewById(R.id.pref_advanced); } - private void removePreviousPreferencesFile() { - SharedPreferences.Editor editor = getPreferenceManager().getSharedPreferences().edit(); - editor.clear(); - editor.apply(); - - File dir = new File(getActivity().getFilesDir().getAbsolutePath() + "shared_prefs"); - FileUtils.recursiveFileRemoval(dir); - } - - // Inits the values or the listener on some settings - private void initSettings() { - initTunnelSettings(); - initAudioSettings(); - initVideoSettings(); - initCallSettings(); - initChatSettings(); - initNetworkSettings(); - initAdvancedSettings(); - - findPreference(getString(R.string.pref_add_account_key)) - .setOnPreferenceClickListener( - new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - int nbAccounts = mPrefs.getAccountCount(); - LinphoneActivity.instance().displayAccountSettings(nbAccounts); - return true; - } - }); - } - - // Sets listener for each preference to update the matching value in linphonecore - private void setListeners() { - findPreference(getString(R.string.pref_tunnel_key)) - .setOnPreferenceClickListener(mPrefClickListener); - findPreference(getString(R.string.pref_audio_key)) - .setOnPreferenceClickListener(mPrefClickListener); - findPreference(getString(R.string.pref_video_key)) - .setOnPreferenceClickListener(mPrefClickListener); - findPreference(getString(R.string.pref_call_key)) - .setOnPreferenceClickListener(mPrefClickListener); - findPreference(getString(R.string.pref_chat_key)) - .setOnPreferenceClickListener(mPrefClickListener); - findPreference(getString(R.string.pref_network_key)) - .setOnPreferenceClickListener(mPrefClickListener); - findPreference(getString(R.string.pref_advanced_key)) - .setOnPreferenceClickListener(mPrefClickListener); - - setTunnelPreferencesListener(); - setAudioPreferencesListener(); - setVideoPreferencesListener(); - setCallPreferencesListener(); - setChatPreferencesListener(); - setNetworkPreferencesListener(); - setAdvancedPreferencesListener(); - } - - // Read the values set in resources and hides the settings accordingly - private void hideSettings() { - if (getResources().getBoolean(R.bool.hide_accounts)) { - emptyAndHidePreference(R.string.pref_sipaccounts_key); - } - - if (!getResources().getBoolean(R.bool.replace_assistant_with_old_interface)) { - hidePreference(R.string.pref_add_account_key); - } - - if (getResources().getBoolean(R.bool.disable_chat)) { - findPreference(getString(R.string.pref_image_sharing_server_key)) - .setLayoutResource(R.layout.hidden); - } - - if (!getResources().getBoolean(R.bool.enable_push_id)) { - hidePreference(R.string.pref_push_notification_key); - } - - if (!DeviceUtils.hasDevicePowerManager(LinphoneActivity.instance())) { - hidePreference(R.string.pref_device_power_saver_settings_key); - } - - if (!Version.isVideoCapable() - || !LinphoneManager.getLcIfManagerNotDestroyedOrNull().videoSupported()) { - emptyAndHidePreference(R.string.pref_video_key); - } else { - if (!AndroidCameraConfiguration.hasFrontCamera()) { - uncheckAndHidePreference(R.string.pref_video_use_front_camera_key); - } - } - - if (!LinphoneManager.getLc().tunnelAvailable()) { - emptyAndHidePreference(R.string.pref_tunnel_key); - } - - if (getResources().getBoolean(R.bool.hide_camera_settings)) { - emptyAndHidePreference(R.string.pref_video_key); - } - - if (getResources().getBoolean(R.bool.disable_every_log)) { - uncheckAndHidePreference(R.string.pref_debug_key); - uncheckAndHidePreference(R.string.pref_java_debug_key); - } - } - - private void uncheckAndHidePreference(int preferenceKey) { - Preference preference = findPreference(getString(preferenceKey)); - if (!(preference instanceof CheckBoxPreference)) return; - - CheckBoxPreference checkBoxPreference = (CheckBoxPreference) preference; - checkBoxPreference.setChecked(false); - hidePreference(checkBoxPreference); - } - - private void emptyAndHidePreference(int preferenceKey) { - Preference preference = findPreference(getString(preferenceKey)); - if (preference instanceof PreferenceCategory) emptyAndHidePreferenceCategory(preferenceKey); - else if (preference instanceof PreferenceScreen) - emptyAndHidePreferenceScreen(preferenceKey); - } - - private void emptyAndHidePreferenceCategory(int preferenceKey) { - Preference preference = findPreference(getString(preferenceKey)); - if (!(preference instanceof PreferenceCategory)) return; - - PreferenceCategory preferenceCategory = (PreferenceCategory) preference; - preferenceCategory.removeAll(); - hidePreference(preferenceCategory); - } - - private void emptyAndHidePreferenceScreen(int preferenceKey) { - Preference preference = findPreference(getString(preferenceKey)); - if (!(preference instanceof PreferenceScreen)) return; - - PreferenceScreen preferenceScreen = (PreferenceScreen) preference; - preferenceScreen.removeAll(); - hidePreference(preferenceScreen); - } - - private void hidePreference(int preferenceKey) { - hidePreference(findPreference(getString(preferenceKey))); - } - - private void hidePreference(Preference preference) { - preference.setLayoutResource(R.layout.hidden); - } - - private void setPreferenceDefaultValueAndSummary(int pref, String value) { - if (value != null) { - EditTextPreference etPref = (EditTextPreference) findPreference(getString(pref)); - if (etPref != null) { - etPref.setText(value); - etPref.setSummary(value); - } - } - } - - private void initTunnelSettings() { - if (!LinphoneManager.isInstanciated() || !LinphoneManager.getLc().tunnelAvailable()) { - return; - } - - setPreferenceDefaultValueAndSummary(R.string.pref_tunnel_host_key, mPrefs.getTunnelHost()); - setPreferenceDefaultValueAndSummary( - R.string.pref_tunnel_port_key, String.valueOf(mPrefs.getTunnelPort())); - ListPreference tunnelModePref = - (ListPreference) findPreference(getString(R.string.pref_tunnel_mode_key)); - String tunnelMode = mPrefs.getTunnelMode(); - tunnelModePref.setSummary(tunnelMode); - tunnelModePref.setValue(tunnelMode); - } - - private void setTunnelPreferencesListener() { - findPreference(getString(R.string.pref_tunnel_host_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String host = newValue.toString(); - mPrefs.setTunnelHost(host); - preference.setSummary(host); - return true; - } - }); - findPreference(getString(R.string.pref_tunnel_port_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - try { - int port = Integer.parseInt(newValue.toString()); - mPrefs.setTunnelPort(port); - preference.setSummary(String.valueOf(port)); - return true; - } catch (NumberFormatException nfe) { - return false; - } - } - }); - findPreference(getString(R.string.pref_tunnel_mode_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String mode = newValue.toString(); - mPrefs.setTunnelMode(mode); - preference.setSummary(mode); - return true; - } - }); - } - - private void initAccounts() { - if (!getResources().getBoolean(R.bool.hide_accounts)) { - PreferenceCategory accounts = - (PreferenceCategory) findPreference(getString(R.string.pref_sipaccounts_key)); - accounts.removeAll(); - - // Get already configured extra accounts - int defaultAccountID = mPrefs.getDefaultAccountIndex(); - int nbAccounts = mPrefs.getAccountCount(); - for (int i = 0; i < nbAccounts; i++) { - final int accountId = i; - // For each, add menus to configure it - String username = mPrefs.getAccountUsername(accountId); - String domain = mPrefs.getAccountDomain(accountId); - LedPreference account = new LedPreference(getActivity()); - - if (username == null) { - account.setTitle(getString(R.string.pref_sipaccount)); - } else { - account.setTitle(username + "@" + domain); - } - - if (defaultAccountID == i) { - account.setSummary(R.string.default_account_flag); - } - - account.setOnPreferenceClickListener( - new OnPreferenceClickListener() { - public boolean onPreferenceClick(Preference preference) { - LinphoneActivity.instance().displayAccountSettings(accountId); - return false; - } - }); - updateAccountLed(account, username, domain, mPrefs.isAccountEnabled(i)); - accounts.addPreference(account); - } - } - } - - private void updateAccountLed( - final LedPreference me, final String username, final String domain, boolean enabled) { - if (!enabled) { - me.setLed(R.drawable.led_disconnected); - return; - } - - if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) { - for (ProxyConfig lpc : LinphoneManager.getLc().getProxyConfigList()) { - Address addr = lpc.getIdentityAddress(); - if (addr.getUsername().equals(username) && addr.getDomain().equals(domain)) { - if (lpc.getState() == RegistrationState.Ok) { - me.setLed(R.drawable.led_connected); - } else if (lpc.getState() == RegistrationState.Failed) { - me.setLed(R.drawable.led_error); - } else if (lpc.getState() == RegistrationState.Progress) { - me.setLed(R.drawable.led_inprogress); - mHandler.postDelayed( - new Runnable() { - @Override - public void run() { - updateAccountLed(me, username, domain, true); - } - }, - 500); - } else { - me.setLed(R.drawable.led_disconnected); + protected void setListeners() { + mTunnel.setListener( + new SettingListenerBase() { + @Override + public void onClicked() { + LinphoneActivity.instance() + .displaySubSettings(new TunnelSettingsFragment()); } - break; - } - } - } - } + }); - private void initMediaEncryptionPreference(ListPreference pref) { - List entries = new ArrayList<>(); - List values = new ArrayList<>(); - entries.add(getString(R.string.pref_none)); - values.add(getString(R.string.pref_media_encryption_key_none)); - - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc == null - || getResources().getBoolean(R.bool.disable_all_security_features_for_markets)) { - setListPreferenceValues(pref, entries, values); - return; - } - - boolean hasZrtp = lc.mediaEncryptionSupported(MediaEncryption.ZRTP); - boolean hasSrtp = lc.mediaEncryptionSupported(MediaEncryption.SRTP); - boolean hasDtls = lc.mediaEncryptionSupported(MediaEncryption.DTLS); - - if (!hasSrtp && !hasZrtp && !hasDtls) { - pref.setEnabled(false); - } else { - if (hasSrtp) { - entries.add(getString(R.string.media_encryption_srtp)); - values.add(getString(R.string.pref_media_encryption_key_srtp)); - } - if (hasZrtp) { - entries.add(getString(R.string.media_encryption_zrtp)); - values.add(getString(R.string.pref_media_encryption_key_zrtp)); - } - if (hasDtls) { - entries.add(getString(R.string.media_encryption_dtls)); - values.add(getString(R.string.pref_media_encryption_key_dtls)); - } - setListPreferenceValues(pref, entries, values); - } - - MediaEncryption value = mPrefs.getMediaEncryption(); - pref.setSummary(value.toString()); - - String key = getString(R.string.pref_media_encryption_key_none); - if (value.toString().equals(getString(R.string.media_encryption_srtp))) - key = getString(R.string.pref_media_encryption_key_srtp); - else if (value.toString().equals(getString(R.string.media_encryption_zrtp))) - key = getString(R.string.pref_media_encryption_key_zrtp); - else if (value.toString().equals(getString(R.string.media_encryption_dtls))) - key = getString(R.string.pref_media_encryption_key_dtls); - pref.setValue(key); - } - - private void initializePreferredVideoSizePreferences(ListPreference pref) { - List entries = new ArrayList<>(); - List values = new ArrayList<>(); - for (VideoDefinition vd : Factory.instance().getSupportedVideoDefinitions()) { - entries.add(vd.getName()); - values.add(vd.getName()); - } - - setListPreferenceValues(pref, entries, values); - - String value = mPrefs.getPreferredVideoSize(); - pref.setSummary(value); - pref.setValue(value); - } - - private void initializePreferredVideoFpsPreferences(ListPreference pref) { - List entries = new ArrayList<>(); - List 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); - } - setListPreferenceValues(pref, entries, values); - String value = Integer.toString(mPrefs.getPreferredVideoFps()); - if (value.equals("0")) { - value = getString(R.string.pref_none); - } - pref.setSummary(value); - pref.setValue(value); - } - - private void initAutoDownloadPolicyPreference(ListPreference pref) { - int max_size = mPrefs.getAutoDownloadFileMaxSize(); - if (max_size == -1) { - pref.setSummary(getString(R.string.pref_auto_download_disabled)); - pref.setValue(getString(R.string.pref_auto_download_policy_disabled_key)); - } else if (max_size == 0) { - pref.setSummary(getString(R.string.pref_auto_download_always)); - pref.setValue(getString(R.string.pref_auto_download_policy_always_key)); - } else { - pref.setSummary(getString(R.string.pref_auto_download_under_size)); - pref.setValue(getString(R.string.pref_auto_download_policy_size_key)); - } - } - - private void initAudioSettings() { - PreferenceCategory codecs = - (PreferenceCategory) findPreference(getString(R.string.pref_codecs_key)); - codecs.removeAll(); - - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - if (lc != null) { - for (final PayloadType pt : lc.getAudioPayloadTypes()) { - CheckBoxPreference codec = new CheckBoxPreference(getActivity()); - codec.setTitle(pt.getMimeType()); - /* Special case */ - if (pt.getMimeType().equals("mpeg4-generic")) { - codec.setTitle("AAC-ELD"); - } - - codec.setSummary(pt.getClockRate() + " Hz"); - codec.setDefaultValue(pt.enabled()); - - codec.setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean enable = (Boolean) newValue; - pt.enable(enable); - return true; - } - }); - - codecs.addPreference(codec); - } - } - - CheckBoxPreference echoCancellation = - (CheckBoxPreference) findPreference(getString(R.string.pref_echo_cancellation_key)); - echoCancellation.setChecked(mPrefs.echoCancellationEnabled()); - - if (mPrefs.echoCancellationEnabled()) { - Preference echoCalibration = - findPreference(getString(R.string.pref_echo_canceller_calibration_key)); - echoCalibration.setSummary( - String.format( - getString(R.string.ec_calibrated), - String.valueOf(mPrefs.getEchoCalibration()))); - } - - CheckBoxPreference adaptiveRateControl = - (CheckBoxPreference) - findPreference(getString(R.string.pref_adaptive_rate_control_key)); - adaptiveRateControl.setChecked(mPrefs.adaptiveRateControlEnabled()); - - ListPreference bitrateLimit = - (ListPreference) findPreference(getString(R.string.pref_codec_bitrate_limit_key)); - bitrateLimit.setSummary(String.valueOf(mPrefs.getCodecBitrateLimit())); - bitrateLimit.setValue(String.valueOf(mPrefs.getCodecBitrateLimit())); - - EditTextPreference micGain = - (EditTextPreference) findPreference(getString(R.string.pref_mic_gain_db_key)); - micGain.setText(String.valueOf(mPrefs.getMicGainDb())); - micGain.setSummary(String.valueOf(mPrefs.getMicGainDb())); - EditTextPreference playbackGain = - (EditTextPreference) findPreference(getString(R.string.pref_playback_gain_db_key)); - playbackGain.setText(String.valueOf(mPrefs.getPlaybackGainDb())); - playbackGain.setSummary(String.valueOf(mPrefs.getPlaybackGainDb())); - } - - private void setAudioPreferencesListener() { - findPreference(getString(R.string.pref_echo_cancellation_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean enabled = (Boolean) newValue; - mPrefs.setEchoCancellation(enabled); - return true; - } - }); - - findPreference(getString(R.string.pref_adaptive_rate_control_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean enabled = (Boolean) newValue; - mPrefs.enableAdaptiveRateControl(enabled); - return true; - } - }); - - findPreference(getString(R.string.pref_codec_bitrate_limit_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setCodecBitrateLimit(Integer.parseInt(newValue.toString())); - Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - int bitrate = Integer.parseInt(newValue.toString()); - - for (final PayloadType pt : lc.getAudioPayloadTypes()) { - if (pt.isVbr()) { - pt.setNormalBitrate(bitrate); - } - } - - preference.setSummary( - String.valueOf(mPrefs.getCodecBitrateLimit())); - return true; - } - }); - - findPreference(getString(R.string.pref_echo_canceller_calibration_key)) - .setOnPreferenceClickListener( - new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - synchronized (SettingsFragment.this) { - preference.setSummary(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(); - } - } - return true; - } - }); - - findPreference(getString(R.string.pref_echo_tester_key)) - .setOnPreferenceClickListener( - new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - synchronized (SettingsFragment.this) { - 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(); - } - } - return true; - } - }); - - findPreference(getString(R.string.pref_mic_gain_db_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - float newVal = Float.valueOf((String) o); - mPrefs.setMicGainDb(newVal); - preference.setSummary(String.valueOf(newVal)); - return true; - } - }); - - findPreference(getString(R.string.pref_playback_gain_db_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - float newVal = Float.valueOf((String) o); - mPrefs.setPlaybackGainDb(newVal); - preference.setSummary(String.valueOf(newVal)); - return true; - } - }); - } - - public void startEchoTester() { - Preference preference = findPreference(getString(R.string.pref_echo_tester_key)); - if (LinphoneManager.getInstance().startEchoTester() > 0) { - preference.setSummary("Is running"); - } - } - - private void stopEchoTester() { - Preference preference = findPreference(getString(R.string.pref_echo_tester_key)); - if (LinphoneManager.getInstance().stopEchoTester() > 0) { - preference.setSummary("Is stopped"); - } - } - - public void startEchoCancellerCalibration() { - if (LinphoneManager.getInstance().getEchoTesterStatus()) stopEchoTester(); - LinphoneManager.getLc().addListener(mListener); - LinphoneManager.getInstance().startEcCalibration(); - } - - public void echoCalibrationFail() { - Preference echoCancellerCalibration = - findPreference(getString(R.string.pref_echo_canceller_calibration_key)); - echoCancellerCalibration.setSummary(R.string.failed); - } - - private void initOpenH264AlertDialog( - final OpenH264DownloadHelper mCodecDownloader, final CheckBoxPreference codec) { - mCodecDownloader.setOpenH264HelperListener( - LinphoneManager.getInstance().getOpenH264HelperListener()); - mCodecDownloader.setUserData(0, LinphoneManager.getInstance().getContext()); - mCodecDownloader.setUserData(1, codec); - - AlertDialog.Builder builder = - new AlertDialog.Builder(LinphoneManager.getInstance().getContext()); - builder.setCancelable(false); - builder.setMessage("Do you agree to download " + mCodecDownloader.getLicenseMessage()) - .setPositiveButton( - "Yes", - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) - mCodecDownloader.downloadCodec(); - } - }); - builder.setNegativeButton( - "No", - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_NEGATIVE) { - // Disable H264 - codec.setChecked(false); - } - } - }) - .show(); - } - - private void initVideoSettings() { - initializePreferredVideoSizePreferences( - (ListPreference) findPreference(getString(R.string.pref_preferred_video_size_key))); - initializePreferredVideoFpsPreferences( - (ListPreference) findPreference(getString(R.string.pref_preferred_video_fps_key))); - EditTextPreference bandwidth = - (EditTextPreference) findPreference(getString(R.string.pref_bandwidth_limit_key)); - bandwidth.setText(Integer.toString(mPrefs.getBandwidthLimit())); - bandwidth.setSummary(bandwidth.getText()); - updateVideoPreferencesAccordingToPreset(); - - ListPreference videoPresetPref = - (ListPreference) findPreference(getString(R.string.pref_video_preset_key)); - videoPresetPref.setSummary(mPrefs.getVideoPreset()); - videoPresetPref.setValue(mPrefs.getVideoPreset()); - - PreferenceCategory codecs = - (PreferenceCategory) findPreference(getString(R.string.pref_video_codecs_key)); - codecs.removeAll(); - - final Core lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); - - final OpenH264DownloadHelper mCodecDownloader = - LinphoneManager.getInstance().getOpenH264DownloadHelper(); - - boolean h264IsHere = false; - for (final PayloadType pt : lc.getVideoPayloadTypes()) { - final CheckBoxPreference codec = new CheckBoxPreference(getActivity()); - codec.setTitle(pt.getMimeType()); - - if (!pt.getMimeType().equals("VP8")) { - if (getResources().getBoolean(R.bool.disable_all_patented_codecs_for_markets)) { - continue; - } else { - if (!Version.hasFastCpuWithAsmOptim() && pt.getMimeType().equals("H264")) { - // Android without neon doesn't support H264 - Log.w("CPU does not have asm optimisations available, disabling H264"); - continue; + mAudio.setListener( + new SettingListenerBase() { + @Override + public void onClicked() { + LinphoneActivity.instance().displaySubSettings(new AudioSettingsFragment()); } + }); + + mVideo.setListener( + new SettingListenerBase() { + @Override + public void onClicked() { + LinphoneActivity.instance().displaySubSettings(new VideoSettingsFragment()); + } + }); + + mCall.setListener( + new SettingListenerBase() { + @Override + public void onClicked() { + LinphoneActivity.instance().displaySubSettings(new CallSettingsFragment()); + } + }); + + mChat.setListener( + new SettingListenerBase() { + @Override + public void onClicked() { + LinphoneActivity.instance().displaySubSettings(new ChatSettingsFragment()); + } + }); + + mNetwork.setListener( + new SettingListenerBase() { + @Override + public void onClicked() { + LinphoneActivity.instance() + .displaySubSettings(new NetworkSettingsFragment()); + } + }); + + mAdvanced.setListener( + new SettingListenerBase() { + @Override + public void onClicked() { + LinphoneActivity.instance() + .displaySubSettings(new AdvancedSettingsFragment()); + } + }); + } + + protected void updateValues() { + Core core = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + if (core != null) { + mTunnel.setVisibility(core.tunnelAvailable() ? View.VISIBLE : View.GONE); + initAccounts(core); + } + } + + private void initAccounts(Core core) { + mAccounts.removeAllViews(); + ProxyConfig[] proxyConfigs = core.getProxyConfigList(); + + if (proxyConfigs == null || proxyConfigs.length == 0) { + mAccountsHeader.setVisibility(View.GONE); + } else { + mAccountsHeader.setVisibility(View.VISIBLE); + int i = 0; + for (ProxyConfig proxyConfig : proxyConfigs) { + final LedSetting account = new LedSetting(getActivity()); + account.setTitle( + LinphoneUtils.getDisplayableAddress(proxyConfig.getIdentityAddress())); + + if (proxyConfig.equals(core.getDefaultProxyConfig())) { + account.setSubtitle(getString(R.string.default_account_flag)); } - } else if (pt.getMimeType().equals("H264")) { - h264IsHere = true; - if (OpenH264DownloadHelper.isOpenH264DownloadEnabled() - && mCodecDownloader.isCodecFound()) { - codec.setSummary(mCodecDownloader.getLicenseMessage()); - codec.setTitle("OpenH264"); + + switch (proxyConfig.getState()) { + case Ok: + account.setColor(LedSetting.Color.GREEN); + break; + case Failed: + account.setColor(LedSetting.Color.RED); + break; + case Progress: + account.setColor(LedSetting.Color.ORANGE); + break; + case None: + case Cleared: + account.setColor(LedSetting.Color.GRAY); + break; } + + final int accountIndex = i; + account.setListener( + new SettingListenerBase() { + @Override + public void onClicked() { + LinphoneActivity.instance().displayAccountSettings(accountIndex); + } + }); + + mAccounts.addView(account); + i += 1; } - - codec.setDefaultValue(pt.enabled()); - - codec.setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean enable = (Boolean) newValue; - if (OpenH264DownloadHelper.isOpenH264DownloadEnabled()) { - if (enable - && Version.getCpuAbis().contains("armeabi-v7a") - && !Version.getCpuAbis().contains("x86") - && pt.getMimeType().equals("H264") - && !mCodecDownloader.isCodecFound()) { - mCodecDownloader.setOpenH264HelperListener( - LinphoneManager.getInstance() - .getOpenH264HelperListener()); - mCodecDownloader.setUserData( - 0, LinphoneManager.getInstance().getContext()); - mCodecDownloader.setUserData(1, codec); - - AlertDialog.Builder builder = - new AlertDialog.Builder( - LinphoneManager.getInstance().getContext()); - builder.setCancelable(false); - builder.setMessage( - "Do you agree to download " - + mCodecDownloader.getLicenseMessage()) - .setPositiveButton( - "Yes", - new DialogInterface.OnClickListener() { - @Override - public void onClick( - DialogInterface dialog, int which) { - if (which - == DialogInterface - .BUTTON_POSITIVE) - mCodecDownloader.downloadCodec(); - } - }); - builder.setNegativeButton("No", null).show(); - } - } - pt.enable(enable); - return true; - } - }); - - codecs.addPreference(codec); } - // Adding OpenH264 button on device < 5.1 - if (OpenH264DownloadHelper.isOpenH264DownloadEnabled() && !h264IsHere) { - final CheckBoxPreference codec = new CheckBoxPreference(getActivity()); - codec.setTitle("OpenH264"); - codec.setSummary(mCodecDownloader.getLicenseMessage()); - // codec.setEnabled(false); - codec.setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - boolean enable = (Boolean) newValue; - if (OpenH264DownloadHelper.isOpenH264DownloadEnabled()) { - if (enable - && Version.getCpuAbis().contains("armeabi-v7a") - && !Version.getCpuAbis().contains("x86") - && !mCodecDownloader.isCodecFound()) { - initOpenH264AlertDialog(mCodecDownloader, codec); - } - } - return true; - } - }); - codecs.addPreference(codec); - } - ((CheckBoxPreference) findPreference(getString(R.string.pref_video_enable_key))) - .setChecked(mPrefs.isVideoEnabled()); - ((CheckBoxPreference) findPreference(getString(R.string.pref_video_use_front_camera_key))) - .setChecked(mPrefs.useFrontCam()); - ((CheckBoxPreference) - findPreference(getString(R.string.pref_video_initiate_call_with_video_key))) - .setChecked(mPrefs.shouldInitiateVideoCall()); - ((CheckBoxPreference) - findPreference( - getString(R.string.pref_video_automatically_accept_video_key))) - .setChecked(mPrefs.shouldAutomaticallyAcceptVideoRequests()); - ((CheckBoxPreference) findPreference(getString(R.string.pref_overlay_key))) - .setChecked(mPrefs.isOverlayEnabled()); - } - - private void updateVideoPreferencesAccordingToPreset() { - if (mPrefs.getVideoPreset().equals("custom")) { - findPreference(getString(R.string.pref_preferred_video_fps_key)).setEnabled(true); - findPreference(getString(R.string.pref_bandwidth_limit_key)).setEnabled(true); - } else { - findPreference(getString(R.string.pref_preferred_video_fps_key)).setEnabled(false); - findPreference(getString(R.string.pref_bandwidth_limit_key)).setEnabled(false); - } - findPreference(getString(R.string.pref_video_preset_key)) - .setSummary(mPrefs.getVideoPreset()); - int fps = mPrefs.getPreferredVideoFps(); - String fpsStr = Integer.toString(fps); - if (fpsStr.equals("0")) { - fpsStr = getString(R.string.pref_none); - } - findPreference(getString(R.string.pref_preferred_video_fps_key)).setSummary(fpsStr); - findPreference(getString(R.string.pref_bandwidth_limit_key)) - .setSummary(Integer.toString(mPrefs.getBandwidthLimit())); - } - - private void setVideoPreferencesListener() { - findPreference(getString(R.string.pref_video_enable_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean enable = (Boolean) newValue; - mPrefs.enableVideo(enable); - if (!enable) { - mPrefs.setInitiateVideoCall(false); - mPrefs.setAutomaticallyAcceptVideoRequests(false); - ((CheckBoxPreference) - findPreference( - getString( - R.string - .pref_video_initiate_call_with_video_key))) - .setChecked(mPrefs.shouldInitiateVideoCall()); - ((CheckBoxPreference) - findPreference( - getString( - R.string - .pref_video_automatically_accept_video_key))) - .setChecked( - mPrefs - .shouldAutomaticallyAcceptVideoRequests()); - } - return true; - } - }); - - findPreference(getString(R.string.pref_video_use_front_camera_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean enable = (Boolean) newValue; - mPrefs.setFrontCamAsDefault(enable); - return true; - } - }); - - findPreference(getString(R.string.pref_video_initiate_call_with_video_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean enable = (Boolean) newValue; - mPrefs.setInitiateVideoCall(enable); - return true; - } - }); - - findPreference(getString(R.string.pref_video_automatically_accept_video_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean enable = (Boolean) newValue; - mPrefs.setAutomaticallyAcceptVideoRequests(enable); - return true; - } - }); - - findPreference(getString(R.string.pref_video_preset_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setVideoPreset(newValue.toString()); - preference.setSummary(mPrefs.getVideoPreset()); - updateVideoPreferencesAccordingToPreset(); - return true; - } - }); - findPreference(getString(R.string.pref_preferred_video_size_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setPreferredVideoSize(newValue.toString()); - preference.setSummary(mPrefs.getPreferredVideoSize()); - updateVideoPreferencesAccordingToPreset(); - return true; - } - }); - - findPreference(getString(R.string.pref_preferred_video_fps_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setPreferredVideoFps(Integer.parseInt(newValue.toString())); - updateVideoPreferencesAccordingToPreset(); - return true; - } - }); - - findPreference(getString(R.string.pref_bandwidth_limit_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setBandwidthLimit(Integer.parseInt(newValue.toString())); - preference.setSummary(newValue.toString()); - return true; - } - }); - - findPreference(getString(R.string.pref_overlay_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean enable = (Boolean) newValue; - if (enable) { - if (LinphoneActivity.instance() - .checkAndRequestOverlayPermission()) { - mPrefs.enableOverlay(true); - } - } else { - mPrefs.enableOverlay(false); - } - return true; - } - }); - } - - private void initCallSettings() { - CheckBoxPreference deviceRingtone = - (CheckBoxPreference) findPreference(getString(R.string.pref_device_ringtone_key)); - CheckBoxPreference incomingCallVibration = - (CheckBoxPreference) - findPreference(getString(R.string.pref_incoming_call_vibration_key)); - CheckBoxPreference autoAnswer = - (CheckBoxPreference) findPreference(getString(R.string.pref_auto_answer_key)); - EditTextPreference autoAnswerTime = - (EditTextPreference) findPreference(getString(R.string.pref_auto_answer_time_key)); - CheckBoxPreference rfc2833 = - (CheckBoxPreference) findPreference(getString(R.string.pref_rfc2833_dtmf_key)); - CheckBoxPreference sipInfo = - (CheckBoxPreference) findPreference(getString(R.string.pref_sipinfo_dtmf_key)); - CheckBoxPreference dialerCall = - (CheckBoxPreference) findPreference(getString(R.string.pref_dialer_call_key)); - EditTextPreference incTimeout = - (EditTextPreference) - findPreference(getString(R.string.pref_incoming_call_timeout_key)); - CheckBoxPreference earlyMedia = - (CheckBoxPreference) - findPreference(getString(R.string.pref_accept_early_media_key)); - - rfc2833.setChecked(mPrefs.useRfc2833Dtmfs()); - sipInfo.setChecked(mPrefs.useSipInfoDtmfs()); - deviceRingtone.setChecked(mPrefs.isDeviceRingtoneEnabled()); - incomingCallVibration.setChecked(mPrefs.isIncomingCallVibrationEnabled()); - incTimeout.setText(String.valueOf(mPrefs.getIncTimeout())); - incTimeout.setSummary(String.valueOf(mPrefs.getIncTimeout())); - autoAnswer.setChecked(mPrefs.isAutoAnswerEnabled()); - autoAnswerTime.setText(String.valueOf(mPrefs.getAutoAnswerTime())); - autoAnswerTime.setSummary(String.valueOf(mPrefs.getAutoAnswerTime())); - earlyMedia.setChecked(mPrefs.acceptIncomingEarlyMedia()); - - if (mPrefs.isAutoAnswerEnabled()) { - autoAnswerTime.setEnabled(true); - } else { - autoAnswerTime.setEnabled(false); - } - - setPreferenceDefaultValueAndSummary(R.string.pref_voice_mail_key, mPrefs.getVoiceMailUri()); - dialerCall.setChecked(mPrefs.getNativeDialerCall()); - } - - private void setCallPreferencesListener() { - findPreference(getString(R.string.pref_device_ringtone_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean use = (Boolean) newValue; - if (use) { - int readExternalStorage = - getActivity() - .getPackageManager() - .checkPermission( - Manifest.permission - .READ_EXTERNAL_STORAGE, - getActivity().getPackageName()); - if (readExternalStorage == PackageManager.PERMISSION_GRANTED) { - mPrefs.enableDeviceRingtone(true); - LinphoneManager.getInstance().enableDeviceRingtone(true); - } else { - LinphoneActivity.instance() - .checkAndRequestReadExternalStoragePermissionForDeviceRingtone(); - } - } else { - mPrefs.enableDeviceRingtone(false); - LinphoneManager.getInstance().enableDeviceRingtone(false); - } - - return true; - } - }); - - findPreference(getString(R.string.pref_incoming_call_vibration_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean use = (Boolean) newValue; - mPrefs.enableIncomingCallVibration(use); - return true; - } - }); - - findPreference(getString(R.string.pref_media_encryption_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String value = newValue.toString(); - MediaEncryption menc = MediaEncryption.None; - if (value.equals( - getString(R.string.pref_media_encryption_key_srtp))) - menc = MediaEncryption.SRTP; - else if (value.equals( - getString(R.string.pref_media_encryption_key_zrtp))) - menc = MediaEncryption.ZRTP; - else if (value.equals( - getString(R.string.pref_media_encryption_key_dtls))) - menc = MediaEncryption.DTLS; - mPrefs.setMediaEncryption(menc); - - preference.setSummary(mPrefs.getMediaEncryption().toString()); - return true; - } - }); - - initMediaEncryptionPreference( - (ListPreference) findPreference(getString(R.string.pref_media_encryption_key))); - - findPreference(getString(R.string.pref_auto_answer_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean use = (Boolean) newValue; - mPrefs.enableAutoAnswer(use); - if (use) { - findPreference(getString(R.string.pref_auto_answer_time_key)) - .setEnabled(true); - } else { - findPreference(getString(R.string.pref_auto_answer_time_key)) - .setEnabled(false); - } - return true; - } - }); - - findPreference(getString(R.string.pref_rfc2833_dtmf_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean use = (Boolean) newValue; - mPrefs.sendDtmfsAsRfc2833(use); - return true; - } - }); - - findPreference(getString(R.string.pref_voice_mail_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - EditTextPreference voiceMail = - (EditTextPreference) - findPreference( - getString(R.string.pref_voice_mail_key)); - voiceMail.setSummary(newValue.toString()); - voiceMail.setText(newValue.toString()); - mPrefs.setVoiceMailUri(newValue.toString()); - return true; - } - }); - - findPreference(getString(R.string.pref_sipinfo_dtmf_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean use = (Boolean) newValue; - mPrefs.sendDTMFsAsSipInfo(use); - return true; - } - }); - - findPreference(getString(R.string.pref_dialer_call_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean use = (Boolean) newValue; - mPrefs.setNativeDialerCall(use); - return true; - } - }); - - findPreference(getString(R.string.pref_incoming_call_timeout_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String value = (String) newValue; - try { - mPrefs.setIncTimeout(Integer.valueOf(value)); - preference.setSummary(value); - } catch (NumberFormatException nfe) { - Log.e("Value is not an Integer ! " + value); - return false; - } - return true; - } - }); - - findPreference(getString(R.string.pref_auto_answer_time_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String value = (String) newValue; - mPrefs.setAutoAnswerTime(Integer.valueOf(value)); - preference.setSummary(value); - return true; - } - }); - - findPreference(getString(R.string.pref_accept_early_media_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean accept = (Boolean) newValue; - mPrefs.setAcceptIncomingEarlyMedia(accept); - return true; - } - }); - } - - private void initChatSettings() { - setPreferenceDefaultValueAndSummary( - R.string.pref_image_sharing_server_key, mPrefs.getSharingPictureServerUrl()); - initAutoDownloadPolicyPreference( - (ListPreference) findPreference(getString(R.string.pref_auto_download_policy_key))); - int max_size = mPrefs.getAutoDownloadFileMaxSize(); - setPreferenceDefaultValueAndSummary( - R.string.pref_auto_download_max_size_key, String.valueOf(max_size)); - findPreference(getString(R.string.pref_auto_download_max_size_key)) - .setEnabled(max_size > 0); - if (Version.sdkStrictlyBelow(Version.API26_O_80)) { - findPreference(getString(R.string.pref_android_app_notif_settings_key)) - .setLayoutResource(R.layout.hidden); - } - } - - private void setChatPreferencesListener() { - findPreference(getString(R.string.pref_image_sharing_server_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String value = (String) newValue; - mPrefs.setSharingPictureServerUrl(value); - preference.setSummary(value); - return true; - } - }); - - findPreference(getString(R.string.pref_android_app_notif_settings_key)) - .setOnPreferenceClickListener( - new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - synchronized (SettingsFragment.this) { - if (Build.VERSION.SDK_INT >= Version.API26_O_80) { - Context context = SettingsFragment.this.getActivity(); - 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); - context.startActivity(i); - } - return true; - } - } - }); - - findPreference(getString(R.string.pref_auto_download_policy_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String value = (String) newValue; - int size = Integer.valueOf(value); - mPrefs.setAutoDownloadFileMaxSize(size); - initAutoDownloadPolicyPreference( - (ListPreference) - findPreference( - getString( - R.string - .pref_auto_download_policy_key))); - setPreferenceDefaultValueAndSummary( - R.string.pref_auto_download_max_size_key, - String.valueOf(size)); - findPreference(getString(R.string.pref_auto_download_max_size_key)) - .setEnabled(size > 0); - return true; - } - }); - - findPreference(getString(R.string.pref_auto_download_max_size_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String value = (String) newValue; - int size = Integer.valueOf(value); - mPrefs.setAutoDownloadFileMaxSize(size); - preference.setSummary(String.valueOf(size)); - preference.setEnabled(size > 0); - initAutoDownloadPolicyPreference( - (ListPreference) - findPreference( - getString( - R.string - .pref_auto_download_policy_key))); - return true; - } - }); - } - - private void initNetworkSettings() { - ((CheckBoxPreference) findPreference(getString(R.string.pref_wifi_only_key))) - .setChecked(mPrefs.isWifiOnlyEnabled()); - - // Disable UPnP if ICE si enabled, or disable ICE if UPnP is enabled - CheckBoxPreference ice = - (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key)); - CheckBoxPreference turn = - (CheckBoxPreference) findPreference(getString(R.string.pref_turn_enable_key)); - ice.setChecked(mPrefs.isIceEnabled()); - turn.setEnabled(mPrefs.getStunServer() != null); - turn.setChecked(mPrefs.isTurnEnabled()); - - EditTextPreference turnUsername = - (EditTextPreference) findPreference(getString(R.string.pref_turn_username_key)); - EditTextPreference turnPassword = - (EditTextPreference) findPreference(getString(R.string.pref_turn_passwd_key)); - turnUsername.setEnabled(mPrefs.isTurnEnabled()); - turnUsername.setSummary(mPrefs.getTurnUsername()); - turnUsername.setText(mPrefs.getTurnUsername()); - turnPassword.setEnabled(mPrefs.isTurnEnabled()); - - CheckBoxPreference randomPort = - (CheckBoxPreference) - findPreference(getString(R.string.pref_transport_use_random_ports_key)); - randomPort.setChecked(mPrefs.isUsingRandomPort()); - - // Disable sip port choice if port is random - EditTextPreference sipPort = - (EditTextPreference) findPreference(getString(R.string.pref_sip_port_key)); - sipPort.setEnabled(!randomPort.isChecked()); - sipPort.setSummary(mPrefs.getSipPort()); - sipPort.setText(mPrefs.getSipPort()); - - EditTextPreference stun = - (EditTextPreference) findPreference(getString(R.string.pref_stun_server_key)); - stun.setSummary(mPrefs.getStunServer()); - stun.setText(mPrefs.getStunServer()); - - ((CheckBoxPreference) findPreference(getString(R.string.pref_push_notification_key))) - .setChecked(mPrefs.isPushNotificationEnabled()); - if (!PushNotificationUtils.isAvailable(getActivity())) { - findPreference(getString(R.string.pref_push_notification_key)) - .setLayoutResource(R.layout.hidden); - } - ((CheckBoxPreference) findPreference(getString(R.string.pref_ipv6_key))) - .setChecked(mPrefs.isUsingIpv6()); - } - - private void setNetworkPreferencesListener() { - findPreference(getString(R.string.pref_wifi_only_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setWifiOnlyEnabled((Boolean) newValue); - return true; - } - }); - - findPreference(getString(R.string.pref_stun_server_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setStunServer(newValue.toString()); - preference.setSummary(newValue.toString()); - - CheckBoxPreference turn = - (CheckBoxPreference) - findPreference( - getString(R.string.pref_turn_enable_key)); - turn.setEnabled(mPrefs.getStunServer() != null); - return true; - } - }); - - findPreference(getString(R.string.pref_ice_enable_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setIceEnabled((Boolean) newValue); - return true; - } - }); - - findPreference(getString(R.string.pref_turn_enable_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setTurnEnabled((Boolean) newValue); - EditTextPreference turnUsername = - (EditTextPreference) - findPreference( - getString(R.string.pref_turn_username_key)); - EditTextPreference turnPassword = - (EditTextPreference) - findPreference( - getString(R.string.pref_turn_passwd_key)); - turnUsername.setEnabled(mPrefs.isTurnEnabled()); - turnPassword.setEnabled(mPrefs.isTurnEnabled()); - return true; - } - }); - - findPreference(getString(R.string.pref_turn_username_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setTurnUsername((String) newValue); - preference.setSummary(mPrefs.getTurnUsername()); - return true; - } - }); - - findPreference(getString(R.string.pref_turn_passwd_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setTurnPassword((String) newValue); - return true; - } - }); - - findPreference(getString(R.string.pref_transport_use_random_ports_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean randomPort = (Boolean) newValue; - mPrefs.useRandomPort((Boolean) newValue); - findPreference(getString(R.string.pref_sip_port_key)) - .setEnabled(!randomPort); - return true; - } - }); - - findPreference(getString(R.string.pref_sip_port_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - int port = -1; - try { - port = Integer.parseInt(newValue.toString()); - } catch (NumberFormatException nfe) { - Log.e(nfe); - } - - mPrefs.setSipPort(port); - preference.setSummary(newValue.toString()); - return true; - } - }); - - findPreference(getString(R.string.pref_push_notification_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.setPushNotificationEnabled((Boolean) newValue); - return true; - } - }); - - findPreference(getString(R.string.pref_device_power_saver_settings_key)) - .setOnPreferenceClickListener( - new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - LinphonePreferences.instance().powerSaverDialogPrompted(true); - Intent intent = - DeviceUtils.getDevicePowerManagerIntent( - LinphoneActivity.instance()); - startActivity(intent); - return true; - } - }); - - findPreference(getString(R.string.pref_ipv6_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - mPrefs.useIpv6((Boolean) newValue); - return true; - } - }); - } - - private void initAdvancedSettings() { - ((CheckBoxPreference) findPreference(getString(R.string.pref_dark_mode_key))) - .setChecked(mPrefs.isDarkModeEnabled()); - ((CheckBoxPreference) findPreference(getString(R.string.pref_friendlist_subscribe_key))) - .setChecked(mPrefs.isFriendlistsubscriptionEnabled()); - ((CheckBoxPreference) findPreference(getString(R.string.pref_debug_key))) - .setChecked(mPrefs.isDebugEnabled()); - ((CheckBoxPreference) findPreference(getString(R.string.pref_java_debug_key))) - .setChecked(mPrefs.useJavaLogger()); - ((CheckBoxPreference) findPreference(getString(R.string.pref_background_mode_key))) - .setChecked(mPrefs.isBackgroundModeEnabled()); - ((CheckBoxPreference) findPreference(getString(R.string.pref_service_notification_key))) - .setChecked(mPrefs.getServiceNotificationVisibility()); - ((CheckBoxPreference) findPreference(getString(R.string.pref_autostart_key))) - .setChecked(mPrefs.isAutoStartEnabled()); - setPreferenceDefaultValueAndSummary( - R.string.pref_remote_provisioning_key, mPrefs.getRemoteProvisioningUrl()); - setPreferenceDefaultValueAndSummary( - R.string.pref_display_name_key, mPrefs.getDefaultDisplayName()); - setPreferenceDefaultValueAndSummary( - R.string.pref_user_name_key, mPrefs.getDefaultUsername()); - } - - private void setAdvancedPreferencesListener() { - findPreference(getString(R.string.pref_dark_mode_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean value = (Boolean) newValue; - mPrefs.enableDarkMode(value); - LinphoneActivity.instance().recreate(); - return true; - } - }); - - findPreference(getString(R.string.pref_friendlist_subscribe_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean value = (Boolean) newValue; - mPrefs.enabledFriendlistSubscription(value); - LinphoneManager.getInstance().subscribeFriendList(value); - return true; - } - }); - - findPreference(getString(R.string.pref_debug_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean value = (Boolean) newValue; - mPrefs.setDebugEnabled(value); - return true; - } - }); - - findPreference(getString(R.string.pref_java_debug_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean value = (Boolean) newValue; - mPrefs.setJavaLogger(value); - return true; - } - }); - - findPreference(getString(R.string.pref_background_mode_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean value = (Boolean) newValue; - mPrefs.setBackgroundModeEnabled(value); - return true; - } - }); - - findPreference(getString(R.string.pref_service_notification_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean value = (Boolean) newValue; - mPrefs.setServiceNotificationVisibility(value); - if (value) { - LinphoneService.instance() - .getNotificationManager() - .startForeground(); - } else { - LinphoneService.instance() - .getNotificationManager() - .stopForeground(); - } - return true; - } - }); - - findPreference(getString(R.string.pref_autostart_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - boolean value = (Boolean) newValue; - mPrefs.setAutoStart(value); - return true; - } - }); - - findPreference(getString(R.string.pref_remote_provisioning_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String value = (String) newValue; - mPrefs.setRemoteProvisioningUrl(value); - preference.setSummary(value); - return true; - } - }); - - findPreference(getString(R.string.pref_android_app_settings_key)) - .setOnPreferenceClickListener( - new OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - synchronized (SettingsFragment.this) { - 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); - LinphoneActivity.instance() - .startActivityForResult( - i, - LinphoneActivity.ANDROID_APP_SETTINGS_ACTIVITY); - } - return true; - } - }); - - findPreference(getString(R.string.pref_display_name_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String value = (String) newValue; - mPrefs.setDefaultDisplayName(value); - preference.setSummary(value); - return true; - } - }); - - findPreference(getString(R.string.pref_user_name_key)) - .setOnPreferenceChangeListener( - new OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange( - Preference preference, Object newValue) { - String value = (String) newValue; - if (value.equals("")) return false; - - mPrefs.setDefaultUsername(value); - preference.setSummary(value); - return true; - } - }); } } diff --git a/app/src/main/java/org/linphone/settings/TunnelSettingsFragment.java b/app/src/main/java/org/linphone/settings/TunnelSettingsFragment.java new file mode 100644 index 000000000..a64027201 --- /dev/null +++ b/app/src/main/java/org/linphone/settings/TunnelSettingsFragment.java @@ -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(); + } +} diff --git a/app/src/main/java/org/linphone/settings/VideoSettingsFragment.java b/app/src/main/java/org/linphone/settings/VideoSettingsFragment.java new file mode 100644 index 000000000..a37e2ca1a --- /dev/null +++ b/app/src/main/java/org/linphone/settings/VideoSettingsFragment.java @@ -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 entries = new ArrayList<>(); + List 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 entries = new ArrayList<>(); + List 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); + } +} diff --git a/app/src/main/java/org/linphone/settings/widget/BasicSetting.java b/app/src/main/java/org/linphone/settings/widget/BasicSetting.java new file mode 100644 index 000000000..99191a3e9 --- /dev/null +++ b/app/src/main/java/org/linphone/settings/widget/BasicSetting.java @@ -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); + } +} diff --git a/app/src/main/java/org/linphone/settings/widget/CheckBoxSetting.java b/app/src/main/java/org/linphone/settings/widget/CheckBoxSetting.java new file mode 100644 index 000000000..253a8ac41 --- /dev/null +++ b/app/src/main/java/org/linphone/settings/widget/CheckBoxSetting.java @@ -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(); + } +} diff --git a/app/src/main/java/org/linphone/settings/widget/LedSetting.java b/app/src/main/java/org/linphone/settings/widget/LedSetting.java new file mode 100644 index 000000000..182672257 --- /dev/null +++ b/app/src/main/java/org/linphone/settings/widget/LedSetting.java @@ -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; + } + } +} diff --git a/app/src/main/java/org/linphone/settings/widget/ListSetting.java b/app/src/main/java/org/linphone/settings/widget/ListSetting.java new file mode 100644 index 000000000..b0633f75b --- /dev/null +++ b/app/src/main/java/org/linphone/settings/widget/ListSetting.java @@ -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 mItems; + protected List 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 list, List valuesList) { + mItems = list; + mItemsValues = valuesList; + ArrayAdapter 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)); + } +} diff --git a/app/src/main/java/org/linphone/settings/widget/SettingListener.java b/app/src/main/java/org/linphone/settings/widget/SettingListener.java new file mode 100644 index 000000000..8e4f997f3 --- /dev/null +++ b/app/src/main/java/org/linphone/settings/widget/SettingListener.java @@ -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); +} diff --git a/app/src/main/java/org/linphone/settings/widget/SettingListenerBase.java b/app/src/main/java/org/linphone/settings/widget/SettingListenerBase.java new file mode 100644 index 000000000..a3d567d12 --- /dev/null +++ b/app/src/main/java/org/linphone/settings/widget/SettingListenerBase.java @@ -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) {} +} diff --git a/app/src/main/java/org/linphone/settings/widget/SwitchSetting.java b/app/src/main/java/org/linphone/settings/widget/SwitchSetting.java new file mode 100644 index 000000000..f788de59a --- /dev/null +++ b/app/src/main/java/org/linphone/settings/widget/SwitchSetting.java @@ -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(); + } +} diff --git a/app/src/main/java/org/linphone/settings/widget/TextSetting.java b/app/src/main/java/org/linphone/settings/widget/TextSetting.java new file mode 100644 index 000000000..94437b089 --- /dev/null +++ b/app/src/main/java/org/linphone/settings/widget/TextSetting.java @@ -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(); + } +} diff --git a/app/src/main/res/layout/contacts_list.xml b/app/src/main/res/layout/contacts_list.xml index b1f63d7af..982fc76fb 100644 --- a/app/src/main/res/layout/contacts_list.xml +++ b/app/src/main/res/layout/contacts_list.xml @@ -101,7 +101,7 @@ android:iconifiedByDefault="false" android:inputType="textPersonName" android:paddingRight="5dp" - android:queryBackground="@android:color/transparent" + android:queryBackground="@color/transparent_color" android:queryHint="@string/chat_room_creation_filter_hint"/> diff --git a/app/src/main/res/layout/settings.xml b/app/src/main/res/layout/settings.xml index 9a34ec0fa..88a171f24 100644 --- a/app/src/main/res/layout/settings.xml +++ b/app/src/main/res/layout/settings.xml @@ -1,15 +1,83 @@ - + android:layout_height="match_parent" + android:background="?attr/backgroundColor"> - + android:paddingTop="5dp" + android:paddingBottom="5dp" + android:orientation="vertical"> - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_account.xml b/app/src/main/res/layout/settings_account.xml new file mode 100644 index 000000000..28fc0bf30 --- /dev/null +++ b/app/src/main/res/layout/settings_account.xml @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_advanced.xml b/app/src/main/res/layout/settings_advanced.xml new file mode 100644 index 000000000..16622a9f4 --- /dev/null +++ b/app/src/main/res/layout/settings_advanced.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_audio.xml b/app/src/main/res/layout/settings_audio.xml new file mode 100644 index 000000000..6bfe933e4 --- /dev/null +++ b/app/src/main/res/layout/settings_audio.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_call.xml b/app/src/main/res/layout/settings_call.xml new file mode 100644 index 000000000..0f6edf9d4 --- /dev/null +++ b/app/src/main/res/layout/settings_call.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_chat.xml b/app/src/main/res/layout/settings_chat.xml new file mode 100644 index 000000000..2f5037ceb --- /dev/null +++ b/app/src/main/res/layout/settings_chat.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_network.xml b/app/src/main/res/layout/settings_network.xml new file mode 100644 index 000000000..cb4309da9 --- /dev/null +++ b/app/src/main/res/layout/settings_network.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_tunnel.xml b/app/src/main/res/layout/settings_tunnel.xml new file mode 100644 index 000000000..ce402e2ad --- /dev/null +++ b/app/src/main/res/layout/settings_tunnel.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_video.xml b/app/src/main/res/layout/settings_video.xml new file mode 100644 index 000000000..19d0ca296 --- /dev/null +++ b/app/src/main/res/layout/settings_video.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/settings_widget_basic.xml b/app/src/main/res/layout/settings_widget_basic.xml new file mode 100644 index 000000000..fced78cb7 --- /dev/null +++ b/app/src/main/res/layout/settings_widget_basic.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/settings_widget_checkbox.xml b/app/src/main/res/layout/settings_widget_checkbox.xml new file mode 100644 index 000000000..254223fdc --- /dev/null +++ b/app/src/main/res/layout/settings_widget_checkbox.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/settings_widget_led.xml b/app/src/main/res/layout/settings_widget_led.xml new file mode 100644 index 000000000..4e4109a29 --- /dev/null +++ b/app/src/main/res/layout/settings_widget_led.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/settings_widget_list.xml b/app/src/main/res/layout/settings_widget_list.xml new file mode 100644 index 000000000..49f9eec8d --- /dev/null +++ b/app/src/main/res/layout/settings_widget_list.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/settings_widget_switch.xml b/app/src/main/res/layout/settings_widget_switch.xml new file mode 100644 index 000000000..74e6936a6 --- /dev/null +++ b/app/src/main/res/layout/settings_widget_switch.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/settings_widget_text.xml b/app/src/main/res/layout/settings_widget_text.xml new file mode 100644 index 000000000..7eaec0ea1 --- /dev/null +++ b/app/src/main/res/layout/settings_widget_text.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 2e5f3b719..8eca89d97 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -280,7 +280,7 @@ الحساب الافتراضي إضافة حساب متجر التبضع المحمول - النفق + النفق إسم المضيف المنفذ الوضع diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f8708d906..f5cbfedf7 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -329,7 +329,7 @@ Standardkonto Konto hinzufügen In-App Store - Tunnel + Tunnel Hostname Port Modus diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 6d8588dd6..e559b4d8e 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -152,7 +152,7 @@ Cuentas SIP Cuenta por defecto Añadir cuenta - Túnel + Túnel Nombre del servidor Puerto Modo diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index f154b7935..ee30b6712 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -183,7 +183,7 @@ SIP Tilit Vakio tili Lisää tili - Tunneli + Tunneli Hostname \'eli verkkotunnuksen etunimi\' Portti Tila diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 22bfab740..e522dd1cb 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -358,7 +358,7 @@ Disponible gratuitement ici : http://www.linphone.org/technical-corner/linphone/ Compte par défaut Ajouter un compte Magasin - Tunnel + Tunnel Hôte Port Mode diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 452eb9b64..ba2cbd437 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -317,7 +317,7 @@ Account predefinito Aggiungi account In-app Store - Tunnel + Tunnel Nome host Porta Modalità diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 228e4319f..cd2d7d41b 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -267,7 +267,7 @@ デフォルトのアカウント アカウントを追加する アプリストアで - トンネル + トンネル ホスト名 ポート モード diff --git a/app/src/main/res/values-ka/strings.xml b/app/src/main/res/values-ka/strings.xml index d27567fcc..2f51dc4c4 100644 --- a/app/src/main/res/values-ka/strings.xml +++ b/app/src/main/res/values-ka/strings.xml @@ -308,7 +308,7 @@ ნაგულისხმევი ანგარიში ანგარიშის დამატება პროგრამის-შიდა მაღაზია - გვირაბი + გვირაბი ჰოსტის სახელ პორტი რეჟიმი diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index a9faa5e96..61ea58a18 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -134,7 +134,7 @@ SIP-accounts Standaard account Account toevoegen - Tunnel + Tunnel Hostnaam Poort Modus diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index a4f4d618f..230fc9ed6 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -258,7 +258,7 @@ Wpisz wyświetlaną nazwę (opcjonalnie) Domyślne konto Dodaj konto W aplikacji Store - Tunel + Tunel Nazwa hosta Port Tryb diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 30f1cd8e7..33164b6aa 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -315,7 +315,7 @@ Conta padrão Adicionar Conta In-app Store - Túnel + Túnel Hostname Porta Modo diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index aedba48f7..23a818e5a 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -355,7 +355,7 @@ Аккаунт по умолчанию Добавить аккаунт Магазин в приложении - Туннель + Туннель Сервер Порт Режим diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index 89955bd48..809b8bbb8 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -133,7 +133,7 @@ СИП налози Основни налог Додај налог - Тунел + Тунел Домаћин Прикључник Режим diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index 48f85a5a6..cd1ed1797 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -355,7 +355,7 @@ Standardkonto Lägg till konto Butik inom app - Tunnel + Tunnel Värdnamn Port Läge diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index 486e65343..e9a3740e3 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -310,7 +310,7 @@ Öntanımlı hesap Hesap ekle Uygulama İçi Mağaza - Tünel + Tünel Makine Adı Bağlanma Noktası Kip diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 9d2dbb5c9..71db1bb7f 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -343,7 +343,7 @@ Типова обліківка Додати обліківку In-app Store - Тунель + Тунель Сервер Порт Режим diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 715bc446d..1afdb615f 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -269,7 +269,7 @@ 默认账户 添加帐户 内购商店 - Tunnel隧道 + Tunnel隧道 主机名 端口 模式 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index ecad3517e..6e8aae42f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -315,7 +315,7 @@ 預設帳號 加入帳號 應用程式內的商店 - 隧道(Tunnel) + 隧道(Tunnel) 主機名稱 連接埠 模式 diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index c36244411..05516bc49 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -27,4 +27,12 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/non_localizable_strings.xml b/app/src/main/res/values/non_localizable_strings.xml index bbb4b125e..a6b9070db 100644 --- a/app/src/main/res/values/non_localizable_strings.xml +++ b/app/src/main/res/values/non_localizable_strings.xml @@ -5,193 +5,14 @@ dummy subject - pref_dark_mode_key - - - pref_disable_account_key - pref_nb_accounts_extra - pref_default_account - - pref_tunnel_key - pref_tunnel_mode_key - disabled - 3G_only - always - - @string/tunnel_mode_entry_value_disabled - @string/tunnel_mode_entry_value_3G_only - @string/tunnel_mode_entry_value_always - @string/tunnel_mode_entry_value_auto + + @string/debug_popup_enable_logs + @string/cancel - pref_tunnel_host_key - pref_tunnel_port_key - auto - - pref_audio_use_specific_mode_key - pref_audio_hacks_use_galaxys_hack_key - pref_audio_hacks_use_routing_api_key - pref_audio_soft_volume_key - pref_audio_ringtone - pref_incoming_call_vibration_key - pref_mic_gain_db_key - pref_playback_gain_db_key - - pref_ipv6_key - - menu_about_key - pref_sipaccounts_key - setup_key - pref_add_account_key - pref_in_app_store_key - pref_video_key - pref_video_codecs_key - - pref_transport_key - pref_transport_udp_key - pref_transport_tcp_key - pref_transport_tls_key - pref_transport_use_random_ports_key - pref_sip_port_key - - pref_echo_canceller_calibration_key - pref_prefix_key - pref_proxy_key - pref_domain_key - pref_passwd_key - pref_username_key - pref_auth_userid_key - pref_wizard_key - pref_activated_key - pref_debug_key - pref_java_debug_key - first_launch_succeeded_once_key - - pref_wifi_only_key - pref_doze_mode_key - - pref_overlay_key - pref_video_use_front_camera_key - pref_video_codec_h263_key - pref_video_codec_mpeg4_key - pref_video_codec_h264_key - pref_video_automatically_accept_video_key - pref_video_initiate_call_with_video_key - pref_video_enable_key - pref_video_preset_key - pref_preferred_video_size_key - pref_preferred_video_fps_key - pref_bandwidth_limit_key - pref_animation_enable_key - pref_service_notification_key - pref_escape_plus_key - pref_friendlist_subscribe_key - pref_link_account_key - pref_proxy_push_notif_key - pref_device_power_saver_settings_key - pref_echo_cancellation_key - pref_autostart_key - Outbound proxy - pref_codec_pcma_key - pref_codec_pcmu_key - pref_codec_gsm_key - pref_codec_g722_key - pref_codec_g729_key - pref_codec_amr_key - pref_codec_amrwb_key - pref_codec_ilbc_key - pref_codec_speex8_key - pref_codec_speex16_key - pref_codec_speex32_key - pref_codec_silk8_key - pref_codec_silk12_key - pref_codec_silk16_key - pref_codec_silk24_key - pref_codec_opus_key - pref_codecs_key - pref_stun_server_key - pref_ice_enable_key - pref_turn_enable_key - pref_video_codec_vp8_key - pref_media_encryption_key - none - srtp - zrtp - dtls - pref_background_mode_key - pref_codec_bitrate_limit_key - pref_adaptive_rate_control_key - pref_echo_tester_key - pref_auto_download_policy_key - pref_auto_download_max_size_key - -1 - 0 - 10000000 - - @string/pref_auto_download_policy_disabled_key - @string/pref_auto_download_policy_always_key - @string/pref_auto_download_policy_size_key - - pref_accept_early_media_key - - push_reg_id_key - push_sender_id_key - pref_push_notification_key - - pref_auto_accept_friends_key - pref_image_sharing_server_key - pref_remote_provisioning_key - - pref_video_port_key - pref_audio_port_key - pref_incoming_expire_key - pref_call_timeout_key - pref_auto_answer_time_key - - pref_display_name_key - pref_user_name_key - pref_expire_key - pref_avpf_key - pref_avpf_rr_interval_key - - pref_rfc2833_dtmf_key - pref_sipinfo_dtmf_key - pref_voice_mail_key - pref_dialer_call_key - pref_upnp_enable_key - - pref_first_time_linphone_chat_storage - - pref_sipaccount_key - pref_audio_key - pref_call_key - pref_chat_key - pref_network_key - pref_advanced_key - pref_manage_key - - - H263 - MP4V-ES - H264 - pcma - pcmu - gsm - g722 - amr - amr-wb - ilbc - speex 8 Khz - speex 16 Khz - opus 48Khz - silk 8 Khz - silk 12 Khz - silk 16 Khz - silk 24 Khz - g729 - - - Simple - Stateful + + @string/debug_popup_disable_logs + @string/debug_popup_send_logs + @string/cancel @@ -217,33 +38,28 @@ custom - VP8 - SRTP - ZRTP - DTLS - - Debug - - Enable logs - Cancel + -1 + 0 + 10000000 + + @string/pref_auto_download_policy_disabled_key + @string/pref_auto_download_policy_always_key + @string/pref_auto_download_policy_size_key - - Disable logs - Send logs - Cancel - - - pref_use_lime_encryption_key - pref_device_ringtone_key - pref_auto_answer_key - pref_android_app_settings_key - pref_android_app_notif_settings_key - pref_turn_username_key - pref_turn_passwd_key - @string/pref_auto_download_disabled @string/pref_auto_download_always @string/pref_auto_download_under_size + + disabled + 3G_only + always + auto + + @string/tunnel_mode_entry_value_disabled + @string/tunnel_mode_entry_value_3G_only + @string/tunnel_mode_entry_value_always + @string/tunnel_mode_entry_value_auto + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3b9d8a3ba..ffb928197 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -377,7 +377,7 @@ Default account Add account In-app Store - Tunnel + Tunnel Hostname Port Mode @@ -506,6 +506,12 @@ Settings Later + + Debug + Enable logs + Disable logs + Send logs + Back Dialer diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index d2c91c6a1..08fee9f5b 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -308,6 +308,25 @@ 28sp + + + + + + + +