631 lines
26 KiB
Java
631 lines
26 KiB
Java
/*
|
|
* Copyright (C) 2017 Schürmann & Breitmoser GbR
|
|
*
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package org.sufficientlysecure.keychain.ui;
|
|
|
|
|
|
import java.security.KeyStore;
|
|
import java.security.KeyStoreException;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
import android.Manifest;
|
|
import android.accounts.Account;
|
|
import android.accounts.AccountManager;
|
|
import android.annotation.TargetApi;
|
|
import android.app.Activity;
|
|
import android.content.ContentResolver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.pm.PackageManager;
|
|
import android.os.Build;
|
|
import android.os.Bundle;
|
|
import android.preference.EditTextPreference;
|
|
import android.preference.ListPreference;
|
|
import android.preference.Preference;
|
|
import android.preference.PreferenceFragment;
|
|
import android.preference.PreferenceScreen;
|
|
import android.preference.SwitchPreference;
|
|
import android.provider.ContactsContract;
|
|
import android.text.TextUtils;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.LinearLayout;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.appcompat.widget.Toolbar;
|
|
import androidx.core.content.ContextCompat;
|
|
import org.sufficientlysecure.keychain.Constants;
|
|
import org.sufficientlysecure.keychain.KeychainApplication;
|
|
import org.sufficientlysecure.keychain.R;
|
|
import org.sufficientlysecure.keychain.compatibility.AppCompatPreferenceActivity;
|
|
import org.sufficientlysecure.keychain.keyimport.HkpKeyserverAddress;
|
|
import org.sufficientlysecure.keychain.keysync.KeyserverSyncManager;
|
|
import org.sufficientlysecure.keychain.network.orbot.OrbotHelper;
|
|
import org.sufficientlysecure.keychain.ui.util.Notify;
|
|
import org.sufficientlysecure.keychain.ui.util.ThemeChanger;
|
|
import org.sufficientlysecure.keychain.util.Preferences;
|
|
import timber.log.Timber;
|
|
|
|
public class SettingsActivity extends AppCompatPreferenceActivity {
|
|
|
|
public static final int REQUEST_CODE_KEYSERVER_PREF = 0x00007005;
|
|
public static final int REQUEST_CODE_SMARTPGP_AUTHORITIES_PREF = 0x00007006;
|
|
private static final int REQUEST_PERMISSION_READ_CONTACTS = 13;
|
|
|
|
private static Preferences sPreferences;
|
|
private ThemeChanger mThemeChanger;
|
|
|
|
@Override
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
sPreferences = Preferences.getPreferences(this);
|
|
mThemeChanger = new ThemeChanger(this);
|
|
mThemeChanger.setThemes(R.style.Theme_Keychain_Light, R.style.Theme_Keychain_Dark);
|
|
mThemeChanger.changeTheme();
|
|
super.onCreate(savedInstanceState);
|
|
|
|
setupToolbar();
|
|
}
|
|
|
|
@Override
|
|
protected void onResume() {
|
|
super.onResume();
|
|
|
|
if (mThemeChanger.changeTheme()) {
|
|
Intent intent = getIntent();
|
|
finish();
|
|
overridePendingTransition(0, 0);
|
|
startActivity(intent);
|
|
overridePendingTransition(0, 0);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hack to get Toolbar in PreferenceActivity. See http://stackoverflow.com/a/26614696
|
|
*/
|
|
private void setupToolbar() {
|
|
ViewGroup root = findViewById(android.R.id.content);
|
|
LinearLayout content = (LinearLayout) root.getChildAt(0);
|
|
LinearLayout toolbarContainer = (LinearLayout) View.inflate(this, R.layout.preference_toolbar, null);
|
|
|
|
root.removeAllViews();
|
|
toolbarContainer.addView(content);
|
|
root.addView(toolbarContainer);
|
|
|
|
Toolbar toolbar = toolbarContainer.findViewById(R.id.toolbar);
|
|
|
|
toolbar.setTitle(R.string.title_preferences);
|
|
// noinspection deprecation, TODO use alternative in API level 21
|
|
toolbar.setNavigationIcon(getResources().getDrawable(R.drawable.ic_arrow_back_white_24dp));
|
|
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
//What to do on back clicked
|
|
finish();
|
|
}
|
|
});
|
|
}
|
|
|
|
public static abstract class PresetPreferenceFragment extends PreferenceFragment {
|
|
@Override
|
|
public void addPreferencesFromResource(int preferencesResId) {
|
|
// so that preferences are written to our preference file, not the default
|
|
Preferences.setPreferenceManagerFileAndMode(this.getPreferenceManager());
|
|
super.addPreferencesFromResource(preferencesResId);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onBuildHeaders(List<Header> target) {
|
|
super.onBuildHeaders(target);
|
|
loadHeadersFromResource(R.xml.preference_headers, target);
|
|
}
|
|
|
|
/**
|
|
* This fragment shows the Cloud Search preferences
|
|
*/
|
|
public static class CloudSearchPrefsFragment extends PresetPreferenceFragment {
|
|
|
|
private PreferenceScreen mKeyServerPreference = null;
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
|
|
// Load the preferences from an XML resource
|
|
addPreferencesFromResource(R.xml.cloud_search_preferences);
|
|
|
|
mKeyServerPreference = (PreferenceScreen) findPreference(Constants.Pref.KEY_SERVERS);
|
|
mKeyServerPreference.setSummary(keyserverSummary(getActivity()));
|
|
|
|
mKeyServerPreference
|
|
.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
|
public boolean onPreferenceClick(Preference preference) {
|
|
Intent intent = new Intent(getActivity(),
|
|
SettingsKeyServerActivity.class);
|
|
intent.putExtra(SettingsKeyServerActivity.EXTRA_KEY_SERVERS,
|
|
sPreferences.getKeyServers());
|
|
startActivityForResult(intent, REQUEST_CODE_KEYSERVER_PREF);
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
switch (requestCode) {
|
|
case REQUEST_CODE_KEYSERVER_PREF: {
|
|
// update preference, in case it changed
|
|
mKeyServerPreference.setSummary(keyserverSummary(getActivity()));
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static String keyserverSummary(Context context) {
|
|
ArrayList<HkpKeyserverAddress> servers = sPreferences.getKeyServers();
|
|
String serverSummary = context.getResources().getQuantityString(
|
|
R.plurals.n_keyservers, servers.size(), servers.size());
|
|
return serverSummary + "; " + context.getString(R.string.label_preferred) + ": " + sPreferences
|
|
.getPreferredKeyserver().getUrl();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This fragment shows the PIN/password preferences
|
|
*/
|
|
public static class PassphrasePrefsFragment extends PresetPreferenceFragment {
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
|
|
// Load the preferences from an XML resource
|
|
addPreferencesFromResource(R.xml.passphrase_preferences);
|
|
}
|
|
}
|
|
|
|
public static class ProxyPrefsFragment extends PresetPreferenceFragment {
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
|
|
new Initializer(this).initialize();
|
|
|
|
}
|
|
|
|
public static class Initializer {
|
|
private SwitchPreference mUseTor;
|
|
private SwitchPreference mUseNormalProxy;
|
|
private EditTextPreference mProxyHost;
|
|
private EditTextPreference mProxyPort;
|
|
private ListPreference mProxyType;
|
|
private PresetPreferenceFragment mFragment;
|
|
|
|
public Initializer(PresetPreferenceFragment fragment) {
|
|
mFragment = fragment;
|
|
}
|
|
|
|
public Preference automaticallyFindPreference(String key) {
|
|
return mFragment.findPreference(key);
|
|
}
|
|
|
|
public void initialize() {
|
|
mFragment.addPreferencesFromResource(R.xml.proxy_preferences);
|
|
|
|
mUseTor = (SwitchPreference) automaticallyFindPreference(Constants.Pref.USE_TOR_PROXY);
|
|
mUseNormalProxy = (SwitchPreference) automaticallyFindPreference(Constants.Pref.USE_NORMAL_PROXY);
|
|
mProxyHost = (EditTextPreference) automaticallyFindPreference(Constants.Pref.PROXY_HOST);
|
|
mProxyPort = (EditTextPreference) automaticallyFindPreference(Constants.Pref.PROXY_PORT);
|
|
mProxyType = (ListPreference) automaticallyFindPreference(Constants.Pref.PROXY_TYPE);
|
|
initializeUseTorPref();
|
|
initializeUseNormalProxyPref();
|
|
initializeEditTextPreferences();
|
|
initializeProxyTypePreference();
|
|
|
|
if (mUseTor.isChecked()) {
|
|
disableNormalProxyPrefs();
|
|
} else if (mUseNormalProxy.isChecked()) {
|
|
disableUseTorPrefs();
|
|
} else {
|
|
disableNormalProxySettings();
|
|
}
|
|
}
|
|
|
|
private void initializeUseTorPref() {
|
|
mUseTor.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
@Override
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
Activity activity = mFragment.getActivity();
|
|
if ((Boolean) newValue) {
|
|
boolean installed = OrbotHelper.isOrbotInstalled(activity);
|
|
if (!installed) {
|
|
Timber.d("Prompting to install Tor");
|
|
OrbotHelper.getPreferenceInstallDialogFragment().show(activity.getFragmentManager(),
|
|
"installDialog");
|
|
// don't let the user check the box until he's installed orbot
|
|
return false;
|
|
} else {
|
|
disableNormalProxyPrefs();
|
|
// let the enable tor box be checked
|
|
return true;
|
|
}
|
|
} else {
|
|
// we're unchecking Tor, so enable other proxy
|
|
enableNormalProxyCheckbox();
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private void initializeUseNormalProxyPref() {
|
|
mUseNormalProxy.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
@Override
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
if ((Boolean) newValue) {
|
|
disableUseTorPrefs();
|
|
enableNormalProxySettings();
|
|
} else {
|
|
enableUseTorPrefs();
|
|
disableNormalProxySettings();
|
|
}
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
private void initializeEditTextPreferences() {
|
|
mProxyHost.setSummary(mProxyHost.getText());
|
|
mProxyPort.setSummary(mProxyPort.getText());
|
|
|
|
mProxyHost.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
@Override
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
Activity activity = mFragment.getActivity();
|
|
if (TextUtils.isEmpty((String) newValue)) {
|
|
Notify.create(
|
|
activity,
|
|
R.string.pref_proxy_host_err_invalid,
|
|
Notify.Style.ERROR
|
|
).show();
|
|
return false;
|
|
} else {
|
|
mProxyHost.setSummary((CharSequence) newValue);
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
|
|
mProxyPort.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
@Override
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
Activity activity = mFragment.getActivity();
|
|
try {
|
|
int port = Integer.parseInt((String) newValue);
|
|
if (port < 0 || port > 65535) {
|
|
Notify.create(
|
|
activity,
|
|
R.string.pref_proxy_port_err_invalid,
|
|
Notify.Style.ERROR
|
|
).show();
|
|
return false;
|
|
}
|
|
// no issues, save port
|
|
mProxyPort.setSummary("" + port);
|
|
return true;
|
|
} catch (NumberFormatException e) {
|
|
Notify.create(
|
|
activity,
|
|
R.string.pref_proxy_port_err_invalid,
|
|
Notify.Style.ERROR
|
|
).show();
|
|
return false;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private void initializeProxyTypePreference() {
|
|
mProxyType.setSummary(mProxyType.getEntry());
|
|
|
|
mProxyType.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
@Override
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
CharSequence entry = mProxyType.getEntries()[mProxyType.findIndexOfValue((String) newValue)];
|
|
mProxyType.setSummary(entry);
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
|
|
private void disableNormalProxyPrefs() {
|
|
mUseNormalProxy.setChecked(false);
|
|
mUseNormalProxy.setEnabled(false);
|
|
disableNormalProxySettings();
|
|
}
|
|
|
|
private void enableNormalProxyCheckbox() {
|
|
mUseNormalProxy.setEnabled(true);
|
|
}
|
|
|
|
private void enableNormalProxySettings() {
|
|
mProxyHost.setEnabled(true);
|
|
mProxyPort.setEnabled(true);
|
|
mProxyType.setEnabled(true);
|
|
}
|
|
|
|
private void disableNormalProxySettings() {
|
|
mProxyHost.setEnabled(false);
|
|
mProxyPort.setEnabled(false);
|
|
mProxyType.setEnabled(false);
|
|
}
|
|
|
|
private void disableUseTorPrefs() {
|
|
mUseTor.setChecked(false);
|
|
mUseTor.setEnabled(false);
|
|
}
|
|
|
|
private void enableUseTorPrefs() {
|
|
mUseTor.setEnabled(true);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This fragment shows the keyserver/wifi-only-sync/contacts sync preferences
|
|
*/
|
|
public static class SyncPrefsFragment extends PresetPreferenceFragment {
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
|
|
// Load the preferences from an XML resource
|
|
addPreferencesFromResource(R.xml.sync_preferences);
|
|
|
|
findPreference(Constants.Pref.SYNC_KEYSERVER).setOnPreferenceChangeListener(
|
|
(preference, newValue) -> {
|
|
return true;
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void onStop() {
|
|
super.onStop();
|
|
KeyserverSyncManager.updateKeyserverSyncScheduleAsync(getActivity(), true);
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
// this needs to be done in onResume since the user can change sync values from Android
|
|
// settings and we need to reflect that change when the user navigates back
|
|
final Account account = KeychainApplication.createAccountIfNecessary(getActivity());
|
|
// for contacts sync
|
|
initializeSyncCheckBox(
|
|
(SwitchPreference) findPreference(Constants.Pref.SYNC_CONTACTS),
|
|
account,
|
|
ContactsContract.AUTHORITY
|
|
);
|
|
}
|
|
|
|
private void initializeSyncCheckBox(final SwitchPreference syncCheckBox,
|
|
final Account account,
|
|
final String authority) {
|
|
// account is null if it could not be created for some reason
|
|
boolean syncEnabled =
|
|
account != null
|
|
&& ContentResolver.getSyncAutomatically(account, authority)
|
|
&& checkContactsPermission(authority);
|
|
syncCheckBox.setChecked(syncEnabled);
|
|
setSummary(syncCheckBox, authority, syncEnabled);
|
|
|
|
syncCheckBox.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
@TargetApi(Build.VERSION_CODES.M)
|
|
@Override
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
boolean syncEnabled = (Boolean) newValue;
|
|
if (syncEnabled) {
|
|
if (checkContactsPermission(authority)) {
|
|
ContentResolver.setSyncAutomatically(account, authority, true);
|
|
setSummary(syncCheckBox, authority, true);
|
|
return true;
|
|
} else {
|
|
requestPermissions(
|
|
new String[]{Manifest.permission.READ_CONTACTS},
|
|
REQUEST_PERMISSION_READ_CONTACTS);
|
|
// don't update preference
|
|
return false;
|
|
}
|
|
} else {
|
|
if (account == null) {
|
|
// if account could not be created for some reason,
|
|
// we can't have our sync
|
|
return false;
|
|
}
|
|
// disable syncs
|
|
ContentResolver.setSyncAutomatically(account, authority, false);
|
|
// cancel any ongoing/pending syncs
|
|
ContentResolver.cancelSync(account, authority);
|
|
setSummary(syncCheckBox, authority, false);
|
|
return true;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
private boolean checkContactsPermission(String authority) {
|
|
if (!ContactsContract.AUTHORITY.equals(authority)) {
|
|
// provides convenience of not using separate checks for keyserver and contact sync
|
|
// in initializeSyncCheckBox
|
|
return true;
|
|
}
|
|
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
|
return true;
|
|
}
|
|
|
|
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_CONTACTS)
|
|
== PackageManager.PERMISSION_GRANTED) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void onRequestPermissionsResult(int requestCode,
|
|
@NonNull String[] permissions,
|
|
@NonNull int[] grantResults) {
|
|
|
|
if (requestCode != REQUEST_PERMISSION_READ_CONTACTS) {
|
|
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
|
return;
|
|
}
|
|
|
|
boolean permissionWasGranted = grantResults.length > 0
|
|
&& grantResults[0] == PackageManager.PERMISSION_GRANTED;
|
|
|
|
if (permissionWasGranted) {
|
|
// permission granted -> enable contact linking
|
|
AccountManager manager = AccountManager.get(getActivity());
|
|
final Account account = manager.getAccountsByType(Constants.ACCOUNT_TYPE)[0];
|
|
SwitchPreference pref = (SwitchPreference) findPreference(Constants.Pref.SYNC_CONTACTS);
|
|
ContentResolver.setSyncAutomatically(account, ContactsContract.AUTHORITY, true);
|
|
setSummary(pref, ContactsContract.AUTHORITY, true);
|
|
pref.setChecked(true);
|
|
}
|
|
}
|
|
|
|
private void setSummary(SwitchPreference syncCheckBox, String authority,
|
|
boolean checked) {
|
|
switch (authority) {
|
|
case Constants.PROVIDER_AUTHORITY: {
|
|
if (checked) {
|
|
syncCheckBox.setSummary(R.string.label_sync_settings_keyserver_summary_on);
|
|
} else {
|
|
syncCheckBox.setSummary(R.string.label_sync_settings_keyserver_summary_off);
|
|
}
|
|
break;
|
|
}
|
|
case ContactsContract.AUTHORITY: {
|
|
if (checked) {
|
|
syncCheckBox.setSummary(R.string.label_sync_settings_contacts_summary_on);
|
|
} else {
|
|
syncCheckBox.setSummary(R.string.label_sync_settings_contacts_summary_off);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* This fragment shows experimental features
|
|
*/
|
|
public static class ExperimentalPrefsFragment extends PresetPreferenceFragment {
|
|
|
|
private PreferenceScreen mSmartPGPAuthoritiesPreference = null;
|
|
|
|
@Override
|
|
public void onCreate(Bundle savedInstanceState) {
|
|
super.onCreate(savedInstanceState);
|
|
|
|
// Load the preferences from an XML resource
|
|
addPreferencesFromResource(R.xml.experimental_preferences);
|
|
|
|
initializeTheme((ListPreference) findPreference(Constants.Pref.THEME));
|
|
|
|
mSmartPGPAuthoritiesPreference = (PreferenceScreen) findPreference(Constants.Pref.EXPERIMENTAL_SMARTPGP_AUTHORITIES);
|
|
|
|
final KeyStore ks = SettingsSmartPGPAuthoritiesActivity.readKeystore(getActivity());
|
|
int size = 0;
|
|
try {
|
|
if (ks != null) {
|
|
size = ks.size();
|
|
}
|
|
} catch (KeyStoreException e) {}
|
|
|
|
mSmartPGPAuthoritiesPreference.setSummary(getActivity().getResources().getQuantityString(R.plurals.n_authorities, size, size));
|
|
|
|
mSmartPGPAuthoritiesPreference
|
|
.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
|
public boolean onPreferenceClick(Preference preference) {
|
|
Intent intent = new Intent(getActivity(),
|
|
SettingsSmartPGPAuthoritiesActivity.class);
|
|
startActivityForResult(intent, REQUEST_CODE_SMARTPGP_AUTHORITIES_PREF);
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
switch (requestCode) {
|
|
case REQUEST_CODE_SMARTPGP_AUTHORITIES_PREF: {
|
|
// update preference, in case it changed
|
|
final KeyStore ks = SettingsSmartPGPAuthoritiesActivity.readKeystore(getActivity());
|
|
int size = 0;
|
|
try {
|
|
if (ks != null) {
|
|
size = ks.size();
|
|
}
|
|
} catch (KeyStoreException e) {}
|
|
|
|
mSmartPGPAuthoritiesPreference.setSummary(getActivity().getResources().getQuantityString(R.plurals.n_authorities, size, size));
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
super.onActivityResult(requestCode, resultCode, data);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void initializeTheme(final ListPreference themePref) {
|
|
themePref.setSummary(themePref.getEntry() + "\n"
|
|
+ themePref.getContext().getString(R.string.label_experimental_settings_theme_summary));
|
|
themePref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
|
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
|
themePref.setSummary(newValue + "\n"
|
|
+ themePref.getContext().getString(R.string.label_experimental_settings_theme_summary));
|
|
|
|
((SettingsActivity) themePref.getContext()).recreate();
|
|
|
|
return true;
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
protected boolean isValidFragment(String fragmentName) {
|
|
return PassphrasePrefsFragment.class.getName().equals(fragmentName)
|
|
|| CloudSearchPrefsFragment.class.getName().equals(fragmentName)
|
|
|| ProxyPrefsFragment.class.getName().equals(fragmentName)
|
|
|| SyncPrefsFragment.class.getName().equals(fragmentName)
|
|
|| ExperimentalPrefsFragment.class.getName().equals(fragmentName)
|
|
|| super.isValidFragment(fragmentName);
|
|
}
|
|
}
|