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.ui.adapter.AccountAdapter;
 11import eu.siacs.conversations.xmpp.XmppConnection;
 12import android.app.Activity;
 13import android.app.AlertDialog;
 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.Menu;
 21import android.view.MenuInflater;
 22import android.view.MenuItem;
 23import android.view.View;
 24import android.widget.AdapterView;
 25import android.widget.AdapterView.OnItemClickListener;
 26import android.widget.AdapterView.OnItemLongClickListener;
 27import android.widget.ListView;
 28import android.widget.TextView;
 29
 30public class ManageAccountActivity extends XmppActivity {
 31
 32	protected boolean isActionMode = false;
 33	protected ActionMode actionMode;
 34	protected Account selectedAccountForActionMode = null;
 35	protected ManageAccountActivity activity = this;
 36
 37	protected boolean firstrun = true;
 38
 39	protected List<Account> accountList = new ArrayList<Account>();
 40	protected ListView accountListView;
 41	protected AccountAdapter mAccountAdapter;
 42	protected OnAccountUpdate accountChanged = new OnAccountUpdate() {
 43
 44		@Override
 45		public void onAccountUpdate() {
 46			accountList.clear();
 47			accountList.addAll(xmppConnectionService.getAccounts());
 48			runOnUiThread(new Runnable() {
 49
 50				@Override
 51				public void run() {
 52					mAccountAdapter.notifyDataSetChanged();
 53				}
 54			});
 55		}
 56	};
 57
 58	protected ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
 59
 60		@Override
 61		public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
 62			if (selectedAccountForActionMode
 63					.isOptionSet(Account.OPTION_DISABLED)) {
 64				menu.findItem(R.id.mgmt_account_enable).setVisible(true);
 65				menu.findItem(R.id.mgmt_account_disable).setVisible(false);
 66			} else {
 67				menu.findItem(R.id.mgmt_account_disable).setVisible(true);
 68				menu.findItem(R.id.mgmt_account_enable).setVisible(false);
 69			}
 70			return true;
 71		}
 72
 73		@Override
 74		public void onDestroyActionMode(ActionMode mode) {
 75			// TODO Auto-generated method stub
 76
 77		}
 78
 79		@Override
 80		public boolean onCreateActionMode(ActionMode mode, Menu menu) {
 81			MenuInflater inflater = mode.getMenuInflater();
 82			inflater.inflate(R.menu.manageaccounts_context, menu);
 83			return true;
 84		}
 85
 86		@Override
 87		public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
 88			if (item.getItemId() == R.id.mgmt_account_edit) {
 89				editAccount(selectedAccountForActionMode);
 90			} else if (item.getItemId() == R.id.mgmt_account_disable) {
 91				selectedAccountForActionMode.setOption(Account.OPTION_DISABLED,
 92						true);
 93				xmppConnectionService
 94						.updateAccount(selectedAccountForActionMode);
 95				mode.finish();
 96			} else if (item.getItemId() == R.id.mgmt_account_enable) {
 97				selectedAccountForActionMode.setOption(Account.OPTION_DISABLED,
 98						false);
 99				xmppConnectionService
100						.updateAccount(selectedAccountForActionMode);
101				mode.finish();
102			} else if (item.getItemId() == R.id.mgmt_account_publish_avatar) {
103				Intent intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class);
104				intent.putExtra("account", selectedAccountForActionMode.getJid());
105				startActivity(intent);
106			} else if (item.getItemId() == R.id.mgmt_account_delete) {
107				AlertDialog.Builder builder = new AlertDialog.Builder(activity);
108				builder.setTitle(getString(R.string.mgmt_account_are_you_sure));
109				builder.setIconAttribute(android.R.attr.alertDialogIcon);
110				builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text));
111				builder.setPositiveButton(getString(R.string.delete),
112						new OnClickListener() {
113
114							@Override
115							public void onClick(DialogInterface dialog,
116									int which) {
117								xmppConnectionService
118										.deleteAccount(selectedAccountForActionMode);
119								selectedAccountForActionMode = null;
120								mode.finish();
121							}
122						});
123				builder.setNegativeButton(getString(R.string.cancel), null);
124				builder.create().show();
125			} else if (item.getItemId() == R.id.mgmt_account_announce_pgp) {
126				if (activity.hasPgp()) {
127					mode.finish();
128					announcePgp(selectedAccountForActionMode, null);
129				} else {
130					activity.showInstallPgpDialog();
131				}
132			} else if (item.getItemId() == R.id.mgmt_otr_key) {
133				AlertDialog.Builder builder = new AlertDialog.Builder(activity);
134				builder.setTitle("OTR Fingerprint");
135				String fingerprintTxt = selectedAccountForActionMode
136						.getOtrFingerprint(getApplicationContext());
137				View view = (View) getLayoutInflater().inflate(
138						R.layout.otr_fingerprint, null);
139				if (fingerprintTxt != null) {
140					TextView fingerprint = (TextView) view
141							.findViewById(R.id.otr_fingerprint);
142					TextView noFingerprintView = (TextView) view
143							.findViewById(R.id.otr_no_fingerprint);
144					fingerprint.setText(fingerprintTxt);
145					fingerprint.setVisibility(View.VISIBLE);
146					noFingerprintView.setVisibility(View.GONE);
147				}
148				builder.setView(view);
149				builder.setPositiveButton(getString(R.string.done), null);
150				builder.create().show();
151			} else if (item.getItemId() == R.id.mgmt_account_info) {
152				AlertDialog.Builder builder = new AlertDialog.Builder(activity);
153				builder.setTitle(getString(R.string.account_info));
154				if (selectedAccountForActionMode.getStatus() == Account.STATUS_ONLINE) {
155					XmppConnection xmpp = selectedAccountForActionMode
156							.getXmppConnection();
157					long connectionAge = (SystemClock.elapsedRealtime() - xmpp.lastConnect) / 60000;
158					long sessionAge = (SystemClock.elapsedRealtime() - xmpp.lastSessionStarted) / 60000;
159					long connectionAgeHours = connectionAge / 60;
160					long sessionAgeHours = sessionAge / 60;
161					View view = (View) getLayoutInflater().inflate(
162							R.layout.server_info, null);
163					TextView connection = (TextView) view
164							.findViewById(R.id.connection);
165					TextView session = (TextView) view
166							.findViewById(R.id.session);
167					TextView pcks_sent = (TextView) view
168							.findViewById(R.id.pcks_sent);
169					TextView pcks_received = (TextView) view
170							.findViewById(R.id.pcks_received);
171					TextView carbon = (TextView) view.findViewById(R.id.carbon);
172					TextView stream = (TextView) view.findViewById(R.id.stream);
173					TextView roster = (TextView) view.findViewById(R.id.roster);
174					TextView presences = (TextView) view
175							.findViewById(R.id.number_presences);
176					presences.setText(selectedAccountForActionMode
177							.countPresences() + "");
178					pcks_received.setText("" + xmpp.getReceivedStanzas());
179					pcks_sent.setText("" + xmpp.getSentStanzas());
180					if (connectionAgeHours >= 2) {
181						connection.setText(connectionAgeHours + " "
182								+ getString(R.string.hours));
183					} else {
184						connection.setText(connectionAge + " "
185								+ getString(R.string.mins));
186					}
187					if (xmpp.hasFeatureStreamManagment()) {
188						if (sessionAgeHours >= 2) {
189							session.setText(sessionAgeHours + " "
190									+ getString(R.string.hours));
191						} else {
192							session.setText(sessionAge + " "
193									+ getString(R.string.mins));
194						}
195						stream.setText(getString(R.string.yes));
196					} else {
197						stream.setText(getString(R.string.no));
198						session.setText(connection.getText());
199					}
200					if (xmpp.hasFeaturesCarbon()) {
201						carbon.setText(getString(R.string.yes));
202					} else {
203						carbon.setText(getString(R.string.no));
204					}
205					if (xmpp.hasFeatureRosterManagment()) {
206						roster.setText(getString(R.string.yes));
207					} else {
208						roster.setText(getString(R.string.no));
209					}
210					builder.setView(view);
211				} else {
212					builder.setMessage(getString(R.string.mgmt_account_account_offline));
213				}
214				builder.setPositiveButton(getString(R.string.hide), null);
215				builder.create().show();
216			}
217			return true;
218		}
219
220	};
221
222	@Override
223	protected void onCreate(Bundle savedInstanceState) {
224
225		super.onCreate(savedInstanceState);
226
227		setContentView(R.layout.manage_accounts);
228
229		accountListView = (ListView) findViewById(R.id.account_list);
230		final XmppActivity activity = this;
231		this.mAccountAdapter = new AccountAdapter(this, accountList);
232		accountListView.setAdapter(this.mAccountAdapter);
233		accountListView.setOnItemClickListener(new OnItemClickListener() {
234
235			@Override
236			public void onItemClick(AdapterView<?> arg0, View view,
237					int position, long arg3) {
238				if (!isActionMode) {
239					Account account = accountList.get(position);
240					if (account.getStatus() == Account.STATUS_OFFLINE) {
241						activity.xmppConnectionService.reconnectAccount(
242								accountList.get(position), true);
243					} else if (account.getStatus() == Account.STATUS_ONLINE) {
244						activity.startActivity(new Intent(activity
245								.getApplicationContext(),
246								StartConversationActivity.class));
247					} else if (account.getStatus() != Account.STATUS_DISABLED) {
248						editAccount(account);
249					}
250				} else {
251					selectedAccountForActionMode = accountList.get(position);
252					actionMode.invalidate();
253				}
254			}
255		});
256		accountListView
257				.setOnItemLongClickListener(new OnItemLongClickListener() {
258
259					@Override
260					public boolean onItemLongClick(AdapterView<?> arg0,
261							View view, int position, long arg3) {
262						if (!isActionMode) {
263							accountListView
264									.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
265							accountListView.setItemChecked(position, true);
266							selectedAccountForActionMode = accountList
267									.get(position);
268							actionMode = activity
269									.startActionMode(mActionModeCallback);
270							return true;
271						} else {
272							return false;
273						}
274					}
275				});
276	}
277
278	@Override
279	protected void onStop() {
280		if (xmppConnectionServiceBound) {
281			xmppConnectionService.removeOnAccountListChangedListener();
282		}
283		super.onStop();
284	}
285
286	@Override
287	void onBackendConnected() {
288		xmppConnectionService.setOnAccountListChangedListener(accountChanged);
289		this.accountList.clear();
290		this.accountList.addAll(xmppConnectionService.getAccounts());
291		mAccountAdapter.notifyDataSetChanged();
292		if ((this.accountList.size() == 0) && (this.firstrun)) {
293			getActionBar().setDisplayHomeAsUpEnabled(false);
294			getActionBar().setHomeButtonEnabled(false);
295			addAccount();
296			this.firstrun = false;
297		}
298	}
299
300	@Override
301	public boolean onCreateOptionsMenu(Menu menu) {
302		getMenuInflater().inflate(R.menu.manageaccounts, menu);
303		return true;
304	}
305
306	@Override
307	public boolean onOptionsItemSelected(MenuItem item) {
308		switch (item.getItemId()) {
309		case R.id.action_add_account:
310			addAccount();
311			break;
312		default:
313			break;
314		}
315		return super.onOptionsItemSelected(item);
316	}
317
318	@Override
319	public boolean onNavigateUp() {
320		if (xmppConnectionService.getConversations().size() == 0) {
321			Intent contactsIntent = new Intent(this,
322					StartConversationActivity.class);
323			contactsIntent.setFlags(
324			// if activity exists in stack, pop the stack and go back to it
325					Intent.FLAG_ACTIVITY_CLEAR_TOP |
326					// otherwise, make a new task for it
327							Intent.FLAG_ACTIVITY_NEW_TASK |
328							// don't use the new activity animation; finish
329							// animation runs instead
330							Intent.FLAG_ACTIVITY_NO_ANIMATION);
331			startActivity(contactsIntent);
332			finish();
333			return true;
334		} else {
335			return super.onNavigateUp();
336		}
337	}
338
339	private void editAccount(Account account) {
340		EditAccountDialog dialog = new EditAccountDialog();
341		dialog.setAccount(account);
342		dialog.setEditAccountListener(new EditAccountListener() {
343
344			@Override
345			public void onAccountEdited(Account account) {
346				xmppConnectionService.updateAccount(account);
347				if (actionMode != null) {
348					actionMode.finish();
349				}
350			}
351		});
352		dialog.show(getFragmentManager(), "edit_account");
353		dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this);
354
355	}
356
357	protected void addAccount() {
358		final Activity activity = this;
359		EditAccountDialog dialog = new EditAccountDialog();
360		dialog.setEditAccountListener(new EditAccountListener() {
361
362			@Override
363			public void onAccountEdited(Account account) {
364				xmppConnectionService.createAccount(account);
365				activity.getActionBar().setDisplayHomeAsUpEnabled(true);
366				activity.getActionBar().setHomeButtonEnabled(true);
367			}
368		});
369		dialog.show(getFragmentManager(), "add_account");
370		dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this);
371	}
372
373	@Override
374	public void onActionModeStarted(ActionMode mode) {
375		super.onActionModeStarted(mode);
376		this.isActionMode = true;
377	}
378
379	@Override
380	public void onActionModeFinished(ActionMode mode) {
381		super.onActionModeFinished(mode);
382		this.isActionMode = false;
383		accountListView.clearChoices();
384		accountListView.requestLayout();
385		accountListView.post(new Runnable() {
386			@Override
387			public void run() {
388				accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
389			}
390		});
391	}
392
393	@Override
394	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
395		super.onActivityResult(requestCode, resultCode, data);
396		if (resultCode == RESULT_OK) {
397			if (requestCode == REQUEST_ANNOUNCE_PGP) {
398				announcePgp(selectedAccountForActionMode, null);
399			}
400		}
401	}
402}