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