ManageAccountActivity.java

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