ManageAccountActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.app.AlertDialog;
  4import android.content.DialogInterface;
  5import android.content.DialogInterface.OnClickListener;
  6import android.content.Intent;
  7import android.os.Bundle;
  8import android.security.KeyChain;
  9import android.security.KeyChainAliasCallback;
 10import android.util.Log;
 11import android.view.ContextMenu;
 12import android.view.ContextMenu.ContextMenuInfo;
 13import android.view.Menu;
 14import android.view.MenuItem;
 15import android.view.View;
 16import android.widget.AdapterView;
 17import android.widget.AdapterView.AdapterContextMenuInfo;
 18import android.widget.AdapterView.OnItemClickListener;
 19import android.widget.ListView;
 20import android.widget.Toast;
 21
 22import java.util.ArrayList;
 23import java.util.List;
 24
 25import eu.siacs.conversations.Config;
 26import eu.siacs.conversations.R;
 27import eu.siacs.conversations.entities.Account;
 28import eu.siacs.conversations.services.XmppConnectionService;
 29import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 30import eu.siacs.conversations.ui.adapter.AccountAdapter;
 31
 32public class ManageAccountActivity extends XmppActivity implements OnAccountUpdate, KeyChainAliasCallback, XmppConnectionService.OnAccountCreated {
 33
 34	protected Account selectedAccount = null;
 35
 36	protected final List<Account> accountList = new ArrayList<>();
 37	protected ListView accountListView;
 38	protected AccountAdapter mAccountAdapter;
 39
 40	@Override
 41	public void onAccountUpdate() {
 42		refreshUi();
 43	}
 44
 45	@Override
 46	protected void refreshUiReal() {
 47		synchronized (this.accountList) {
 48			accountList.clear();
 49			accountList.addAll(xmppConnectionService.getAccounts());
 50		}
 51		invalidateOptionsMenu();
 52		mAccountAdapter.notifyDataSetChanged();
 53	}
 54
 55	@Override
 56	protected void onCreate(Bundle savedInstanceState) {
 57
 58		super.onCreate(savedInstanceState);
 59
 60		setContentView(R.layout.manage_accounts);
 61
 62		accountListView = (ListView) findViewById(R.id.account_list);
 63		this.mAccountAdapter = new AccountAdapter(this, accountList);
 64		accountListView.setAdapter(this.mAccountAdapter);
 65		accountListView.setOnItemClickListener(new OnItemClickListener() {
 66
 67			@Override
 68			public void onItemClick(AdapterView<?> arg0, View view,
 69									int position, long arg3) {
 70				switchToAccount(accountList.get(position));
 71			}
 72		});
 73		registerForContextMenu(accountListView);
 74	}
 75
 76	@Override
 77	public void onCreateContextMenu(ContextMenu menu, View v,
 78			ContextMenuInfo menuInfo) {
 79		super.onCreateContextMenu(menu, v, menuInfo);
 80		ManageAccountActivity.this.getMenuInflater().inflate(
 81				R.menu.manageaccounts_context, menu);
 82		AdapterView.AdapterContextMenuInfo acmi = (AdapterContextMenuInfo) menuInfo;
 83		this.selectedAccount = accountList.get(acmi.position);
 84		if (this.selectedAccount.isOptionSet(Account.OPTION_DISABLED)) {
 85			menu.findItem(R.id.mgmt_account_disable).setVisible(false);
 86			menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(false);
 87			menu.findItem(R.id.mgmt_account_publish_avatar).setVisible(false);
 88		} else {
 89			menu.findItem(R.id.mgmt_account_enable).setVisible(false);
 90			menu.findItem(R.id.mgmt_account_announce_pgp).setVisible(!Config.HIDE_PGP_IN_UI);
 91		}
 92		menu.setHeaderTitle(this.selectedAccount.getJid().toBareJid().toString());
 93	}
 94
 95	@Override
 96	void onBackendConnected() {
 97		this.accountList.clear();
 98		this.accountList.addAll(xmppConnectionService.getAccounts());
 99		mAccountAdapter.notifyDataSetChanged();
100	}
101
102	@Override
103	public boolean onCreateOptionsMenu(Menu menu) {
104		getMenuInflater().inflate(R.menu.manageaccounts, menu);
105		MenuItem enableAll = menu.findItem(R.id.action_enable_all);
106		if (!accountsLeftToEnable()) {
107			enableAll.setVisible(false);
108		}
109		MenuItem disableAll = menu.findItem(R.id.action_disable_all);
110		if (!accountsLeftToDisable()) {
111			disableAll.setVisible(false);
112		}
113		return true;
114	}
115
116	@Override
117	public boolean onContextItemSelected(MenuItem item) {
118		switch (item.getItemId()) {
119		case R.id.mgmt_account_publish_avatar:
120			publishAvatar(selectedAccount);
121			return true;
122		case R.id.mgmt_account_disable:
123			disableAccount(selectedAccount);
124			return true;
125		case R.id.mgmt_account_enable:
126			enableAccount(selectedAccount);
127			return true;
128		case R.id.mgmt_account_delete:
129			deleteAccount(selectedAccount);
130			return true;
131		case R.id.mgmt_account_announce_pgp:
132			publishOpenPGPPublicKey(selectedAccount);
133			return true;
134		default:
135			return super.onContextItemSelected(item);
136		}
137	}
138
139	@Override
140	public boolean onOptionsItemSelected(MenuItem item) {
141		switch (item.getItemId()) {
142			case R.id.action_add_account:
143				startActivity(new Intent(getApplicationContext(),
144						EditAccountActivity.class));
145				break;
146			case R.id.action_disable_all:
147				disableAllAccounts();
148				break;
149			case R.id.action_enable_all:
150				enableAllAccounts();
151				break;
152			case R.id.action_add_account_from_key:
153				addAccountFromKey();
154				break;
155			default:
156				break;
157		}
158		return super.onOptionsItemSelected(item);
159	}
160
161	@Override
162	public boolean onNavigateUp() {
163		if (xmppConnectionService.getConversations().size() == 0) {
164			Intent contactsIntent = new Intent(this,
165					StartConversationActivity.class);
166			contactsIntent.setFlags(
167			// if activity exists in stack, pop the stack and go back to it
168					Intent.FLAG_ACTIVITY_CLEAR_TOP |
169					// otherwise, make a new task for it
170							Intent.FLAG_ACTIVITY_NEW_TASK |
171							// don't use the new activity animation; finish
172							// animation runs instead
173							Intent.FLAG_ACTIVITY_NO_ANIMATION);
174			startActivity(contactsIntent);
175			finish();
176			return true;
177		} else {
178			return super.onNavigateUp();
179		}
180	}
181
182	public void onClickTglAccountState(Account account, boolean enable) {
183		if (enable) {
184			enableAccount(account);
185		} else {
186			disableAccount(account);
187		}
188	}
189
190	private void addAccountFromKey() {
191		KeyChain.choosePrivateKeyAlias(this, this, null, null, null, -1, null);
192	}
193
194	private void publishAvatar(Account account) {
195		Intent intent = new Intent(getApplicationContext(),
196				PublishProfilePictureActivity.class);
197		intent.putExtra("account", account.getJid().toString());
198		startActivity(intent);
199	}
200
201	private void disableAllAccounts() {
202		List<Account> list = new ArrayList<>();
203		synchronized (this.accountList) {
204			for (Account account : this.accountList) {
205				if (!account.isOptionSet(Account.OPTION_DISABLED)) {
206					list.add(account);
207				}
208			}
209		}
210		for(Account account : list) {
211			disableAccount(account);
212		}
213	}
214
215	private boolean accountsLeftToDisable() {
216		synchronized (this.accountList) {
217			for (Account account : this.accountList) {
218				if (!account.isOptionSet(Account.OPTION_DISABLED)) {
219					return true;
220				}
221			}
222			return false;
223		}
224	}
225
226	private boolean accountsLeftToEnable() {
227		synchronized (this.accountList) {
228			for (Account account : this.accountList) {
229				if (account.isOptionSet(Account.OPTION_DISABLED)) {
230					return true;
231				}
232			}
233			return false;
234		}
235	}
236
237	private void enableAllAccounts() {
238		List<Account> list = new ArrayList<>();
239		synchronized (this.accountList) {
240			for (Account account : this.accountList) {
241				if (account.isOptionSet(Account.OPTION_DISABLED)) {
242					list.add(account);
243				}
244			}
245		}
246		for(Account account : list) {
247			enableAccount(account);
248		}
249	}
250
251	private void disableAccount(Account account) {
252		account.setOption(Account.OPTION_DISABLED, true);
253		xmppConnectionService.updateAccount(account);
254	}
255
256	private void enableAccount(Account account) {
257		account.setOption(Account.OPTION_DISABLED, false);
258		xmppConnectionService.updateAccount(account);
259	}
260
261	private void publishOpenPGPPublicKey(Account account) {
262		if (ManageAccountActivity.this.hasPgp()) {
263			announcePgp(account, null);
264		} else {
265			this.showInstallPgpDialog();
266		}
267	}
268
269	private void deleteAccount(final Account account) {
270		AlertDialog.Builder builder = new AlertDialog.Builder(
271				ManageAccountActivity.this);
272		builder.setTitle(getString(R.string.mgmt_account_are_you_sure));
273		builder.setIconAttribute(android.R.attr.alertDialogIcon);
274		builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text));
275		builder.setPositiveButton(getString(R.string.delete),
276				new OnClickListener() {
277					@Override
278					public void onClick(DialogInterface dialog, int which) {
279						xmppConnectionService.deleteAccount(account);
280						selectedAccount = null;
281					}
282				});
283		builder.setNegativeButton(getString(R.string.cancel), null);
284		builder.create().show();
285	}
286
287	@Override
288	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
289		super.onActivityResult(requestCode, resultCode, data);
290		if (resultCode == RESULT_OK) {
291			if (requestCode == REQUEST_ANNOUNCE_PGP) {
292				announcePgp(selectedAccount, null);
293			}
294		}
295	}
296
297	@Override
298	public void alias(String alias) {
299		if (alias != null) {
300			xmppConnectionService.createAccountFromKey(alias, this);
301		}
302	}
303
304	@Override
305	public void onAccountCreated(Account account) {
306		switchToAccount(account, true);
307	}
308
309	@Override
310	public void informUser(final int r) {
311		runOnUiThread(new Runnable() {
312			@Override
313			public void run() {
314				Toast.makeText(ManageAccountActivity.this,r,Toast.LENGTH_LONG).show();
315			}
316		});
317	}
318}