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