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