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