EditAccountActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.app.AlertDialog.Builder;
  4import android.app.PendingIntent;
  5import android.content.DialogInterface;
  6import android.content.Intent;
  7import android.os.Bundle;
  8import android.text.Editable;
  9import android.text.TextWatcher;
 10import android.view.Menu;
 11import android.view.MenuItem;
 12import android.view.View;
 13import android.view.View.OnClickListener;
 14import android.widget.AutoCompleteTextView;
 15import android.widget.Button;
 16import android.widget.CheckBox;
 17import android.widget.CompoundButton;
 18import android.widget.CompoundButton.OnCheckedChangeListener;
 19import android.widget.EditText;
 20import android.widget.ImageButton;
 21import android.widget.ImageView;
 22import android.widget.LinearLayout;
 23import android.widget.RelativeLayout;
 24import android.widget.TableLayout;
 25import android.widget.TextView;
 26import android.widget.Toast;
 27
 28import org.whispersystems.libaxolotl.IdentityKey;
 29
 30import java.util.Set;
 31
 32import eu.siacs.conversations.Config;
 33import eu.siacs.conversations.R;
 34import eu.siacs.conversations.entities.Account;
 35import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 36import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
 37import eu.siacs.conversations.utils.CryptoHelper;
 38import eu.siacs.conversations.utils.UIHelper;
 39import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
 40import eu.siacs.conversations.xmpp.XmppConnection.Features;
 41import eu.siacs.conversations.xmpp.jid.InvalidJidException;
 42import eu.siacs.conversations.xmpp.jid.Jid;
 43import eu.siacs.conversations.xmpp.pep.Avatar;
 44
 45public class EditAccountActivity extends XmppActivity implements OnAccountUpdate, OnKeyStatusUpdated {
 46
 47	private AutoCompleteTextView mAccountJid;
 48	private EditText mPassword;
 49	private EditText mPasswordConfirm;
 50	private CheckBox mRegisterNew;
 51	private Button mCancelButton;
 52	private Button mSaveButton;
 53	private TableLayout mMoreTable;
 54
 55	private LinearLayout mStats;
 56	private TextView mServerInfoSm;
 57	private TextView mServerInfoRosterVersion;
 58	private TextView mServerInfoCarbons;
 59	private TextView mServerInfoMam;
 60	private TextView mServerInfoCSI;
 61	private TextView mServerInfoBlocking;
 62	private TextView mServerInfoPep;
 63	private TextView mSessionEst;
 64	private TextView mOtrFingerprint;
 65	private TextView mAxolotlFingerprint;
 66	private TextView mAccountJidLabel;
 67	private ImageView mAvatar;
 68	private RelativeLayout mOtrFingerprintBox;
 69	private RelativeLayout mAxolotlFingerprintBox;
 70	private ImageButton mOtrFingerprintToClipboardButton;
 71	private ImageButton mAxolotlFingerprintToClipboardButton;
 72	private ImageButton mRegenerateAxolotlKeyButton;
 73	private LinearLayout keys;
 74	private LinearLayout keysCard;
 75
 76	private Jid jidToEdit;
 77	private Account mAccount;
 78	private String messageFingerprint;
 79
 80	private boolean mFetchingAvatar = false;
 81
 82	private final OnClickListener mSaveButtonClickListener = new OnClickListener() {
 83
 84		@Override
 85		public void onClick(final View v) {
 86			if (mAccount != null && mAccount.getStatus() == Account.State.DISABLED && !accountInfoEdited()) {
 87				mAccount.setOption(Account.OPTION_DISABLED, false);
 88				xmppConnectionService.updateAccount(mAccount);
 89				return;
 90			}
 91			final boolean registerNewAccount = mRegisterNew.isChecked() && !Config.DISALLOW_REGISTRATION_IN_UI;
 92			if (Config.DOMAIN_LOCK != null && mAccountJid.getText().toString().contains("@")) {
 93				mAccountJid.setError(getString(R.string.invalid_username));
 94				mAccountJid.requestFocus();
 95				return;
 96			}
 97			final Jid jid;
 98			try {
 99				if (Config.DOMAIN_LOCK != null) {
100					jid = Jid.fromParts(mAccountJid.getText().toString(),Config.DOMAIN_LOCK,null);
101				} else {
102					jid = Jid.fromString(mAccountJid.getText().toString());
103				}
104			} catch (final InvalidJidException e) {
105				if (Config.DOMAIN_LOCK != null) {
106					mAccountJid.setError(getString(R.string.invalid_username));
107				} else {
108					mAccountJid.setError(getString(R.string.invalid_jid));
109				}
110				mAccountJid.requestFocus();
111				return;
112			}
113			if (jid.isDomainJid()) {
114				if (Config.DOMAIN_LOCK != null) {
115					mAccountJid.setError(getString(R.string.invalid_username));
116				} else {
117					mAccountJid.setError(getString(R.string.invalid_jid));
118				}
119				mAccountJid.requestFocus();
120				return;
121			}
122			final String password = mPassword.getText().toString();
123			final String passwordConfirm = mPasswordConfirm.getText().toString();
124			if (registerNewAccount) {
125				if (!password.equals(passwordConfirm)) {
126					mPasswordConfirm.setError(getString(R.string.passwords_do_not_match));
127					mPasswordConfirm.requestFocus();
128					return;
129				}
130			}
131			if (mAccount != null) {
132				try {
133					mAccount.setUsername(jid.hasLocalpart() ? jid.getLocalpart() : "");
134					mAccount.setServer(jid.getDomainpart());
135				} catch (final InvalidJidException ignored) {
136					return;
137				}
138				mAccountJid.setError(null);
139				mPasswordConfirm.setError(null);
140				mAccount.setPassword(password);
141				mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
142				xmppConnectionService.updateAccount(mAccount);
143			} else {
144				if (xmppConnectionService.findAccountByJid(jid) != null) {
145					mAccountJid.setError(getString(R.string.account_already_exists));
146					mAccountJid.requestFocus();
147					return;
148				}
149				mAccount = new Account(jid.toBareJid(), password);
150				mAccount.setOption(Account.OPTION_USETLS, true);
151				mAccount.setOption(Account.OPTION_USECOMPRESSION, true);
152				mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
153				xmppConnectionService.createAccount(mAccount);
154			}
155			if (jidToEdit != null && !mAccount.isOptionSet(Account.OPTION_DISABLED)) {
156				finish();
157			} else {
158				updateSaveButton();
159				updateAccountInformation(true);
160			}
161
162		}
163	};
164	private final OnClickListener mCancelButtonClickListener = new OnClickListener() {
165
166		@Override
167		public void onClick(final View v) {
168			finish();
169		}
170	};
171
172	public void refreshUiReal() {
173		invalidateOptionsMenu();
174		if (mAccount != null
175				&& mAccount.getStatus() != Account.State.ONLINE
176				&& mFetchingAvatar) {
177			startActivity(new Intent(getApplicationContext(),
178						ManageAccountActivity.class));
179			finish();
180		} else if (jidToEdit == null && mAccount != null
181				&& mAccount.getStatus() == Account.State.ONLINE) {
182			if (!mFetchingAvatar) {
183				mFetchingAvatar = true;
184				xmppConnectionService.checkForAvatar(mAccount,
185						mAvatarFetchCallback);
186			}
187		} else {
188			updateSaveButton();
189		}
190		if (mAccount != null) {
191			updateAccountInformation(false);
192		}
193	}
194
195	@Override
196	public void onAccountUpdate() {
197		refreshUi();
198	}
199	private final UiCallback<Avatar> mAvatarFetchCallback = new UiCallback<Avatar>() {
200
201		@Override
202		public void userInputRequried(final PendingIntent pi, final Avatar avatar) {
203			finishInitialSetup(avatar);
204		}
205
206		@Override
207		public void success(final Avatar avatar) {
208			finishInitialSetup(avatar);
209		}
210
211		@Override
212		public void error(final int errorCode, final Avatar avatar) {
213			finishInitialSetup(avatar);
214		}
215	};
216	private final TextWatcher mTextWatcher = new TextWatcher() {
217
218		@Override
219		public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
220			updateSaveButton();
221		}
222
223		@Override
224		public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
225		}
226
227		@Override
228		public void afterTextChanged(final Editable s) {
229
230		}
231	};
232
233	private final OnClickListener mAvatarClickListener = new OnClickListener() {
234		@Override
235		public void onClick(final View view) {
236			if (mAccount != null) {
237				final Intent intent = new Intent(getApplicationContext(),
238						PublishProfilePictureActivity.class);
239				intent.putExtra("account", mAccount.getJid().toBareJid().toString());
240				startActivity(intent);
241			}
242		}
243	};
244
245	protected void finishInitialSetup(final Avatar avatar) {
246		runOnUiThread(new Runnable() {
247
248			@Override
249			public void run() {
250				final Intent intent;
251				if (avatar != null) {
252					intent = new Intent(getApplicationContext(),
253							StartConversationActivity.class);
254					if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) {
255						intent.putExtra("init", true);
256					}
257				} else {
258					intent = new Intent(getApplicationContext(),
259							PublishProfilePictureActivity.class);
260					intent.putExtra("account", mAccount.getJid().toBareJid().toString());
261					intent.putExtra("setup", true);
262				}
263				startActivity(intent);
264				finish();
265			}
266		});
267	}
268
269	protected void updateSaveButton() {
270		if (accountInfoEdited() && jidToEdit != null) {
271			this.mSaveButton.setText(R.string.save);
272			this.mSaveButton.setEnabled(true);
273			this.mSaveButton.setTextColor(getPrimaryTextColor());
274		} else if (mAccount != null && (mAccount.getStatus() == Account.State.CONNECTING || mFetchingAvatar)) {
275			this.mSaveButton.setEnabled(false);
276			this.mSaveButton.setTextColor(getSecondaryTextColor());
277			this.mSaveButton.setText(R.string.account_status_connecting);
278		} else if (mAccount != null && mAccount.getStatus() == Account.State.DISABLED) {
279			this.mSaveButton.setEnabled(true);
280			this.mSaveButton.setTextColor(getPrimaryTextColor());
281			this.mSaveButton.setText(R.string.enable);
282		} else {
283			this.mSaveButton.setEnabled(true);
284			this.mSaveButton.setTextColor(getPrimaryTextColor());
285			if (jidToEdit != null) {
286				if (mAccount != null && mAccount.isOnlineAndConnected()) {
287					this.mSaveButton.setText(R.string.save);
288					if (!accountInfoEdited()) {
289						this.mSaveButton.setEnabled(false);
290						this.mSaveButton.setTextColor(getSecondaryTextColor());
291					}
292				} else {
293					this.mSaveButton.setText(R.string.connect);
294				}
295			} else {
296				this.mSaveButton.setText(R.string.next);
297			}
298		}
299	}
300
301	protected boolean accountInfoEdited() {
302		if (this.mAccount == null) {
303			return false;
304		}
305		final String unmodified;
306		if (Config.DOMAIN_LOCK != null) {
307			unmodified = this.mAccount.getJid().getLocalpart();
308		} else {
309			unmodified = this.mAccount.getJid().toBareJid().toString();
310		}
311		return !unmodified.equals(this.mAccountJid.getText().toString()) ||
312				!this.mAccount.getPassword().equals(this.mPassword.getText().toString());
313	}
314
315	@Override
316	protected String getShareableUri() {
317		if (mAccount!=null) {
318			return mAccount.getShareableUri();
319		} else {
320			return "";
321		}
322	}
323
324	@Override
325	protected void onCreate(final Bundle savedInstanceState) {
326		super.onCreate(savedInstanceState);
327		setContentView(R.layout.activity_edit_account);
328		this.mAccountJid = (AutoCompleteTextView) findViewById(R.id.account_jid);
329		this.mAccountJid.addTextChangedListener(this.mTextWatcher);
330		this.mAccountJidLabel = (TextView) findViewById(R.id.account_jid_label);
331		if (Config.DOMAIN_LOCK != null) {
332			this.mAccountJidLabel.setText(R.string.username);
333			this.mAccountJid.setHint(R.string.username_hint);
334		}
335		this.mPassword = (EditText) findViewById(R.id.account_password);
336		this.mPassword.addTextChangedListener(this.mTextWatcher);
337		this.mPasswordConfirm = (EditText) findViewById(R.id.account_password_confirm);
338		this.mAvatar = (ImageView) findViewById(R.id.avater);
339		this.mAvatar.setOnClickListener(this.mAvatarClickListener);
340		this.mRegisterNew = (CheckBox) findViewById(R.id.account_register_new);
341		this.mStats = (LinearLayout) findViewById(R.id.stats);
342		this.mSessionEst = (TextView) findViewById(R.id.session_est);
343		this.mServerInfoRosterVersion = (TextView) findViewById(R.id.server_info_roster_version);
344		this.mServerInfoCarbons = (TextView) findViewById(R.id.server_info_carbons);
345		this.mServerInfoMam = (TextView) findViewById(R.id.server_info_mam);
346		this.mServerInfoCSI = (TextView) findViewById(R.id.server_info_csi);
347		this.mServerInfoBlocking = (TextView) findViewById(R.id.server_info_blocking);
348		this.mServerInfoSm = (TextView) findViewById(R.id.server_info_sm);
349		this.mServerInfoPep = (TextView) findViewById(R.id.server_info_pep);
350		this.mOtrFingerprint = (TextView) findViewById(R.id.otr_fingerprint);
351		this.mOtrFingerprintBox = (RelativeLayout) findViewById(R.id.otr_fingerprint_box);
352		this.mOtrFingerprintToClipboardButton = (ImageButton) findViewById(R.id.action_copy_to_clipboard);
353		this.mAxolotlFingerprint = (TextView) findViewById(R.id.axolotl_fingerprint);
354		this.mAxolotlFingerprintBox = (RelativeLayout) findViewById(R.id.axolotl_fingerprint_box);
355		this.mAxolotlFingerprintToClipboardButton = (ImageButton) findViewById(R.id.action_copy_axolotl_to_clipboard);
356		this.mRegenerateAxolotlKeyButton = (ImageButton) findViewById(R.id.action_regenerate_axolotl_key);
357		this.keysCard = (LinearLayout) findViewById(R.id.other_device_keys_card);
358		this.keys = (LinearLayout) findViewById(R.id.other_device_keys);
359		this.mSaveButton = (Button) findViewById(R.id.save_button);
360		this.mCancelButton = (Button) findViewById(R.id.cancel_button);
361		this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener);
362		this.mCancelButton.setOnClickListener(this.mCancelButtonClickListener);
363		this.mMoreTable = (TableLayout) findViewById(R.id.server_info_more);
364		final OnCheckedChangeListener OnCheckedShowConfirmPassword = new OnCheckedChangeListener() {
365			@Override
366			public void onCheckedChanged(final CompoundButton buttonView,
367					final boolean isChecked) {
368				if (isChecked) {
369					mPasswordConfirm.setVisibility(View.VISIBLE);
370				} else {
371					mPasswordConfirm.setVisibility(View.GONE);
372				}
373				updateSaveButton();
374			}
375		};
376		this.mRegisterNew.setOnCheckedChangeListener(OnCheckedShowConfirmPassword);
377		if (Config.DISALLOW_REGISTRATION_IN_UI) {
378			this.mRegisterNew.setVisibility(View.GONE);
379		}
380	}
381
382	@Override
383	public boolean onCreateOptionsMenu(final Menu menu) {
384		super.onCreateOptionsMenu(menu);
385		getMenuInflater().inflate(R.menu.editaccount, menu);
386		final MenuItem showQrCode = menu.findItem(R.id.action_show_qr_code);
387		final MenuItem showBlocklist = menu.findItem(R.id.action_show_block_list);
388		final MenuItem showMoreInfo = menu.findItem(R.id.action_server_info_show_more);
389		final MenuItem changePassword = menu.findItem(R.id.action_change_password_on_server);
390		final MenuItem clearDevices = menu.findItem(R.id.action_clear_devices);
391		if (mAccount != null && mAccount.isOnlineAndConnected()) {
392			if (!mAccount.getXmppConnection().getFeatures().blocking()) {
393				showBlocklist.setVisible(false);
394			}
395			if (!mAccount.getXmppConnection().getFeatures().register()) {
396				changePassword.setVisible(false);
397			}
398			Set<Integer> otherDevices = mAccount.getAxolotlService().getOwnDeviceIds();
399			if (otherDevices == null || otherDevices.isEmpty()) {
400				clearDevices.setVisible(false);
401			}
402		} else {
403			showQrCode.setVisible(false);
404			showBlocklist.setVisible(false);
405			showMoreInfo.setVisible(false);
406			changePassword.setVisible(false);
407			clearDevices.setVisible(false);
408		}
409		return true;
410	}
411
412	@Override
413	protected void onStart() {
414		super.onStart();
415		if (getIntent() != null) {
416			try {
417				this.jidToEdit = Jid.fromString(getIntent().getStringExtra("jid"));
418			} catch (final InvalidJidException | NullPointerException ignored) {
419				this.jidToEdit = null;
420			}
421			this.messageFingerprint = getIntent().getStringExtra("fingerprint");
422			if (this.jidToEdit != null) {
423				this.mRegisterNew.setVisibility(View.GONE);
424				if (getActionBar() != null) {
425					getActionBar().setTitle(getString(R.string.account_details));
426				}
427			} else {
428				this.mAvatar.setVisibility(View.GONE);
429				if (getActionBar() != null) {
430					getActionBar().setTitle(R.string.action_add_account);
431				}
432			}
433		}
434	}
435
436	@Override
437	protected void onBackendConnected() {
438		if (this.jidToEdit != null) {
439			this.mAccount = xmppConnectionService.findAccountByJid(jidToEdit);
440			updateAccountInformation(true);
441		} else if (this.xmppConnectionService.getAccounts().size() == 0) {
442			if (getActionBar() != null) {
443				getActionBar().setDisplayHomeAsUpEnabled(false);
444				getActionBar().setDisplayShowHomeEnabled(false);
445				getActionBar().setHomeButtonEnabled(false);
446			}
447			this.mCancelButton.setEnabled(false);
448			this.mCancelButton.setTextColor(getSecondaryTextColor());
449		}
450		if (Config.DOMAIN_LOCK == null) {
451			final KnownHostsAdapter mKnownHostsAdapter = new KnownHostsAdapter(this,
452					android.R.layout.simple_list_item_1,
453					xmppConnectionService.getKnownHosts());
454			this.mAccountJid.setAdapter(mKnownHostsAdapter);
455		}
456		updateSaveButton();
457	}
458
459	@Override
460	public boolean onOptionsItemSelected(final MenuItem item) {
461		switch (item.getItemId()) {
462			case R.id.action_show_block_list:
463				final Intent showBlocklistIntent = new Intent(this, BlocklistActivity.class);
464				showBlocklistIntent.putExtra("account", mAccount.getJid().toString());
465				startActivity(showBlocklistIntent);
466				break;
467			case R.id.action_server_info_show_more:
468				mMoreTable.setVisibility(item.isChecked() ? View.GONE : View.VISIBLE);
469				item.setChecked(!item.isChecked());
470				break;
471			case R.id.action_change_password_on_server:
472				final Intent changePasswordIntent = new Intent(this, ChangePasswordActivity.class);
473				changePasswordIntent.putExtra("account", mAccount.getJid().toString());
474				startActivity(changePasswordIntent);
475				break;
476			case R.id.action_clear_devices:
477				showWipePepDialog();
478				break;
479		}
480		return super.onOptionsItemSelected(item);
481	}
482
483	private void updateAccountInformation(boolean init) {
484		if (init) {
485			if (Config.DOMAIN_LOCK != null) {
486				this.mAccountJid.setText(this.mAccount.getJid().getLocalpart());
487			} else {
488				this.mAccountJid.setText(this.mAccount.getJid().toBareJid().toString());
489			}
490			this.mPassword.setText(this.mAccount.getPassword());
491		}
492		if (this.jidToEdit != null) {
493			this.mAvatar.setVisibility(View.VISIBLE);
494			this.mAvatar.setImageBitmap(avatarService().get(this.mAccount, getPixel(72)));
495		}
496		if (this.mAccount.isOptionSet(Account.OPTION_REGISTER)) {
497			this.mRegisterNew.setVisibility(View.VISIBLE);
498			this.mRegisterNew.setChecked(true);
499			this.mPasswordConfirm.setText(this.mAccount.getPassword());
500		} else {
501			this.mRegisterNew.setVisibility(View.GONE);
502			this.mRegisterNew.setChecked(false);
503		}
504		if (this.mAccount.isOnlineAndConnected() && !this.mFetchingAvatar) {
505			this.mStats.setVisibility(View.VISIBLE);
506			this.mSessionEst.setText(UIHelper.readableTimeDifferenceFull(this, this.mAccount.getXmppConnection()
507						.getLastSessionEstablished()));
508			Features features = this.mAccount.getXmppConnection().getFeatures();
509			if (features.rosterVersioning()) {
510				this.mServerInfoRosterVersion.setText(R.string.server_info_available);
511			} else {
512				this.mServerInfoRosterVersion.setText(R.string.server_info_unavailable);
513			}
514			if (features.carbons()) {
515				this.mServerInfoCarbons.setText(R.string.server_info_available);
516			} else {
517				this.mServerInfoCarbons
518					.setText(R.string.server_info_unavailable);
519			}
520			if (features.mam()) {
521				this.mServerInfoMam.setText(R.string.server_info_available);
522			} else {
523				this.mServerInfoMam.setText(R.string.server_info_unavailable);
524			}
525			if (features.csi()) {
526				this.mServerInfoCSI.setText(R.string.server_info_available);
527			} else {
528				this.mServerInfoCSI.setText(R.string.server_info_unavailable);
529			}
530			if (features.blocking()) {
531				this.mServerInfoBlocking.setText(R.string.server_info_available);
532			} else {
533				this.mServerInfoBlocking.setText(R.string.server_info_unavailable);
534			}
535			if (features.sm()) {
536				this.mServerInfoSm.setText(R.string.server_info_available);
537			} else {
538				this.mServerInfoSm.setText(R.string.server_info_unavailable);
539			}
540			if (features.pep()) {
541				this.mServerInfoPep.setText(R.string.server_info_available);
542			} else {
543				this.mServerInfoPep.setText(R.string.server_info_unavailable);
544			}
545			final String otrFingerprint = this.mAccount.getOtrFingerprint();
546			if (otrFingerprint != null) {
547				this.mOtrFingerprintBox.setVisibility(View.VISIBLE);
548				this.mOtrFingerprint.setText(CryptoHelper.prettifyFingerprint(otrFingerprint));
549				this.mOtrFingerprintToClipboardButton
550					.setVisibility(View.VISIBLE);
551				this.mOtrFingerprintToClipboardButton
552					.setOnClickListener(new View.OnClickListener() {
553
554						@Override
555						public void onClick(final View v) {
556
557							if (copyTextToClipboard(otrFingerprint, R.string.otr_fingerprint)) {
558								Toast.makeText(
559										EditAccountActivity.this,
560										R.string.toast_message_otr_fingerprint,
561										Toast.LENGTH_SHORT).show();
562							}
563						}
564					});
565			} else {
566				this.mOtrFingerprintBox.setVisibility(View.GONE);
567			}
568			final String axolotlFingerprint = this.mAccount.getAxolotlService().getOwnPublicKey().getFingerprint();
569			if (axolotlFingerprint != null) {
570				this.mAxolotlFingerprintBox.setVisibility(View.VISIBLE);
571				this.mAxolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(axolotlFingerprint));
572				this.mAxolotlFingerprintToClipboardButton
573						.setVisibility(View.VISIBLE);
574				this.mAxolotlFingerprintToClipboardButton
575						.setOnClickListener(new View.OnClickListener() {
576
577							@Override
578							public void onClick(final View v) {
579
580								if (copyTextToClipboard(axolotlFingerprint, R.string.omemo_fingerprint)) {
581									Toast.makeText(
582											EditAccountActivity.this,
583											R.string.toast_message_omemo_fingerprint,
584											Toast.LENGTH_SHORT).show();
585								}
586							}
587						});
588				if (Config.SHOW_REGENERATE_AXOLOTL_KEYS_BUTTON) {
589					this.mRegenerateAxolotlKeyButton
590							.setVisibility(View.VISIBLE);
591					this.mRegenerateAxolotlKeyButton
592							.setOnClickListener(new View.OnClickListener() {
593
594								@Override
595								public void onClick(final View v) {
596									showRegenerateAxolotlKeyDialog();
597								}
598							});
599				}
600			} else {
601				this.mAxolotlFingerprintBox.setVisibility(View.GONE);
602			}
603			final IdentityKey ownKey = mAccount.getAxolotlService().getOwnPublicKey();
604			boolean hasKeys = false;
605			keys.removeAllViews();
606			for(final IdentityKey identityKey : xmppConnectionService.databaseBackend.loadIdentityKeys(
607					mAccount, mAccount.getJid().toBareJid().toString())) {
608				if(ownKey.equals(identityKey)) {
609					continue;
610				}
611				boolean highlight = identityKey.getFingerprint().replaceAll("\\s", "").equals(messageFingerprint);
612				hasKeys |= addFingerprintRow(keys, mAccount, identityKey, highlight);
613			}
614			if (hasKeys) {
615				keysCard.setVisibility(View.VISIBLE);
616			} else {
617				keysCard.setVisibility(View.GONE);
618			}
619		} else {
620			if (this.mAccount.errorStatus()) {
621				this.mAccountJid.setError(getString(this.mAccount.getStatus().getReadableId()));
622				if (init || !accountInfoEdited()) {
623					this.mAccountJid.requestFocus();
624				}
625			} else {
626				this.mAccountJid.setError(null);
627			}
628			this.mStats.setVisibility(View.GONE);
629		}
630	}
631
632	public void showRegenerateAxolotlKeyDialog() {
633		Builder builder = new Builder(this);
634		builder.setTitle("Regenerate Key");
635		builder.setIconAttribute(android.R.attr.alertDialogIcon);
636		builder.setMessage("Are you sure you want to regenerate your Identity Key? (This will also wipe all established sessions and contact Identity Keys)");
637		builder.setNegativeButton(getString(R.string.cancel), null);
638		builder.setPositiveButton("Yes",
639				new DialogInterface.OnClickListener() {
640					@Override
641					public void onClick(DialogInterface dialog, int which) {
642						mAccount.getAxolotlService().regenerateKeys();
643					}
644				});
645		builder.create().show();
646	}
647
648	public void showWipePepDialog() {
649		Builder builder = new Builder(this);
650		builder.setTitle(getString(R.string.clear_other_devices));
651		builder.setIconAttribute(android.R.attr.alertDialogIcon);
652		builder.setMessage(getString(R.string.clear_other_devices_desc));
653		builder.setNegativeButton(getString(R.string.cancel), null);
654		builder.setPositiveButton(getString(R.string.accept),
655				new DialogInterface.OnClickListener() {
656					@Override
657					public void onClick(DialogInterface dialog, int which) {
658						mAccount.getAxolotlService().wipeOtherPepDevices();
659					}
660				});
661		builder.create().show();
662	}
663
664	@Override
665	public void onKeyStatusUpdated() {
666		refreshUi();
667	}
668}