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 java.util.Set;
 29
 30import eu.siacs.conversations.Config;
 31import eu.siacs.conversations.R;
 32import eu.siacs.conversations.entities.Account;
 33import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 34import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
 35import eu.siacs.conversations.utils.CryptoHelper;
 36import eu.siacs.conversations.utils.UIHelper;
 37import eu.siacs.conversations.xmpp.OnKeyStatusUpdated;
 38import eu.siacs.conversations.xmpp.XmppConnection.Features;
 39import eu.siacs.conversations.xmpp.jid.InvalidJidException;
 40import eu.siacs.conversations.xmpp.jid.Jid;
 41import eu.siacs.conversations.xmpp.pep.Avatar;
 42
 43public class EditAccountActivity extends XmppActivity implements OnAccountUpdate, OnKeyStatusUpdated {
 44
 45	private AutoCompleteTextView mAccountJid;
 46	private EditText mPassword;
 47	private EditText mPasswordConfirm;
 48	private CheckBox mRegisterNew;
 49	private Button mCancelButton;
 50	private Button mSaveButton;
 51	private TableLayout mMoreTable;
 52
 53	private LinearLayout mStats;
 54	private TextView mServerInfoSm;
 55	private TextView mServerInfoRosterVersion;
 56	private TextView mServerInfoCarbons;
 57	private TextView mServerInfoMam;
 58	private TextView mServerInfoCSI;
 59	private TextView mServerInfoBlocking;
 60	private TextView mServerInfoPep;
 61	private TextView mServerInfoHttpUpload;
 62	private TextView mSessionEst;
 63	private TextView mOtrFingerprint;
 64	private TextView mAxolotlFingerprint;
 65	private TextView mAccountJidLabel;
 66	private ImageView mAvatar;
 67	private RelativeLayout mOtrFingerprintBox;
 68	private RelativeLayout mAxolotlFingerprintBox;
 69	private ImageButton mOtrFingerprintToClipboardButton;
 70	private ImageButton mAxolotlFingerprintToClipboardButton;
 71	private ImageButton mRegenerateAxolotlKeyButton;
 72	private LinearLayout keys;
 73	private LinearLayout keysCard;
 74
 75	private Jid jidToEdit;
 76	private Account mAccount;
 77	private String messageFingerprint;
 78
 79	private boolean mFetchingAvatar = false;
 80
 81	private final OnClickListener mSaveButtonClickListener = new OnClickListener() {
 82
 83		@Override
 84		public void onClick(final View v) {
 85			if (mAccount != null && mAccount.getStatus() == Account.State.DISABLED && !accountInfoEdited()) {
 86				mAccount.setOption(Account.OPTION_DISABLED, false);
 87				xmppConnectionService.updateAccount(mAccount);
 88				return;
 89			}
 90			final boolean registerNewAccount = mRegisterNew.isChecked() && !Config.DISALLOW_REGISTRATION_IN_UI;
 91			if (Config.DOMAIN_LOCK != null && mAccountJid.getText().toString().contains("@")) {
 92				mAccountJid.setError(getString(R.string.invalid_username));
 93				mAccountJid.requestFocus();
 94				return;
 95			}
 96			final Jid jid;
 97			try {
 98				if (Config.DOMAIN_LOCK != null) {
 99					jid = Jid.fromParts(mAccountJid.getText().toString(),Config.DOMAIN_LOCK,null);
100				} else {
101					jid = Jid.fromString(mAccountJid.getText().toString());
102				}
103			} catch (final InvalidJidException e) {
104				if (Config.DOMAIN_LOCK != null) {
105					mAccountJid.setError(getString(R.string.invalid_username));
106				} else {
107					mAccountJid.setError(getString(R.string.invalid_jid));
108				}
109				mAccountJid.requestFocus();
110				return;
111			}
112			if (jid.isDomainJid()) {
113				if (Config.DOMAIN_LOCK != null) {
114					mAccountJid.setError(getString(R.string.invalid_username));
115				} else {
116					mAccountJid.setError(getString(R.string.invalid_jid));
117				}
118				mAccountJid.requestFocus();
119				return;
120			}
121			final String password = mPassword.getText().toString();
122			final String passwordConfirm = mPasswordConfirm.getText().toString();
123			if (registerNewAccount) {
124				if (!password.equals(passwordConfirm)) {
125					mPasswordConfirm.setError(getString(R.string.passwords_do_not_match));
126					mPasswordConfirm.requestFocus();
127					return;
128				}
129			}
130			if (mAccount != null) {
131				try {
132					mAccount.setUsername(jid.hasLocalpart() ? jid.getLocalpart() : "");
133					mAccount.setServer(jid.getDomainpart());
134				} catch (final InvalidJidException ignored) {
135					return;
136				}
137				mAccountJid.setError(null);
138				mPasswordConfirm.setError(null);
139				mAccount.setPassword(password);
140				mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
141				xmppConnectionService.updateAccount(mAccount);
142			} else {
143				if (xmppConnectionService.findAccountByJid(jid) != null) {
144					mAccountJid.setError(getString(R.string.account_already_exists));
145					mAccountJid.requestFocus();
146					return;
147				}
148				mAccount = new Account(jid.toBareJid(), password);
149				mAccount.setOption(Account.OPTION_USETLS, true);
150				mAccount.setOption(Account.OPTION_USECOMPRESSION, true);
151				mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
152				xmppConnectionService.createAccount(mAccount);
153			}
154			if (jidToEdit != null && !mAccount.isOptionSet(Account.OPTION_DISABLED)) {
155				finish();
156			} else {
157				updateSaveButton();
158				updateAccountInformation(true);
159			}
160
161		}
162	};
163	private final OnClickListener mCancelButtonClickListener = new OnClickListener() {
164
165		@Override
166		public void onClick(final View v) {
167			finish();
168		}
169	};
170
171	public void refreshUiReal() {
172		invalidateOptionsMenu();
173		if (mAccount != null
174				&& mAccount.getStatus() != Account.State.ONLINE
175				&& mFetchingAvatar) {
176			startActivity(new Intent(getApplicationContext(),
177						ManageAccountActivity.class));
178			finish();
179		} else if (jidToEdit == null && mAccount != null
180				&& mAccount.getStatus() == Account.State.ONLINE) {
181			if (!mFetchingAvatar) {
182				mFetchingAvatar = true;
183				xmppConnectionService.checkForAvatar(mAccount,
184						mAvatarFetchCallback);
185			}
186		} else {
187			updateSaveButton();
188		}
189		if (mAccount != null) {
190			updateAccountInformation(false);
191		}
192	}
193
194	@Override
195	public void onAccountUpdate() {
196		refreshUi();
197	}
198	private final UiCallback<Avatar> mAvatarFetchCallback = new UiCallback<Avatar>() {
199
200		@Override
201		public void userInputRequried(final PendingIntent pi, final Avatar avatar) {
202			finishInitialSetup(avatar);
203		}
204
205		@Override
206		public void success(final Avatar avatar) {
207			finishInitialSetup(avatar);
208		}
209
210		@Override
211		public void error(final int errorCode, final Avatar avatar) {
212			finishInitialSetup(avatar);
213		}
214	};
215	private final TextWatcher mTextWatcher = new TextWatcher() {
216
217		@Override
218		public void onTextChanged(final CharSequence s, final int start, final int before, final int count) {
219			updateSaveButton();
220		}
221
222		@Override
223		public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {
224		}
225
226		@Override
227		public void afterTextChanged(final Editable s) {
228
229		}
230	};
231
232	private final OnClickListener mAvatarClickListener = new OnClickListener() {
233		@Override
234		public void onClick(final View view) {
235			if (mAccount != null) {
236				final Intent intent = new Intent(getApplicationContext(),
237						PublishProfilePictureActivity.class);
238				intent.putExtra("account", mAccount.getJid().toBareJid().toString());
239				startActivity(intent);
240			}
241		}
242	};
243
244	protected void finishInitialSetup(final Avatar avatar) {
245		runOnUiThread(new Runnable() {
246
247			@Override
248			public void run() {
249				final Intent intent;
250				if (avatar != null) {
251					intent = new Intent(getApplicationContext(),
252							StartConversationActivity.class);
253					if (xmppConnectionService != null && xmppConnectionService.getAccounts().size() == 1) {
254						intent.putExtra("init", true);
255					}
256				} else {
257					intent = new Intent(getApplicationContext(),
258							PublishProfilePictureActivity.class);
259					intent.putExtra("account", mAccount.getJid().toBareJid().toString());
260					intent.putExtra("setup", true);
261				}
262				startActivity(intent);
263				finish();
264			}
265		});
266	}
267
268	protected void updateSaveButton() {
269		if (accountInfoEdited() && jidToEdit != null) {
270			this.mSaveButton.setText(R.string.save);
271			this.mSaveButton.setEnabled(true);
272			this.mSaveButton.setTextColor(getPrimaryTextColor());
273		} else if (mAccount != null && (mAccount.getStatus() == Account.State.CONNECTING || mFetchingAvatar)) {
274			this.mSaveButton.setEnabled(false);
275			this.mSaveButton.setTextColor(getSecondaryTextColor());
276			this.mSaveButton.setText(R.string.account_status_connecting);
277		} else if (mAccount != null && mAccount.getStatus() == Account.State.DISABLED) {
278			this.mSaveButton.setEnabled(true);
279			this.mSaveButton.setTextColor(getPrimaryTextColor());
280			this.mSaveButton.setText(R.string.enable);
281		} else {
282			this.mSaveButton.setEnabled(true);
283			this.mSaveButton.setTextColor(getPrimaryTextColor());
284			if (jidToEdit != null) {
285				if (mAccount != null && mAccount.isOnlineAndConnected()) {
286					this.mSaveButton.setText(R.string.save);
287					if (!accountInfoEdited()) {
288						this.mSaveButton.setEnabled(false);
289						this.mSaveButton.setTextColor(getSecondaryTextColor());
290					}
291				} else {
292					this.mSaveButton.setText(R.string.connect);
293				}
294			} else {
295				this.mSaveButton.setText(R.string.next);
296			}
297		}
298	}
299
300	protected boolean accountInfoEdited() {
301		if (this.mAccount == null) {
302			return false;
303		}
304		final String unmodified;
305		if (Config.DOMAIN_LOCK != null) {
306			unmodified = this.mAccount.getJid().getLocalpart();
307		} else {
308			unmodified = this.mAccount.getJid().toBareJid().toString();
309		}
310		return !unmodified.equals(this.mAccountJid.getText().toString()) ||
311				!this.mAccount.getPassword().equals(this.mPassword.getText().toString());
312	}
313
314	@Override
315	protected String getShareableUri() {
316		if (mAccount!=null) {
317			return mAccount.getShareableUri();
318		} else {
319			return "";
320		}
321	}
322
323	@Override
324	protected void onCreate(final Bundle savedInstanceState) {
325		super.onCreate(savedInstanceState);
326		setContentView(R.layout.activity_edit_account);
327		this.mAccountJid = (AutoCompleteTextView) findViewById(R.id.account_jid);
328		this.mAccountJid.addTextChangedListener(this.mTextWatcher);
329		this.mAccountJidLabel = (TextView) findViewById(R.id.account_jid_label);
330		if (Config.DOMAIN_LOCK != null) {
331			this.mAccountJidLabel.setText(R.string.username);
332			this.mAccountJid.setHint(R.string.username_hint);
333		}
334		this.mPassword = (EditText) findViewById(R.id.account_password);
335		this.mPassword.addTextChangedListener(this.mTextWatcher);
336		this.mPasswordConfirm = (EditText) findViewById(R.id.account_password_confirm);
337		this.mAvatar = (ImageView) findViewById(R.id.avater);
338		this.mAvatar.setOnClickListener(this.mAvatarClickListener);
339		this.mRegisterNew = (CheckBox) findViewById(R.id.account_register_new);
340		this.mStats = (LinearLayout) findViewById(R.id.stats);
341		this.mSessionEst = (TextView) findViewById(R.id.session_est);
342		this.mServerInfoRosterVersion = (TextView) findViewById(R.id.server_info_roster_version);
343		this.mServerInfoCarbons = (TextView) findViewById(R.id.server_info_carbons);
344		this.mServerInfoMam = (TextView) findViewById(R.id.server_info_mam);
345		this.mServerInfoCSI = (TextView) findViewById(R.id.server_info_csi);
346		this.mServerInfoBlocking = (TextView) findViewById(R.id.server_info_blocking);
347		this.mServerInfoSm = (TextView) findViewById(R.id.server_info_sm);
348		this.mServerInfoPep = (TextView) findViewById(R.id.server_info_pep);
349		this.mServerInfoHttpUpload = (TextView) findViewById(R.id.server_info_http_upload);
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			if (features.httpUpload()) {
546				this.mServerInfoHttpUpload.setText(R.string.server_info_available);
547			} else {
548				this.mServerInfoHttpUpload.setText(R.string.server_info_unavailable);
549			}
550			final String otrFingerprint = this.mAccount.getOtrFingerprint();
551			if (otrFingerprint != null) {
552				this.mOtrFingerprintBox.setVisibility(View.VISIBLE);
553				this.mOtrFingerprint.setText(CryptoHelper.prettifyFingerprint(otrFingerprint));
554				this.mOtrFingerprintToClipboardButton
555					.setVisibility(View.VISIBLE);
556				this.mOtrFingerprintToClipboardButton
557					.setOnClickListener(new View.OnClickListener() {
558
559						@Override
560						public void onClick(final View v) {
561
562							if (copyTextToClipboard(otrFingerprint, R.string.otr_fingerprint)) {
563								Toast.makeText(
564										EditAccountActivity.this,
565										R.string.toast_message_otr_fingerprint,
566										Toast.LENGTH_SHORT).show();
567							}
568						}
569					});
570			} else {
571				this.mOtrFingerprintBox.setVisibility(View.GONE);
572			}
573			final String axolotlFingerprint = this.mAccount.getAxolotlService().getOwnFingerprint();
574			if (axolotlFingerprint != null) {
575				this.mAxolotlFingerprintBox.setVisibility(View.VISIBLE);
576				this.mAxolotlFingerprint.setText(CryptoHelper.prettifyFingerprint(axolotlFingerprint));
577				this.mAxolotlFingerprintToClipboardButton
578						.setVisibility(View.VISIBLE);
579				this.mAxolotlFingerprintToClipboardButton
580						.setOnClickListener(new View.OnClickListener() {
581
582							@Override
583							public void onClick(final View v) {
584
585								if (copyTextToClipboard(axolotlFingerprint, R.string.omemo_fingerprint)) {
586									Toast.makeText(
587											EditAccountActivity.this,
588											R.string.toast_message_omemo_fingerprint,
589											Toast.LENGTH_SHORT).show();
590								}
591							}
592						});
593				if (Config.SHOW_REGENERATE_AXOLOTL_KEYS_BUTTON) {
594					this.mRegenerateAxolotlKeyButton
595							.setVisibility(View.VISIBLE);
596					this.mRegenerateAxolotlKeyButton
597							.setOnClickListener(new View.OnClickListener() {
598
599								@Override
600								public void onClick(final View v) {
601									showRegenerateAxolotlKeyDialog();
602								}
603							});
604				}
605			} else {
606				this.mAxolotlFingerprintBox.setVisibility(View.GONE);
607			}
608			final String ownFingerprint = mAccount.getAxolotlService().getOwnFingerprint();
609			boolean hasKeys = false;
610			keys.removeAllViews();
611			for (final String fingerprint : mAccount.getAxolotlService().getFingerprintsForOwnSessions()) {
612				if(ownFingerprint.equals(fingerprint)) {
613					continue;
614				}
615				boolean highlight = fingerprint.equals(messageFingerprint);
616				hasKeys |= addFingerprintRow(keys, mAccount, fingerprint, highlight);
617			}
618			if (hasKeys) {
619				keysCard.setVisibility(View.VISIBLE);
620			} else {
621				keysCard.setVisibility(View.GONE);
622			}
623		} else {
624			if (this.mAccount.errorStatus()) {
625				this.mAccountJid.setError(getString(this.mAccount.getStatus().getReadableId()));
626				if (init || !accountInfoEdited()) {
627					this.mAccountJid.requestFocus();
628				}
629			} else {
630				this.mAccountJid.setError(null);
631			}
632			this.mStats.setVisibility(View.GONE);
633		}
634	}
635
636	public void showRegenerateAxolotlKeyDialog() {
637		Builder builder = new Builder(this);
638		builder.setTitle("Regenerate Key");
639		builder.setIconAttribute(android.R.attr.alertDialogIcon);
640		builder.setMessage("Are you sure you want to regenerate your Identity Key? (This will also wipe all established sessions and contact Identity Keys)");
641		builder.setNegativeButton(getString(R.string.cancel), null);
642		builder.setPositiveButton("Yes",
643				new DialogInterface.OnClickListener() {
644					@Override
645					public void onClick(DialogInterface dialog, int which) {
646						mAccount.getAxolotlService().regenerateKeys();
647					}
648				});
649		builder.create().show();
650	}
651
652	public void showWipePepDialog() {
653		Builder builder = new Builder(this);
654		builder.setTitle(getString(R.string.clear_other_devices));
655		builder.setIconAttribute(android.R.attr.alertDialogIcon);
656		builder.setMessage(getString(R.string.clear_other_devices_desc));
657		builder.setNegativeButton(getString(R.string.cancel), null);
658		builder.setPositiveButton(getString(R.string.accept),
659				new DialogInterface.OnClickListener() {
660					@Override
661					public void onClick(DialogInterface dialog, int which) {
662						mAccount.getAxolotlService().wipeOtherPepDevices();
663					}
664				});
665		builder.create().show();
666	}
667
668	@Override
669	public void onKeyStatusUpdated() {
670		refreshUi();
671	}
672}