ManageAccountActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import java.util.ArrayList;
  4import java.util.List;
  5
  6import eu.siacs.conversations.R;
  7import eu.siacs.conversations.entities.Account;
  8import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
  9import eu.siacs.conversations.ui.EditAccountDialog.EditAccountListener;
 10import eu.siacs.conversations.xmpp.OnTLSExceptionReceived;
 11import eu.siacs.conversations.xmpp.XmppConnection;
 12import android.app.Activity;
 13import android.app.AlertDialog;
 14import android.content.Context;
 15import android.content.DialogInterface;
 16import android.content.DialogInterface.OnClickListener;
 17import android.content.Intent;
 18import android.os.Bundle;
 19import android.os.SystemClock;
 20import android.view.ActionMode;
 21import android.view.LayoutInflater;
 22import android.view.Menu;
 23import android.view.MenuInflater;
 24import android.view.MenuItem;
 25import android.view.View;
 26import android.view.ViewGroup;
 27import android.widget.AdapterView;
 28import android.widget.AdapterView.OnItemClickListener;
 29import android.widget.AdapterView.OnItemLongClickListener;
 30import android.widget.ArrayAdapter;
 31import android.widget.ListView;
 32import android.widget.TextView;
 33
 34public class ManageAccountActivity extends XmppActivity {
 35
 36	protected boolean isActionMode = false;
 37	protected ActionMode actionMode;
 38	protected Account selectedAccountForActionMode = null;
 39	protected ManageAccountActivity activity = this;
 40
 41	protected boolean firstrun = true;
 42
 43	protected List<Account> accountList = new ArrayList<Account>();
 44	protected ListView accountListView;
 45	protected ArrayAdapter<Account> accountListViewAdapter;
 46	protected OnAccountUpdate accountChanged = new OnAccountUpdate() {
 47
 48		@Override
 49		public void onAccountUpdate() {
 50			accountList.clear();
 51			accountList.addAll(xmppConnectionService.getAccounts());
 52			runOnUiThread(new Runnable() {
 53
 54				@Override
 55				public void run() {
 56					accountListViewAdapter.notifyDataSetChanged();
 57				}
 58			});
 59		}
 60	};
 61
 62	@Override
 63	protected void onCreate(Bundle savedInstanceState) {
 64
 65		super.onCreate(savedInstanceState);
 66
 67		setContentView(R.layout.manage_accounts);
 68
 69		accountListView = (ListView) findViewById(R.id.account_list);
 70		accountListViewAdapter = new ArrayAdapter<Account>(
 71				getApplicationContext(), R.layout.account_row, this.accountList) {
 72			@Override
 73			public View getView(int position, View view, ViewGroup parent) {
 74				Account account = getItem(position);
 75				if (view == null) {
 76					LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 77					view = (View) inflater.inflate(R.layout.account_row, null);
 78				}
 79				((TextView) view.findViewById(R.id.account_jid))
 80						.setText(account.getJid());
 81				TextView statusView = (TextView) view
 82						.findViewById(R.id.account_status);
 83				switch (account.getStatus()) {
 84				case Account.STATUS_DISABLED:
 85					statusView
 86							.setText(getString(R.string.account_status_disabled));
 87					statusView.setTextColor(0xFF1da9da);
 88					break;
 89				case Account.STATUS_ONLINE:
 90					statusView
 91							.setText(getString(R.string.account_status_online));
 92					statusView.setTextColor(0xFF83b600);
 93					break;
 94				case Account.STATUS_CONNECTING:
 95					statusView
 96							.setText(getString(R.string.account_status_connecting));
 97					statusView.setTextColor(0xFF1da9da);
 98					break;
 99				case Account.STATUS_OFFLINE:
100					statusView
101							.setText(getString(R.string.account_status_offline));
102					statusView.setTextColor(0xFFe92727);
103					break;
104				case Account.STATUS_UNAUTHORIZED:
105					statusView
106							.setText(getString(R.string.account_status_unauthorized));
107					statusView.setTextColor(0xFFe92727);
108					break;
109				case Account.STATUS_SERVER_NOT_FOUND:
110					statusView
111							.setText(getString(R.string.account_status_not_found));
112					statusView.setTextColor(0xFFe92727);
113					break;
114				case Account.STATUS_NO_INTERNET:
115					statusView
116							.setText(getString(R.string.account_status_no_internet));
117					statusView.setTextColor(0xFFe92727);
118					break;
119				case Account.STATUS_SERVER_REQUIRES_TLS:
120					statusView
121							.setText(getString(R.string.account_status_requires_tls));
122					statusView.setTextColor(0xFFe92727);
123					break;
124				case Account.STATUS_REGISTRATION_FAILED:
125					statusView
126							.setText(getString(R.string.account_status_regis_fail));
127					statusView.setTextColor(0xFFe92727);
128					break;
129				case Account.STATUS_REGISTRATION_CONFLICT:
130					statusView
131							.setText(getString(R.string.account_status_regis_conflict));
132					statusView.setTextColor(0xFFe92727);
133					break;
134				case Account.STATUS_REGISTRATION_SUCCESSFULL:
135					statusView
136							.setText(getString(R.string.account_status_regis_success));
137					statusView.setTextColor(0xFF83b600);
138					break;
139				case Account.STATUS_REGISTRATION_NOT_SUPPORTED:
140					statusView
141							.setText(getString(R.string.account_status_regis_not_sup));
142					statusView.setTextColor(0xFFe92727);
143					break;
144				default:
145					statusView.setText("");
146					break;
147				}
148
149				return view;
150			}
151		};
152		final XmppActivity activity = this;
153		accountListView.setAdapter(this.accountListViewAdapter);
154		accountListView.setOnItemClickListener(new OnItemClickListener() {
155
156			@Override
157			public void onItemClick(AdapterView<?> arg0, View view,
158					int position, long arg3) {
159				if (!isActionMode) {
160					Account account = accountList.get(position);
161					if (account.getStatus() == Account.STATUS_OFFLINE) {
162						activity.xmppConnectionService.reconnectAccount(
163								accountList.get(position), true);
164					} else if (account.getStatus() == Account.STATUS_ONLINE) {
165						activity.startActivity(new Intent(activity
166								.getApplicationContext(),
167								StartConversationActivity.class));
168					} else if (account.getStatus() != Account.STATUS_DISABLED) {
169						editAccount(account);
170					}
171				} else {
172					selectedAccountForActionMode = accountList.get(position);
173					actionMode.invalidate();
174				}
175			}
176		});
177		accountListView
178				.setOnItemLongClickListener(new OnItemLongClickListener() {
179
180					@Override
181					public boolean onItemLongClick(AdapterView<?> arg0,
182							View view, int position, long arg3) {
183						if (!isActionMode) {
184							accountListView
185									.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
186							accountListView.setItemChecked(position, true);
187							selectedAccountForActionMode = accountList
188									.get(position);
189							actionMode = activity
190									.startActionMode((new ActionMode.Callback() {
191
192										@Override
193										public boolean onPrepareActionMode(
194												ActionMode mode, Menu menu) {
195											if (selectedAccountForActionMode
196													.isOptionSet(Account.OPTION_DISABLED)) {
197												menu.findItem(
198														R.id.mgmt_account_enable)
199														.setVisible(true);
200												menu.findItem(
201														R.id.mgmt_account_disable)
202														.setVisible(false);
203											} else {
204												menu.findItem(
205														R.id.mgmt_account_disable)
206														.setVisible(true);
207												menu.findItem(
208														R.id.mgmt_account_enable)
209														.setVisible(false);
210											}
211											return true;
212										}
213
214										@Override
215										public void onDestroyActionMode(
216												ActionMode mode) {
217											// TODO Auto-generated method stub
218
219										}
220
221										@Override
222										public boolean onCreateActionMode(
223												ActionMode mode, Menu menu) {
224											MenuInflater inflater = mode
225													.getMenuInflater();
226											inflater.inflate(
227													R.menu.manageaccounts_context,
228													menu);
229											return true;
230										}
231
232										@Override
233										public boolean onActionItemClicked(
234												final ActionMode mode,
235												MenuItem item) {
236											if (item.getItemId() == R.id.mgmt_account_edit) {
237												editAccount(selectedAccountForActionMode);
238											} else if (item.getItemId() == R.id.mgmt_account_disable) {
239												selectedAccountForActionMode
240														.setOption(
241																Account.OPTION_DISABLED,
242																true);
243												xmppConnectionService
244														.updateAccount(selectedAccountForActionMode);
245												mode.finish();
246											} else if (item.getItemId() == R.id.mgmt_account_enable) {
247												selectedAccountForActionMode
248														.setOption(
249																Account.OPTION_DISABLED,
250																false);
251												xmppConnectionService
252														.updateAccount(selectedAccountForActionMode);
253												mode.finish();
254											} else if (item.getItemId() == R.id.mgmt_account_delete) {
255												AlertDialog.Builder builder = new AlertDialog.Builder(
256														activity);
257												builder.setTitle(getString(R.string.mgmt_account_are_you_sure));
258												builder.setIconAttribute(android.R.attr.alertDialogIcon);
259												builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text));
260												builder.setPositiveButton(
261														getString(R.string.delete),
262														new OnClickListener() {
263
264															@Override
265															public void onClick(
266																	DialogInterface dialog,
267																	int which) {
268																xmppConnectionService
269																		.deleteAccount(selectedAccountForActionMode);
270																selectedAccountForActionMode = null;
271																mode.finish();
272															}
273														});
274												builder.setNegativeButton(
275														getString(R.string.cancel),
276														null);
277												builder.create().show();
278											} else if (item.getItemId() == R.id.mgmt_account_announce_pgp) {
279												if (activity.hasPgp()) {
280													mode.finish();
281													announcePgp(
282															selectedAccountForActionMode,
283															null);
284												} else {
285													activity.showInstallPgpDialog();
286												}
287											} else if (item.getItemId() == R.id.mgmt_otr_key) {
288												AlertDialog.Builder builder = new AlertDialog.Builder(
289														activity);
290												builder.setTitle("OTR Fingerprint");
291												String fingerprintTxt = selectedAccountForActionMode
292														.getOtrFingerprint(getApplicationContext());
293												View view = (View) getLayoutInflater()
294														.inflate(
295																R.layout.otr_fingerprint,
296																null);
297												if (fingerprintTxt != null) {
298													TextView fingerprint = (TextView) view
299															.findViewById(R.id.otr_fingerprint);
300													TextView noFingerprintView = (TextView) view
301															.findViewById(R.id.otr_no_fingerprint);
302													fingerprint
303															.setText(fingerprintTxt);
304													fingerprint
305															.setVisibility(View.VISIBLE);
306													noFingerprintView
307															.setVisibility(View.GONE);
308												}
309												builder.setView(view);
310												builder.setPositiveButton(
311														getString(R.string.done),
312														null);
313												builder.create().show();
314											} else if (item.getItemId() == R.id.mgmt_account_info) {
315												AlertDialog.Builder builder = new AlertDialog.Builder(
316														activity);
317												builder.setTitle(getString(R.string.account_info));
318												if (selectedAccountForActionMode
319														.getStatus() == Account.STATUS_ONLINE) {
320													XmppConnection xmpp = selectedAccountForActionMode
321															.getXmppConnection();
322													long connectionAge = (SystemClock
323															.elapsedRealtime() - xmpp.lastConnect) / 60000;
324													long sessionAge = (SystemClock
325															.elapsedRealtime() - xmpp.lastSessionStarted) / 60000;
326													long connectionAgeHours = connectionAge / 60;
327													long sessionAgeHours = sessionAge / 60;
328													View view = (View) getLayoutInflater()
329															.inflate(
330																	R.layout.server_info,
331																	null);
332													TextView connection = (TextView) view
333															.findViewById(R.id.connection);
334													TextView session = (TextView) view
335															.findViewById(R.id.session);
336													TextView pcks_sent = (TextView) view
337															.findViewById(R.id.pcks_sent);
338													TextView pcks_received = (TextView) view
339															.findViewById(R.id.pcks_received);
340													TextView carbon = (TextView) view
341															.findViewById(R.id.carbon);
342													TextView stream = (TextView) view
343															.findViewById(R.id.stream);
344													TextView roster = (TextView) view
345															.findViewById(R.id.roster);
346													TextView presences = (TextView) view
347															.findViewById(R.id.number_presences);
348													presences.setText(selectedAccountForActionMode
349															.countPresences()
350															+ "");
351													pcks_received.setText(""
352															+ xmpp.getReceivedStanzas());
353													pcks_sent.setText(""
354															+ xmpp.getSentStanzas());
355													if (connectionAgeHours >= 2) {
356														connection
357																.setText(connectionAgeHours
358																		+ " "
359																		+ getString(R.string.hours));
360													} else {
361														connection
362																.setText(connectionAge
363																		+ " "
364																		+ getString(R.string.mins));
365													}
366													if (xmpp.hasFeatureStreamManagment()) {
367														if (sessionAgeHours >= 2) {
368															session.setText(sessionAgeHours
369																	+ " "
370																	+ getString(R.string.hours));
371														} else {
372															session.setText(sessionAge
373																	+ " "
374																	+ getString(R.string.mins));
375														}
376														stream.setText(getString(R.string.yes));
377													} else {
378														stream.setText(getString(R.string.no));
379														session.setText(connection
380																.getText());
381													}
382													if (xmpp.hasFeaturesCarbon()) {
383														carbon.setText(getString(R.string.yes));
384													} else {
385														carbon.setText(getString(R.string.no));
386													}
387													if (xmpp.hasFeatureRosterManagment()) {
388														roster.setText(getString(R.string.yes));
389													} else {
390														roster.setText(getString(R.string.no));
391													}
392													builder.setView(view);
393												} else {
394													builder.setMessage(getString(R.string.mgmt_account_account_offline));
395												}
396												builder.setPositiveButton(
397														getString(R.string.hide),
398														null);
399												builder.create().show();
400											}
401											return true;
402										}
403
404									}));
405							return true;
406						} else {
407							return false;
408						}
409					}
410				});
411	}
412
413	@Override
414	protected void onStop() {
415		if (xmppConnectionServiceBound) {
416			xmppConnectionService.removeOnAccountListChangedListener();
417		}
418		super.onStop();
419	}
420
421	@Override
422	void onBackendConnected() {
423		xmppConnectionService.setOnAccountListChangedListener(accountChanged);
424		this.accountList.clear();
425		this.accountList.addAll(xmppConnectionService.getAccounts());
426		accountListViewAdapter.notifyDataSetChanged();
427		if ((this.accountList.size() == 0) && (this.firstrun)) {
428			getActionBar().setDisplayHomeAsUpEnabled(false);
429			getActionBar().setHomeButtonEnabled(false);
430			addAccount();
431			this.firstrun = false;
432		}
433	}
434
435	@Override
436	public boolean onCreateOptionsMenu(Menu menu) {
437		getMenuInflater().inflate(R.menu.manageaccounts, menu);
438		return true;
439	}
440
441	@Override
442	public boolean onOptionsItemSelected(MenuItem item) {
443		switch (item.getItemId()) {
444		case R.id.action_add_account:
445			addAccount();
446			break;
447		default:
448			break;
449		}
450		return super.onOptionsItemSelected(item);
451	}
452
453	@Override
454	public boolean onNavigateUp() {
455		if (xmppConnectionService.getConversations().size() == 0) {
456			Intent contactsIntent = new Intent(this, StartConversationActivity.class);
457			contactsIntent.setFlags(
458			// if activity exists in stack, pop the stack and go back to it
459					Intent.FLAG_ACTIVITY_CLEAR_TOP |
460					// otherwise, make a new task for it
461							Intent.FLAG_ACTIVITY_NEW_TASK |
462							// don't use the new activity animation; finish
463							// animation runs instead
464							Intent.FLAG_ACTIVITY_NO_ANIMATION);
465			startActivity(contactsIntent);
466			finish();
467			return true;
468		} else {
469			return super.onNavigateUp();
470		}
471	}
472
473	private void editAccount(Account account) {
474		EditAccountDialog dialog = new EditAccountDialog();
475		dialog.setAccount(account);
476		dialog.setEditAccountListener(new EditAccountListener() {
477
478			@Override
479			public void onAccountEdited(Account account) {
480				xmppConnectionService.updateAccount(account);
481				if (actionMode != null) {
482					actionMode.finish();
483				}
484			}
485		});
486		dialog.show(getFragmentManager(), "edit_account");
487		dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this);
488
489	}
490
491	protected void addAccount() {
492		final Activity activity = this;
493		EditAccountDialog dialog = new EditAccountDialog();
494		dialog.setEditAccountListener(new EditAccountListener() {
495
496			@Override
497			public void onAccountEdited(Account account) {
498				xmppConnectionService.createAccount(account);
499				activity.getActionBar().setDisplayHomeAsUpEnabled(true);
500				activity.getActionBar().setHomeButtonEnabled(true);
501			}
502		});
503		dialog.show(getFragmentManager(), "add_account");
504		dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this);
505	}
506
507	@Override
508	public void onActionModeStarted(ActionMode mode) {
509		super.onActionModeStarted(mode);
510		this.isActionMode = true;
511	}
512
513	@Override
514	public void onActionModeFinished(ActionMode mode) {
515		super.onActionModeFinished(mode);
516		this.isActionMode = false;
517		accountListView.clearChoices();
518		accountListView.requestLayout();
519		accountListView.post(new Runnable() {
520			@Override
521			public void run() {
522				accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
523			}
524		});
525	}
526
527	@Override
528	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
529		super.onActivityResult(requestCode, resultCode, data);
530		if (resultCode == RESULT_OK) {
531			if (requestCode == REQUEST_ANNOUNCE_PGP) {
532				announcePgp(selectedAccountForActionMode, null);
533			}
534		}
535	}
536}