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