SettingsActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.app.AlertDialog;
  4import android.app.FragmentManager;
  5import android.content.DialogInterface;
  6import android.content.Intent;
  7import android.content.SharedPreferences;
  8import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
  9import android.content.pm.PackageManager;
 10import android.os.Build;
 11import android.os.Bundle;
 12import android.preference.ListPreference;
 13import android.preference.Preference;
 14import android.preference.PreferenceCategory;
 15import android.preference.PreferenceManager;
 16import android.preference.PreferenceScreen;
 17import android.widget.Toast;
 18
 19import java.security.KeyStoreException;
 20import java.util.ArrayList;
 21import java.util.Arrays;
 22import java.util.Collections;
 23import java.util.List;
 24import java.util.Locale;
 25
 26import de.duenndns.ssl.MemorizingTrustManager;
 27import eu.siacs.conversations.Config;
 28import eu.siacs.conversations.R;
 29import eu.siacs.conversations.entities.Account;
 30import eu.siacs.conversations.services.ExportLogsService;
 31import eu.siacs.conversations.xmpp.XmppConnection;
 32
 33public class SettingsActivity extends XmppActivity implements
 34		OnSharedPreferenceChangeListener {
 35
 36	public static final int REQUEST_WRITE_LOGS = 0xbf8701;
 37	private SettingsFragment mSettingsFragment;
 38
 39	@Override
 40	protected void onCreate(Bundle savedInstanceState) {
 41		super.onCreate(savedInstanceState);
 42		FragmentManager fm = getFragmentManager();
 43		mSettingsFragment = (SettingsFragment) fm.findFragmentById(android.R.id.content);
 44		if (mSettingsFragment == null || !mSettingsFragment.getClass().equals(SettingsFragment.class)) {
 45			mSettingsFragment = new SettingsFragment();
 46			fm.beginTransaction().replace(android.R.id.content, mSettingsFragment).commit();
 47		}
 48
 49		this.mTheme = findTheme();
 50		setTheme(this.mTheme);
 51
 52		int bgcolor = getPrimaryBackgroundColor();
 53		getWindow().getDecorView().setBackgroundColor(bgcolor);
 54
 55	}
 56
 57	@Override
 58	void onBackendConnected() {
 59
 60	}
 61
 62	@Override
 63	public void onStart() {
 64		super.onStart();
 65		PreferenceManager.getDefaultSharedPreferences(this).registerOnSharedPreferenceChangeListener(this);
 66		ListPreference resources = (ListPreference) mSettingsFragment.findPreference("resource");
 67		if (resources != null) {
 68			ArrayList<CharSequence> entries = new ArrayList<>(Arrays.asList(resources.getEntries()));
 69			if (!entries.contains(Build.MODEL)) {
 70				entries.add(0, Build.MODEL);
 71				resources.setEntries(entries.toArray(new CharSequence[entries.size()]));
 72				resources.setEntryValues(entries.toArray(new CharSequence[entries.size()]));
 73			}
 74		}
 75
 76		if (Config.FORCE_ORBOT) {
 77			PreferenceCategory connectionOptions = (PreferenceCategory) mSettingsFragment.findPreference("connection_options");
 78			PreferenceScreen expert = (PreferenceScreen) mSettingsFragment.findPreference("expert");
 79			if (connectionOptions != null) {
 80				expert.removePreference(connectionOptions);
 81			}
 82		}
 83
 84		final Preference removeCertsPreference = mSettingsFragment.findPreference("remove_trusted_certificates");
 85		removeCertsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
 86			@Override
 87			public boolean onPreferenceClick(Preference preference) {
 88				final MemorizingTrustManager mtm = xmppConnectionService.getMemorizingTrustManager();
 89				final ArrayList<String> aliases = Collections.list(mtm.getCertificates());
 90				if (aliases.size() == 0) {
 91					displayToast(getString(R.string.toast_no_trusted_certs));
 92					return true;
 93				}
 94				final ArrayList selectedItems = new ArrayList<Integer>();
 95				final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(SettingsActivity.this);
 96				dialogBuilder.setTitle(getResources().getString(R.string.dialog_manage_certs_title));
 97				dialogBuilder.setMultiChoiceItems(aliases.toArray(new CharSequence[aliases.size()]), null,
 98						new DialogInterface.OnMultiChoiceClickListener() {
 99							@Override
100							public void onClick(DialogInterface dialog, int indexSelected,
101												boolean isChecked) {
102								if (isChecked) {
103									selectedItems.add(indexSelected);
104								} else if (selectedItems.contains(indexSelected)) {
105									selectedItems.remove(Integer.valueOf(indexSelected));
106								}
107								if (selectedItems.size() > 0)
108									((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
109								else {
110									((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
111								}
112							}
113						});
114
115				dialogBuilder.setPositiveButton(
116						getResources().getString(R.string.dialog_manage_certs_positivebutton), new DialogInterface.OnClickListener() {
117							@Override
118							public void onClick(DialogInterface dialog, int which) {
119								int count = selectedItems.size();
120								if (count > 0) {
121									for (int i = 0; i < count; i++) {
122										try {
123											Integer item = Integer.valueOf(selectedItems.get(i).toString());
124											String alias = aliases.get(item);
125											mtm.deleteCertificate(alias);
126										} catch (KeyStoreException e) {
127											e.printStackTrace();
128											displayToast("Error: " + e.getLocalizedMessage());
129										}
130									}
131									if (xmppConnectionServiceBound) {
132										reconnectAccounts();
133									}
134									displayToast(getResources().getQuantityString(R.plurals.toast_delete_certificates, count, count));
135								}
136							}
137						});
138				dialogBuilder.setNegativeButton(getResources().getString(R.string.dialog_manage_certs_negativebutton), null);
139				AlertDialog removeCertsDialog = dialogBuilder.create();
140				removeCertsDialog.show();
141				removeCertsDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
142				return true;
143			}
144		});
145
146		final Preference exportLogsPreference = mSettingsFragment.findPreference("export_logs");
147		exportLogsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
148			@Override
149			public boolean onPreferenceClick(Preference preference) {
150				hasStoragePermission(REQUEST_WRITE_LOGS);
151				return true;
152			}
153		});
154	}
155
156	@Override
157	public void onStop() {
158		super.onStop();
159		PreferenceManager.getDefaultSharedPreferences(this)
160				.unregisterOnSharedPreferenceChangeListener(this);
161	}
162
163	@Override
164	public void onSharedPreferenceChanged(SharedPreferences preferences, String name) {
165		final List<String> resendPresence = Arrays.asList(
166				"confirm_messages",
167				"xa_on_silent_mode",
168				"away_when_screen_off",
169				"allow_message_correction",
170				"treat_vibrate_as_silent",
171				"manually_change_presence",
172				"last_activity");
173		if (name.equals("resource")) {
174			String resource = preferences.getString("resource", "mobile")
175					.toLowerCase(Locale.US);
176			if (xmppConnectionServiceBound) {
177				for (Account account : xmppConnectionService.getAccounts()) {
178					if (account.setResource(resource)) {
179						if (!account.isOptionSet(Account.OPTION_DISABLED)) {
180							XmppConnection connection = account.getXmppConnection();
181							if (connection != null) {
182								connection.resetStreamId();
183							}
184							xmppConnectionService.reconnectAccountInBackground(account);
185						}
186					}
187				}
188			}
189		} else if (name.equals("keep_foreground_service")) {
190			xmppConnectionService.toggleForegroundService();
191		} else if (resendPresence.contains(name)) {
192			if (xmppConnectionServiceBound) {
193				if (name.equals("away_when_screen_off")
194						|| name.equals("manually_change_presence")) {
195					xmppConnectionService.toggleScreenEventReceiver();
196				}
197				if (name.equals("manually_change_presence") && !noAccountUsesPgp()) {
198					Toast.makeText(this, R.string.republish_pgp_keys, Toast.LENGTH_LONG).show();
199				}
200				xmppConnectionService.refreshAllPresences();
201			}
202		} else if (name.equals("dont_trust_system_cas")) {
203			xmppConnectionService.updateMemorizingTrustmanager();
204			reconnectAccounts();
205		} else if (name.equals("use_tor")) {
206			reconnectAccounts();
207		}
208
209	}
210
211	@Override
212	public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
213		if (grantResults.length > 0)
214			if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
215				if (requestCode == REQUEST_WRITE_LOGS) {
216					getApplicationContext().startService(new Intent(getApplicationContext(), ExportLogsService.class));
217				}
218			} else {
219				Toast.makeText(this, R.string.no_storage_permission, Toast.LENGTH_SHORT).show();
220			}
221	}
222
223	private void displayToast(final String msg) {
224		runOnUiThread(new Runnable() {
225			@Override
226			public void run() {
227				Toast.makeText(SettingsActivity.this, msg, Toast.LENGTH_LONG).show();
228			}
229		});
230	}
231
232	private void reconnectAccounts() {
233		for (Account account : xmppConnectionService.getAccounts()) {
234			if (!account.isOptionSet(Account.OPTION_DISABLED)) {
235				xmppConnectionService.reconnectAccountInBackground(account);
236			}
237		}
238	}
239
240	public void refreshUiReal() {
241		//nothing to do. This Activity doesn't implement any listeners
242	}
243
244}