From ca74953104c23456fc21d97df6ea1e94dbf9d6a0 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 29 Aug 2012 16:06:39 +0200 Subject: [PATCH] Preferences as fragments --- .../linphone/AccountPreferencesFragment.java | 172 ++++++++ src/org/linphone/FragmentsAvailable.java | 6 +- src/org/linphone/InCallActivity.java | 14 + src/org/linphone/LinphoneActivity.java | 64 ++- src/org/linphone/PreferencesFragment.java | 385 +++++++++++++++++- .../linphone/ui/PreferencesListFragment.java | 21 +- 6 files changed, 644 insertions(+), 18 deletions(-) create mode 100644 src/org/linphone/AccountPreferencesFragment.java diff --git a/src/org/linphone/AccountPreferencesFragment.java b/src/org/linphone/AccountPreferencesFragment.java new file mode 100644 index 000000000..2a9064c35 --- /dev/null +++ b/src/org/linphone/AccountPreferencesFragment.java @@ -0,0 +1,172 @@ +package org.linphone; +/* +AccountPreferencesFragment.java +Copyright (C) 2012 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +import org.linphone.compatibility.Compatibility; +import org.linphone.ui.PreferencesListFragment; + +import android.content.SharedPreferences; +import android.os.Bundle; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceCategory; +import android.preference.PreferenceScreen; +import android.text.InputType; + +/** + * @author Sylvain Berfini + */ +public class AccountPreferencesFragment extends PreferencesListFragment { + + public AccountPreferencesFragment() { + super(R.xml.account_preferences); + } + + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + PreferenceScreen screen = getPreferenceScreen(); + int n = getArguments().getInt("Account", 1); + manageAccountPreferencesFields(screen, n); + } + + OnPreferenceChangeListener preferenceChangedListener = new OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + preference.setSummary(newValue.toString()); + return true; + } + }; + + private void manageAccountPreferencesFields(PreferenceScreen parent, final int n) { + final SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); + + PreferenceCategory account = (PreferenceCategory) getPreferenceScreen().getPreference(0); + EditTextPreference username = (EditTextPreference) account.getPreference(0); + username.setText(prefs.getString(getString(R.string.pref_username_key) + getAccountNumber(n), "")); + username.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); + username.setKey(getString(R.string.pref_username_key) + getAccountNumber(n)); + username.setOnPreferenceChangeListener(preferenceChangedListener); + username.setSummary(username.getText()); + + EditTextPreference password = (EditTextPreference) account.getPreference(1); + password.setText(prefs.getString(getString(R.string.pref_passwd_key) + getAccountNumber(n), "")); + password.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_PASSWORD); + password.setKey(getString(R.string.pref_passwd_key) + getAccountNumber(n)); + + EditTextPreference domain = (EditTextPreference) account.getPreference(2); + domain.setText(prefs.getString(getString(R.string.pref_domain_key) + getAccountNumber(n), "")); + domain.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); + domain.setKey(getString(R.string.pref_domain_key) + getAccountNumber(n)); + domain.setOnPreferenceChangeListener(preferenceChangedListener); + domain.setSummary(domain.getText()); + + PreferenceCategory advanced = (PreferenceCategory) getPreferenceScreen().getPreference(1); + EditTextPreference proxy = (EditTextPreference) advanced.getPreference(0); + proxy.setText(prefs.getString(getString(R.string.pref_proxy_key) + getAccountNumber(n), "")); + proxy.getEditText().setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS); + proxy.setKey(getString(R.string.pref_proxy_key) + getAccountNumber(n)); + proxy.setOnPreferenceChangeListener(preferenceChangedListener); + proxy.setSummary("".equals(proxy.getText()) || (proxy.getText() == null) ? getString(R.string.pref_help_proxy) : proxy.getText()); + + Preference outboundProxy = advanced.getPreference(1); + Compatibility.setPreferenceChecked(outboundProxy, prefs.getBoolean(getString(R.string.pref_enable_outbound_proxy_key) + getAccountNumber(n), false)); + outboundProxy.setKey(getString(R.string.pref_enable_outbound_proxy_key) + getAccountNumber(n)); + + final Preference disable = advanced.getPreference(2); + disable.setEnabled(prefs.getInt(getString(R.string.pref_default_account), 0) != n); + Compatibility.setPreferenceChecked(outboundProxy, prefs.getBoolean(getString(R.string.pref_disable_account_key) + getAccountNumber(n), false)); + disable.setKey(getString(R.string.pref_disable_account_key) + getAccountNumber(n)); + + final Preference delete = advanced.getPreference(4); + delete.setEnabled(prefs.getInt(getString(R.string.pref_default_account), 0) != n); + delete.setOnPreferenceClickListener(new OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + int nbAccounts = prefs.getInt(getString(R.string.pref_extra_accounts), 1); + SharedPreferences.Editor editor = prefs.edit(); + + for (int i = n; i < nbAccounts - 1; i++) { + editor.putString(getString(R.string.pref_username_key) + getAccountNumber(i), prefs.getString(getString(R.string.pref_username_key) + getAccountNumber(i+1), null)); + editor.putString(getString(R.string.pref_passwd_key) + getAccountNumber(i), prefs.getString(getString(R.string.pref_passwd_key) + getAccountNumber(i+1), null)); + editor.putString(getString(R.string.pref_domain_key) + getAccountNumber(i), prefs.getString(getString(R.string.pref_domain_key) + getAccountNumber(i+1), null)); + editor.putString(getString(R.string.pref_proxy_key) + getAccountNumber(i), prefs.getString(getString(R.string.pref_proxy_key) + getAccountNumber(i+1), null)); + editor.putBoolean(getString(R.string.pref_enable_outbound_proxy_key) + getAccountNumber(i), prefs.getBoolean(getString(R.string.pref_enable_outbound_proxy_key) + getAccountNumber(i+1), false)); + editor.putBoolean(getString(R.string.pref_disable_account_key) + getAccountNumber(i), prefs.getBoolean(getString(R.string.pref_disable_account_key) + getAccountNumber(i+1), false)); + } + + int lastAccount = nbAccounts - 1; + editor.putString(getString(R.string.pref_username_key) + getAccountNumber(lastAccount), null); + editor.putString(getString(R.string.pref_passwd_key) + getAccountNumber(lastAccount), null); + editor.putString(getString(R.string.pref_domain_key) + getAccountNumber(lastAccount), null); + editor.putString(getString(R.string.pref_proxy_key) + getAccountNumber(lastAccount), null); + editor.putBoolean(getString(R.string.pref_enable_outbound_proxy_key) + getAccountNumber(lastAccount), false); + editor.putBoolean(getString(R.string.pref_disable_account_key) + getAccountNumber(lastAccount), false); + + int defaultAccount = prefs.getInt(getString(R.string.pref_default_account), 0); + if (defaultAccount > n) { + editor.putInt(getString(R.string.pref_default_account), defaultAccount - 1); + } + + editor.putInt(getString(R.string.pref_extra_accounts), nbAccounts - 1); + editor.commit(); + + LinphoneActivity.instance().displaySettings(); + + return true; + } + }); + + Preference mainAccount = advanced.getPreference(3); + Compatibility.setPreferenceChecked(mainAccount, prefs.getInt(getString(R.string.pref_default_account), 0) == n); + mainAccount.setEnabled(!Compatibility.isPreferenceChecked(mainAccount)); + mainAccount.setOnPreferenceClickListener(new OnPreferenceClickListener() + { + public boolean onPreferenceClick(Preference preference) { + + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt(getString(R.string.pref_default_account_key), n); + editor.commit(); + delete.setEnabled(false); + disable.setEnabled(false); + Compatibility.setPreferenceChecked(disable, false); + preference.setEnabled(false); + return true; + } + }); + } + + private String getAccountNumber(int n) { + if (n > 0) + return Integer.toString(n); + else + return ""; + } + + @Override + public void onPause() { + super.onPause(); + + if (LinphoneActivity.isInstanciated()) { + LinphoneActivity.instance().applyConfigChangesIfNeeded(); + } + } +} diff --git a/src/org/linphone/FragmentsAvailable.java b/src/org/linphone/FragmentsAvailable.java index 90bfd6d7c..0f4d50411 100644 --- a/src/org/linphone/FragmentsAvailable.java +++ b/src/org/linphone/FragmentsAvailable.java @@ -29,6 +29,7 @@ public enum FragmentsAvailable { CONTACT, ABOUT_INSTEAD_OF_SETTINGS, ABOUT_INSTEAD_OF_CHAT, + ACCOUNT_SETTINGS, SETTINGS, CHATLIST, CHAT; @@ -62,9 +63,12 @@ public enum FragmentsAvailable { case SETTINGS: return DIALER.isRightOf(fragment) || fragment == DIALER; + case ACCOUNT_SETTINGS: + return SETTINGS.isRightOf(fragment) || fragment == SETTINGS; + case ABOUT_INSTEAD_OF_CHAT: case CHATLIST: - return SETTINGS.isRightOf(fragment) || fragment == SETTINGS || fragment == FragmentsAvailable.ABOUT_INSTEAD_OF_SETTINGS; + return ACCOUNT_SETTINGS.isRightOf(fragment) || fragment == ACCOUNT_SETTINGS || fragment == FragmentsAvailable.ABOUT_INSTEAD_OF_SETTINGS; case CHAT: return CHATLIST.isRightOf(fragment) || fragment == CHATLIST; diff --git a/src/org/linphone/InCallActivity.java b/src/org/linphone/InCallActivity.java index 54211eb38..5de8a05c5 100644 --- a/src/org/linphone/InCallActivity.java +++ b/src/org/linphone/InCallActivity.java @@ -49,6 +49,7 @@ import android.view.animation.AnimationUtils; import android.widget.AdapterView; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.Toast; /** * @author Sylvain Berfini @@ -639,6 +640,10 @@ public class InCallActivity extends FragmentActivity implements @Override public void onCallStateChanged(LinphoneCall call, State state, String message) { + if (state==State.Error){ + showToast(R.string.call_error, message); + } + if (LinphoneManager.getLc().getCallsNb() == 0) { finish(); return; @@ -666,6 +671,15 @@ public class InCallActivity extends FragmentActivity implements transfer.setEnabled(LinphoneManager.getLc().getCurrentCall() != null); } + + private void showToast(int id, String txt) { + final String msg = String.format(getString(id), txt); + mHandler.post(new Runnable() { + public void run() { + Toast.makeText(InCallActivity.this, msg, Toast.LENGTH_SHORT).show(); + } + }); + } @Override public void onCallEncryptionChanged(LinphoneCall call, boolean encrypted, String authenticationToken) { diff --git a/src/org/linphone/LinphoneActivity.java b/src/org/linphone/LinphoneActivity.java index b438f053e..5ac5def64 100644 --- a/src/org/linphone/LinphoneActivity.java +++ b/src/org/linphone/LinphoneActivity.java @@ -25,6 +25,7 @@ import java.util.Calendar; import java.util.List; import org.linphone.LinphoneManager.AddressType; +import org.linphone.LinphoneManager.LinphoneConfigException; import org.linphone.LinphoneSimpleListener.LinphoneOnCallStateChangedListener; import org.linphone.LinphoneSimpleListener.LinphoneOnMessageReceivedListener; import org.linphone.LinphoneSimpleListener.LinphoneOnRegistrationStateChangedListener; @@ -42,7 +43,6 @@ import org.linphone.core.Log; import org.linphone.mediastream.Version; import org.linphone.setup.SetupActivity; import org.linphone.ui.AddressText; -import org.linphone.ui.PreferencesListFragment; import android.app.Activity; import android.content.Context; @@ -87,7 +87,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene private StatusFragment statusFragment; private TextView missedCalls, missedChats; private ImageView history, contacts, dialer, settings, chat, aboutChat, aboutSettings; - private FragmentsAvailable currentFragment; + private FragmentsAvailable currentFragment, nextFragment; private Fragment dialerFragment, messageListenerFragment; private SavedState dialerSavedState; private ChatStorage chatStorage; @@ -128,7 +128,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene instance = this; initButtons(); - currentFragment = FragmentsAvailable.DIALER; + currentFragment = nextFragment = FragmentsAvailable.DIALER; if (savedInstanceState == null) { if (findViewById(R.id.fragmentContainer) != null) { dialerFragment = new DialerFragment(); @@ -194,6 +194,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene if (newFragmentType == currentFragment && newFragmentType != FragmentsAvailable.CHAT) { return; } + nextFragment = newFragmentType; if (currentFragment == FragmentsAvailable.DIALER) { dialerSavedState = getSupportFragmentManager().saveFragmentInstanceState(dialerFragment); @@ -228,6 +229,9 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene case SETTINGS: newFragment = new PreferencesFragment(); break; + case ACCOUNT_SETTINGS: + newFragment = new AccountPreferencesFragment(); + break; case ABOUT_INSTEAD_OF_CHAT: case ABOUT_INSTEAD_OF_SETTINGS: newFragment = new AboutFragment(); @@ -293,7 +297,9 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene transaction.addToBackStack(newFragmentType.toString()); transaction.replace(R.id.fragmentContainer2, newFragment); } else { - if (newFragmentType == FragmentsAvailable.DIALER) { + if (newFragmentType == FragmentsAvailable.DIALER + || newFragmentType == FragmentsAvailable.SETTINGS + || newFragmentType == FragmentsAvailable.ACCOUNT_SETTINGS) { ll.setVisibility(View.GONE); } else { ll.setVisibility(View.INVISIBLE); @@ -441,14 +447,6 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene dialer.setSelected(true); } else if (id == R.id.settings) { -// Intent intent = new Intent(ACTION_MAIN); -// intent.setClass(this, PreferencesActivity.class); -// startActivityForResult(intent, SETTINGS_ACTIVITY); -// if (FragmentsAvailable.SETTINGS.isRightOf(currentFragment)) { -// Compatibility.overridePendingTransition(this, R.anim.slide_in_right_to_left, R.anim.slide_out_right_to_left); -// } else { -// Compatibility.overridePendingTransition(this, R.anim.slide_in_left_to_right, R.anim.slide_out_left_to_right); -// } changeCurrentFragment(FragmentsAvailable.SETTINGS, null); settings.setSelected(true); } @@ -498,6 +496,7 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene dialer.setSelected(true); break; case SETTINGS: + case ACCOUNT_SETTINGS: settings.setSelected(true); break; case ABOUT_INSTEAD_OF_CHAT: @@ -533,6 +532,45 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene } } + public void displaySettings() { + changeCurrentFragment(FragmentsAvailable.SETTINGS, null); + settings.setSelected(true); + } + + public void applyConfigChangesIfNeeded() { + if (nextFragment != FragmentsAvailable.SETTINGS && nextFragment != FragmentsAvailable.ACCOUNT_SETTINGS) { + reloadConfig(); + } + } + + private void reloadConfig() { + LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull(); + + if (lc != null && (lc.isInComingInvitePending() || lc.isIncall())) { + Log.w("Call in progress => settings not applied"); + return; + } + + try { + LinphoneManager.getInstance().initFromConf(); + lc.setVideoPolicy(LinphoneManager.getInstance().isAutoInitiateVideoCalls(), LinphoneManager.getInstance().isAutoAcceptCamera()); + } catch (LinphoneException e) { + if (! (e instanceof LinphoneConfigException)) { + Log.e(e, "Cannot update config"); + return; + } + + LinphoneActivity.instance().showPreferenceErrorDialog(e.getMessage()); + } + } + + public void displayAccountSettings(int accountNumber) { + Bundle bundle = new Bundle(); + bundle.putInt("Account", accountNumber); + changeCurrentFragment(FragmentsAvailable.ACCOUNT_SETTINGS, bundle); + settings.setSelected(true); + } + public StatusFragment getStatusFragment() { return statusFragment; } @@ -936,6 +974,8 @@ public class LinphoneActivity extends FragmentActivity implements OnClickListene if (LinphoneUtils.onKeyBackGoHome(this, keyCode, event)) { return true; } + } else if (keyCode == KeyEvent.KEYCODE_BACK && currentFragment == FragmentsAvailable.SETTINGS) { + reloadConfig(); } if (keyCode == KeyEvent.KEYCODE_MENU && statusFragment != null) { statusFragment.openOrCloseStatusBar(); diff --git a/src/org/linphone/PreferencesFragment.java b/src/org/linphone/PreferencesFragment.java index fac6a9cb4..01db62f9b 100644 --- a/src/org/linphone/PreferencesFragment.java +++ b/src/org/linphone/PreferencesFragment.java @@ -1,20 +1,75 @@ package org.linphone; +/* +PreferencesFragment.java +Copyright (C) 2012 Belledonne Communications, Grenoble, France +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ +import static org.linphone.R.string.ec_calibrating; +import static org.linphone.R.string.pref_codec_amr_key; +import static org.linphone.R.string.pref_codec_amrwb_key; +import static org.linphone.R.string.pref_codec_ilbc_key; +import static org.linphone.R.string.pref_codec_speex16_key; +import static org.linphone.R.string.pref_echo_cancellation_key; +import static org.linphone.R.string.pref_echo_canceller_calibration_key; +import static org.linphone.R.string.pref_echo_limiter_key; import static org.linphone.R.string.pref_media_encryption_key; +import static org.linphone.R.string.pref_video_enable_key; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import org.linphone.LinphoneManager.EcCalibrationListener; import org.linphone.core.LinphoneCore; +import org.linphone.core.LinphoneCore.EcCalibratorStatus; import org.linphone.core.LinphoneCore.MediaEncryption; +import org.linphone.core.LinphoneCoreException; +import org.linphone.core.Log; +import org.linphone.mediastream.Version; +import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration; +import org.linphone.mediastream.video.capture.hwconf.Hacks; +import org.linphone.setup.SetupActivity; import org.linphone.ui.PreferencesListFragment; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; +import android.os.Handler; +import android.preference.CheckBoxPreference; import android.preference.ListPreference; import android.preference.Preference; +import android.preference.Preference.OnPreferenceChangeListener; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceCategory; +import android.preference.PreferenceScreen; -public class PreferencesFragment extends PreferencesListFragment { +public class PreferencesFragment extends PreferencesListFragment implements EcCalibrationListener { + private Handler mHandler = new Handler(); + private Context mContext; + private CheckBoxPreference ecCalibratePref; + private CheckBoxPreference elPref; + private CheckBoxPreference ecPref; private ListPreference mencPref; + private int nbAccounts = 1; + private PreferenceCategory accounts; + + private static final int ACCOUNTS_SETTINGS_ID = 0; + private static final int WIZARD_SETTINGS_ID = 1; + private static final int CAMERA_SETTINGS_ID = 5; public PreferencesFragment() { super(R.xml.preferences); @@ -23,8 +78,325 @@ public class PreferencesFragment extends PreferencesListFragment { @Override public void onCreate(Bundle bundle) { super.onCreate(bundle); + mContext = getActivity(); + + if (getResources().getBoolean(R.bool.hide_accounts)) { + // Hide category + PreferenceCategory accounts = (PreferenceCategory) getPreferenceScreen().getPreference(ACCOUNTS_SETTINGS_ID); + accounts.removeAll(); + accounts.setLayoutResource(R.layout.hidden); + } + + if (getResources().getBoolean(R.bool.hide_wizard)) { + Preference wizard = (Preference) getPreferenceScreen().getPreference(WIZARD_SETTINGS_ID); + wizard.setLayoutResource(R.layout.hidden); + } else { + addWizardPreferenceButton(); + } + + addTransportChecboxesListener(); + + ecCalibratePref = (CheckBoxPreference) findPreference(pref_echo_canceller_calibration_key); + ecCalibratePref.setOnPreferenceClickListener(new OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + startEcCalibration(); + return false; + } + }); + ecPref = (CheckBoxPreference) findPreference(pref_echo_cancellation_key); + elPref = (CheckBoxPreference) findPreference(pref_echo_limiter_key); mencPref = (ListPreference) findPreference(pref_media_encryption_key); + + boolean fastCpu = Version.hasFastCpu(); + if (fastCpu) { + detectAudioCodec(pref_codec_ilbc_key, "iLBC", 8000, 1, false); + findPreference(pref_codec_speex16_key).setEnabled(true); + //findPreference(pref_codec_speex32_key)).setEnabled(enableIlbc); + } + findPreference(pref_echo_limiter_key).setEnabled(true); + initializeMediaEncryptionPreferences(); + + detectAudioCodec(pref_codec_amr_key,"AMR", 8000, 1, false); + detectAudioCodec(pref_codec_amrwb_key,"AMR-WB", 16000, 1, false); + //detectAudioCodec(R.string.pref_codec_silk8_key,"SILK",8000, 1, true); + //detectAudioCodec(R.string.pref_codec_silk12_key,"SILK",12000, 1, true); + detectAudioCodec(R.string.pref_codec_silk16_key,"SILK",16000, 1, true); + detectAudioCodec(R.string.pref_codec_silk24_key,"SILK",24000, 1, true); + detectAudioCodec(R.string.pref_codec_g729_key,"G729",8000, 1, true); + + // No video + if (!Version.isVideoCapable()) { + uncheckAndDisableCheckbox(pref_video_enable_key); + } else if (!AndroidCameraConfiguration.hasFrontCamera()) { + uncheckDisableAndHideCheckbox(R.string.pref_video_use_front_camera_key); + } + + if (prefs().getBoolean(LinphoneActivity.PREF_FIRST_LAUNCH,true)) { + doOnFirstLaunch(); + } + if (Hacks.hasBuiltInEchoCanceller()) { + uncheckDisableAndHideCheckbox(R.string.pref_echo_limiter_key); + uncheckDisableAndHideCheckbox(R.string.pref_echo_cancellation_key); + uncheckDisableAndHideCheckbox(R.string.pref_echo_canceller_calibration_key); + } + + + detectVideoCodec(R.string.pref_video_codec_h264_key, "H264"); + if (!Version.hasNeon()) + { + // Android without neon doesn't support H264 + findPreference(R.string.pref_video_codec_h264_key).setEnabled(false); + findPreference(R.string.pref_video_codec_h264_key).setDefaultValue(false); + } + + addEchoPrefsListener(); + + if (Hacks.needSoftvolume()) checkAndDisableCheckbox(R.string.pref_audio_hacks_use_galaxys_hack_key); + + if (!LinphoneManager.getLc().isTunnelAvailable()){ + hidePreferenceCategory(R.string.pref_tunnel_key); + } + + if (getResources().getBoolean(R.bool.hide_camera_settings)) { + PreferenceScreen screen = getPreferenceScreen(); + PreferenceCategory videoSettings = (PreferenceCategory) screen.getPreference(CAMERA_SETTINGS_ID); + videoSettings.removeAll(); + videoSettings.setLayoutResource(R.layout.hidden); + + Preference enableVideo = findPreference(R.string.pref_video_enable_key); + enableVideo.setLayoutResource(R.layout.hidden); + } + } + + private void hidePreferenceCategory(int key) { + PreferenceCategory p = (PreferenceCategory) findPreference(key); + p.removeAll(); + p.setLayoutResource(R.layout.hidden); + } + + private void doOnFirstLaunch() { + manageCheckbox(R.string.pref_echo_limiter_key, !Hacks.hasBuiltInEchoCanceller(), true, false); + prefs().edit().putBoolean(LinphoneActivity.PREF_FIRST_LAUNCH, false).commit(); + } + + private void addEchoPrefsListener(){ + OnPreferenceChangeListener ec_listener=new OnPreferenceChangeListener(){ + public boolean onPreferenceChange(Preference arg0, Object newValue) { + Boolean val=(Boolean)newValue; + if (val){ + elPref.setChecked(!val); + } + return true; + } + }; + OnPreferenceChangeListener el_listener=new OnPreferenceChangeListener(){ + public boolean onPreferenceChange(Preference arg0, Object newValue) { + Boolean val=(Boolean)newValue; + if (val){ + ecPref.setChecked(!val); + } + return true; + } + }; + ecPref.setOnPreferenceChangeListener(ec_listener); + elPref.setOnPreferenceChangeListener(el_listener); + } + + private void addTransportChecboxesListener() { + + final List checkboxes = Arrays.asList( + findCheckbox(R.string.pref_transport_udp_key) + ,findCheckbox(R.string.pref_transport_tcp_key) + ,findCheckbox(R.string.pref_transport_tls_key) + ); + + + OnPreferenceChangeListener changedListener = new OnPreferenceChangeListener() { + public boolean onPreferenceChange(Preference preference, Object newValue) { + if ((Boolean) newValue) { + for (CheckBoxPreference p : checkboxes) { + if (p == preference) continue; + p.setChecked(false); + } + return true; + } else { + for (CheckBoxPreference p : checkboxes) { + if (p == preference) continue; + if (p.isChecked()) return true; + } + return false; + } + } + }; + + OnPreferenceClickListener clickListener = new OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + // Forbid no protocol selection + + if (((CheckBoxPreference) preference).isChecked()) { + // Trying to unckeck + for (CheckBoxPreference p : checkboxes) { + if (p == preference) continue; + if (p.isChecked()) return false; + } + /*Toast.makeText(LinphonePreferencesActivity.this, + getString(R.string.at_least_a_protocol), + Toast.LENGTH_SHORT).show();*/ + return true; + } + return false; + } + }; + + for (CheckBoxPreference c : checkboxes) { + c.setOnPreferenceChangeListener(changedListener); + c.setOnPreferenceClickListener(clickListener); + } + } + + private synchronized void startEcCalibration() { + try { + LinphoneManager.getInstance().startEcCalibration(this); + + ecCalibratePref.setSummary(ec_calibrating); + ecCalibratePref.getEditor().putBoolean(getString(pref_echo_canceller_calibration_key), false).commit(); + } catch (LinphoneCoreException e) { + Log.w(e, "Cannot calibrate EC"); + } + } + + public void onEcCalibrationStatus(final EcCalibratorStatus status, final int delayMs) { + + mHandler.post(new Runnable() { + public void run() { + if (status == EcCalibratorStatus.Done) { + ecCalibratePref.setSummary(String.format(getString(R.string.ec_calibrated), delayMs)); + ecCalibratePref.setChecked(true); + + } else if (status == EcCalibratorStatus.Failed) { + ecCalibratePref.setSummary(R.string.failed); + ecCalibratePref.setChecked(false); + elPref.setChecked(true); + ecPref.setChecked(false); + } + } + }); + } + + private void uncheckDisableAndHideCheckbox(int key) { + manageCheckbox(key, false, false, true); + } + + private void uncheckAndDisableCheckbox(int key) { + manageCheckbox(key, false, false, false); + } + + private void checkAndDisableCheckbox(int key) { + manageCheckbox(key, true, false, false); + } + + private void manageCheckbox(int key, boolean value, boolean enabled, boolean hidden) { + CheckBoxPreference box = (CheckBoxPreference) findPreference(key); + box.setEnabled(enabled); + box.setChecked(value); + writeBoolean(key, value); + if (hidden) box.setLayoutResource(R.layout.hidden); + } + + private void writeBoolean(int key, boolean value) { + prefs().edit().putBoolean(getString(key), value).commit(); + } + + private SharedPreferences prefs() { + return getPreferenceManager().getSharedPreferences(); + } + + private CheckBoxPreference findCheckbox(int key) { + return (CheckBoxPreference) findPreference(getString(key)); + } + + private void detectAudioCodec(int id, String mime, int rate, int channels, boolean hide) { + boolean enable = LinphoneService.isReady() && LinphoneManager.getLc().findPayloadType(mime, rate, channels)!=null; + Preference cb = findPreference(id); + cb.setEnabled(enable); + if (hide && !enable) { + cb.setLayoutResource(R.layout.hidden); + } + } + + private void detectVideoCodec(int id, String mime) { + findPreference(id).setEnabled(LinphoneManager.getInstance().detectVideoCodec(mime)); + } + + private void createDynamicAccountsPreferences() { + accounts = (PreferenceCategory) getPreferenceScreen().getPreference(ACCOUNTS_SETTINGS_ID); + accounts.removeAll(); + + // Get already configured extra accounts + SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); + nbAccounts = prefs.getInt(getString(R.string.pref_extra_accounts), 0); + for (int i = 0; i < nbAccounts; i++) { + // For each, add menus to configure it + addExtraAccountPreferencesButton(accounts, i, false); + } + } + + public int getNbAccountsExtra() { + return nbAccounts; + } + + private void addExtraAccountPreferencesButton(PreferenceCategory parent, final int n, boolean isNewAccount) { + final SharedPreferences prefs = getPreferenceManager().getSharedPreferences(); + if (isNewAccount) { + SharedPreferences.Editor editor = prefs.edit(); + editor.putInt(getString(R.string.pref_extra_accounts), n+1); + editor.commit(); + } + + final Preference me = new Preference(mContext); + String keyUsername = getString(R.string.pref_username_key); + String keyDomain = getString(R.string.pref_domain_key); + if (n > 0) { + keyUsername += n + ""; + keyDomain += n + ""; + } + if (prefs.getString(keyUsername, null) == null) { + me.setTitle(getString(R.string.pref_sipaccount)); + } else { + me.setTitle(prefs.getString(keyUsername, "") + "@" + prefs.getString(keyDomain, "")); + } + + me.setOnPreferenceClickListener(new OnPreferenceClickListener() + { + public boolean onPreferenceClick(Preference preference) { + LinphoneActivity.instance().displayAccountSettings(n); + return false; + } + }); + + parent.addPreference(me); + } + + public void refresh() { +// try { +// LinphoneManager.getInstance().initAccounts(); +// } catch (Exception e) { +// e.printStackTrace(); +// } + + createDynamicAccountsPreferences(); + } + + private void addWizardPreferenceButton() { + Preference wizard = (Preference) getPreferenceScreen().getPreference(WIZARD_SETTINGS_ID); + wizard.setOnPreferenceClickListener(new OnPreferenceClickListener() { + public boolean onPreferenceClick(Preference preference) { + Intent intent = new Intent(mContext, SetupActivity.class); + startActivity(intent); + return true; + } + }); } private void initializeMediaEncryptionPreferences() { @@ -61,6 +433,15 @@ public class PreferencesFragment extends PreferencesListFragment { return getPreferenceManager().findPreference(getString(key)); } + @Override + public void onPause() { + super.onPause(); + + if (LinphoneActivity.isInstanciated()) { + LinphoneActivity.instance().applyConfigChangesIfNeeded(); + } + } + @Override public void onResume() { super.onResume(); @@ -68,5 +449,7 @@ public class PreferencesFragment extends PreferencesListFragment { if (LinphoneActivity.isInstanciated()) { LinphoneActivity.instance().selectMenu(FragmentsAvailable.SETTINGS); } + + refresh(); } } diff --git a/src/org/linphone/ui/PreferencesListFragment.java b/src/org/linphone/ui/PreferencesListFragment.java index 4ea5163fa..d8a6ff6e1 100644 --- a/src/org/linphone/ui/PreferencesListFragment.java +++ b/src/org/linphone/ui/PreferencesListFragment.java @@ -1,5 +1,22 @@ package org.linphone.ui; +/* +PreferencesListFragment.java +Copyright (C) 2012 Belledonne Communications, Grenoble, France +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -235,8 +252,4 @@ public class PreferencesListFragment extends ListFragment { } return mPreferenceManager.findPreference(key); } - - public interface OnPreferenceAttachedListener { - public void onPreferenceAttached(PreferenceScreen root, int xmlId); - } } \ No newline at end of file