EditAccountActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import android.app.PendingIntent;
  4import android.content.Intent;
  5import android.os.Bundle;
  6import android.text.Editable;
  7import android.text.TextWatcher;
  8import android.view.View;
  9import android.view.View.OnClickListener;
 10import android.widget.AutoCompleteTextView;
 11import android.widget.Button;
 12import android.widget.CheckBox;
 13import android.widget.CompoundButton;
 14import android.widget.EditText;
 15import android.widget.ImageButton;
 16import android.widget.LinearLayout;
 17import android.widget.CompoundButton.OnCheckedChangeListener;
 18import android.widget.RelativeLayout;
 19import android.widget.TextView;
 20import android.widget.Toast;
 21import eu.siacs.conversations.R;
 22import eu.siacs.conversations.entities.Account;
 23import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
 24import eu.siacs.conversations.ui.adapter.KnownHostsAdapter;
 25import eu.siacs.conversations.utils.UIHelper;
 26import eu.siacs.conversations.utils.Validator;
 27import eu.siacs.conversations.xmpp.XmppConnection.Features;
 28import eu.siacs.conversations.xmpp.pep.Avatar;
 29
 30public class EditAccountActivity extends XmppActivity {
 31
 32	private AutoCompleteTextView mAccountJid;
 33	private EditText mPassword;
 34	private EditText mPasswordConfirm;
 35	private CheckBox mRegisterNew;
 36	private Button mCancelButton;
 37	private Button mSaveButton;
 38
 39	private LinearLayout mStats;
 40	private TextView mServerInfoSm;
 41	private TextView mServerInfoCarbons;
 42	private TextView mServerInfoPep;
 43	private TextView mSessionEst;
 44	private TextView mOtrFingerprint;
 45	private RelativeLayout mOtrFingerprintBox;
 46	private ImageButton mOtrFingerprintToClipboardButton;
 47
 48	private String jidToEdit;
 49	private Account mAccount;
 50
 51	private boolean mFetchingAvatar = false;
 52
 53	private OnClickListener mSaveButtonClickListener = new OnClickListener() {
 54
 55		@Override
 56		public void onClick(View v) {
 57			if (mAccount != null
 58					&& mAccount.getStatus() == Account.STATUS_DISABLED) {
 59				mAccount.setOption(Account.OPTION_DISABLED, false);
 60				xmppConnectionService.updateAccount(mAccount);
 61				return;
 62			}
 63			if (!Validator.isValidJid(mAccountJid.getText().toString())) {
 64				mAccountJid.setError(getString(R.string.invalid_jid));
 65				mAccountJid.requestFocus();
 66				return;
 67			}
 68			boolean registerNewAccount = mRegisterNew.isChecked();
 69			String[] jidParts = mAccountJid.getText().toString().split("@");
 70			String username = jidParts[0];
 71			String server;
 72			if (jidParts.length >= 2) {
 73				server = jidParts[1];
 74			} else {
 75				server = "";
 76			}
 77			String password = mPassword.getText().toString();
 78			String passwordConfirm = mPasswordConfirm.getText().toString();
 79			if (registerNewAccount) {
 80				if (!password.equals(passwordConfirm)) {
 81					mPasswordConfirm
 82							.setError(getString(R.string.passwords_do_not_match));
 83					mPasswordConfirm.requestFocus();
 84					return;
 85				}
 86			}
 87			if (mAccount != null) {
 88				mAccount.setPassword(password);
 89				mAccount.setUsername(username);
 90				mAccount.setServer(server);
 91				mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
 92				xmppConnectionService.updateAccount(mAccount);
 93			} else {
 94				if (xmppConnectionService.findAccountByJid(mAccountJid
 95						.getText().toString()) != null) {
 96					mAccountJid
 97							.setError(getString(R.string.account_already_exists));
 98					mAccountJid.requestFocus();
 99					return;
100				}
101				mAccount = new Account(username, server, password);
102				mAccount.setOption(Account.OPTION_USETLS, true);
103				mAccount.setOption(Account.OPTION_USECOMPRESSION, true);
104				mAccount.setOption(Account.OPTION_REGISTER, registerNewAccount);
105				xmppConnectionService.createAccount(mAccount);
106			}
107			if (jidToEdit != null) {
108				finish();
109			} else {
110				updateSaveButton();
111				updateAccountInformation();
112			}
113
114		}
115	};
116	private OnClickListener mCancelButtonClickListener = new OnClickListener() {
117
118		@Override
119		public void onClick(View v) {
120			finish();
121		}
122	};
123	private OnAccountUpdate mOnAccountUpdateListener = new OnAccountUpdate() {
124
125		@Override
126		public void onAccountUpdate() {
127			runOnUiThread(new Runnable() {
128
129				@Override
130				public void run() {
131					if (mAccount != null
132							&& mAccount.getStatus() != Account.STATUS_ONLINE
133							&& mFetchingAvatar) {
134						startActivity(new Intent(getApplicationContext(),
135								ManageAccountActivity.class));
136						finish();
137					} else if (jidToEdit == null && mAccount != null
138							&& mAccount.getStatus() == Account.STATUS_ONLINE) {
139						if (!mFetchingAvatar) {
140							mFetchingAvatar = true;
141							xmppConnectionService.checkForAvatar(mAccount,
142									mAvatarFetchCallback);
143						}
144					} else {
145						updateSaveButton();
146					}
147					if (mAccount != null) {
148						updateAccountInformation();
149					}
150				}
151			});
152		}
153	};
154	private UiCallback<Avatar> mAvatarFetchCallback = new UiCallback<Avatar>() {
155
156		@Override
157		public void userInputRequried(PendingIntent pi, Avatar avatar) {
158			finishInitialSetup(avatar);
159		}
160
161		@Override
162		public void success(Avatar avatar) {
163			finishInitialSetup(avatar);
164		}
165
166		@Override
167		public void error(int errorCode, Avatar avatar) {
168			finishInitialSetup(avatar);
169		}
170	};
171	private KnownHostsAdapter mKnownHostsAdapter;
172	private TextWatcher mTextWatcher = new TextWatcher() {
173
174		@Override
175		public void onTextChanged(CharSequence s, int start, int before,
176				int count) {
177			updateSaveButton();
178		}
179
180		@Override
181		public void beforeTextChanged(CharSequence s, int start, int count,
182				int after) {
183
184		}
185
186		@Override
187		public void afterTextChanged(Editable s) {
188
189		}
190	};
191
192	protected void finishInitialSetup(final Avatar avatar) {
193		runOnUiThread(new Runnable() {
194
195			@Override
196			public void run() {
197				Intent intent;
198				if (avatar != null) {
199					intent = new Intent(getApplicationContext(),
200							StartConversationActivity.class);
201				} else {
202					intent = new Intent(getApplicationContext(),
203							PublishProfilePictureActivity.class);
204					intent.putExtra("account", mAccount.getJid());
205					intent.putExtra("setup", true);
206				}
207				startActivity(intent);
208				finish();
209			}
210		});
211	}
212
213	protected boolean inputDataDiffersFromAccount() {
214		if (mAccount == null) {
215			return true;
216		} else {
217			return (!mAccount.getJid().equals(mAccountJid.getText().toString()))
218					|| (!mAccount.getPassword().equals(
219							mPassword.getText().toString()) || mAccount
220							.isOptionSet(Account.OPTION_REGISTER) != mRegisterNew
221							.isChecked());
222		}
223	}
224
225	protected void updateSaveButton() {
226		if (mAccount != null
227				&& mAccount.getStatus() == Account.STATUS_CONNECTING) {
228			this.mSaveButton.setEnabled(false);
229			this.mSaveButton.setTextColor(getSecondaryTextColor());
230			this.mSaveButton.setText(R.string.account_status_connecting);
231		} else if (mAccount != null
232				&& mAccount.getStatus() == Account.STATUS_DISABLED) {
233			this.mSaveButton.setEnabled(true);
234			this.mSaveButton.setTextColor(getPrimaryTextColor());
235			this.mSaveButton.setText(R.string.enable);
236		} else {
237			this.mSaveButton.setEnabled(true);
238			this.mSaveButton.setTextColor(getPrimaryTextColor());
239			if (jidToEdit != null) {
240				if (mAccount != null
241						&& mAccount.getStatus() == Account.STATUS_ONLINE) {
242					this.mSaveButton.setText(R.string.save);
243					if (!accountInfoEdited()) {
244						this.mSaveButton.setEnabled(false);
245						this.mSaveButton.setTextColor(getSecondaryTextColor());
246					}
247				} else {
248					this.mSaveButton.setText(R.string.connect);
249				}
250			} else {
251				this.mSaveButton.setText(R.string.next);
252			}
253		}
254	}
255
256	protected boolean accountInfoEdited() {
257		return (!this.mAccount.getJid().equals(
258				this.mAccountJid.getText().toString()))
259				|| (!this.mAccount.getPassword().equals(
260						this.mPassword.getText().toString()));
261	}
262
263	@Override
264	protected void onCreate(Bundle savedInstanceState) {
265		super.onCreate(savedInstanceState);
266		setContentView(R.layout.activity_edit_account);
267		this.mAccountJid = (AutoCompleteTextView) findViewById(R.id.account_jid);
268		this.mAccountJid.addTextChangedListener(this.mTextWatcher);
269		this.mPassword = (EditText) findViewById(R.id.account_password);
270		this.mPassword.addTextChangedListener(this.mTextWatcher);
271		this.mPasswordConfirm = (EditText) findViewById(R.id.account_password_confirm);
272		this.mRegisterNew = (CheckBox) findViewById(R.id.account_register_new);
273		this.mStats = (LinearLayout) findViewById(R.id.stats);
274		this.mSessionEst = (TextView) findViewById(R.id.session_est);
275		this.mServerInfoCarbons = (TextView) findViewById(R.id.server_info_carbons);
276		this.mServerInfoSm = (TextView) findViewById(R.id.server_info_sm);
277		this.mServerInfoPep = (TextView) findViewById(R.id.server_info_pep);
278		this.mOtrFingerprint = (TextView) findViewById(R.id.otr_fingerprint);
279		this.mOtrFingerprintBox = (RelativeLayout) findViewById(R.id.otr_fingerprint_box);
280		this.mOtrFingerprintToClipboardButton = (ImageButton) findViewById(R.id.action_copy_to_clipboard);
281		this.mSaveButton = (Button) findViewById(R.id.save_button);
282		this.mCancelButton = (Button) findViewById(R.id.cancel_button);
283		this.mSaveButton.setOnClickListener(this.mSaveButtonClickListener);
284		this.mCancelButton.setOnClickListener(this.mCancelButtonClickListener);
285		this.mRegisterNew
286				.setOnCheckedChangeListener(new OnCheckedChangeListener() {
287
288					@Override
289					public void onCheckedChanged(CompoundButton buttonView,
290							boolean isChecked) {
291						if (isChecked) {
292							mPasswordConfirm.setVisibility(View.VISIBLE);
293						} else {
294							mPasswordConfirm.setVisibility(View.GONE);
295						}
296						updateSaveButton();
297					}
298				});
299	}
300
301	@Override
302	protected void onStart() {
303		super.onStart();
304		if (getIntent() != null) {
305			this.jidToEdit = getIntent().getStringExtra("jid");
306			if (this.jidToEdit != null) {
307				this.mRegisterNew.setVisibility(View.GONE);
308				getActionBar().setTitle(jidToEdit);
309			} else {
310				getActionBar().setTitle(R.string.action_add_account);
311			}
312		}
313	}
314
315	@Override
316	protected void onStop() {
317		if (xmppConnectionServiceBound) {
318			xmppConnectionService.removeOnAccountListChangedListener();
319		}
320		super.onStop();
321	}
322
323	@Override
324	protected void onBackendConnected() {
325		this.mKnownHostsAdapter = new KnownHostsAdapter(this,
326				android.R.layout.simple_list_item_1,
327				xmppConnectionService.getKnownHosts());
328		this.xmppConnectionService
329				.setOnAccountListChangedListener(this.mOnAccountUpdateListener);
330		if (this.jidToEdit != null) {
331			this.mAccount = xmppConnectionService.findAccountByJid(jidToEdit);
332			updateAccountInformation();
333		} else if (this.xmppConnectionService.getAccounts().size() == 0) {
334			getActionBar().setDisplayHomeAsUpEnabled(false);
335			getActionBar().setDisplayShowHomeEnabled(false);
336			this.mCancelButton.setEnabled(false);
337			this.mCancelButton.setTextColor(getSecondaryTextColor());
338		}
339		this.mAccountJid.setAdapter(this.mKnownHostsAdapter);
340		updateSaveButton();
341	}
342
343	private void updateAccountInformation() {
344		this.mAccountJid.setText(this.mAccount.getJid());
345		this.mPassword.setText(this.mAccount.getPassword());
346		if (this.mAccount.isOptionSet(Account.OPTION_REGISTER)) {
347			this.mRegisterNew.setVisibility(View.VISIBLE);
348			this.mRegisterNew.setChecked(true);
349			this.mPasswordConfirm.setText(this.mAccount.getPassword());
350		} else {
351			this.mRegisterNew.setVisibility(View.GONE);
352			this.mRegisterNew.setChecked(false);
353		}
354		if (this.mAccount.getStatus() == Account.STATUS_ONLINE
355				&& !this.mFetchingAvatar) {
356			this.mStats.setVisibility(View.VISIBLE);
357			this.mSessionEst.setText(UIHelper.readableTimeDifference(
358					getApplicationContext(), this.mAccount.getXmppConnection()
359							.getLastSessionEstablished()));
360			Features features = this.mAccount.getXmppConnection().getFeatures();
361			if (features.carbons()) {
362				this.mServerInfoCarbons.setText(R.string.server_info_available);
363			} else {
364				this.mServerInfoCarbons
365						.setText(R.string.server_info_unavailable);
366			}
367			if (features.sm()) {
368				this.mServerInfoSm.setText(R.string.server_info_available);
369			} else {
370				this.mServerInfoSm.setText(R.string.server_info_unavailable);
371			}
372			if (features.pubsub()) {
373				this.mServerInfoPep.setText(R.string.server_info_available);
374			} else {
375				this.mServerInfoPep.setText(R.string.server_info_unavailable);
376			}
377			final String fingerprint = this.mAccount
378					.getOtrFingerprint(xmppConnectionService);
379			if (fingerprint != null) {
380				this.mOtrFingerprintBox.setVisibility(View.VISIBLE);
381				this.mOtrFingerprint.setText(fingerprint);
382				this.mOtrFingerprintToClipboardButton
383						.setVisibility(View.VISIBLE);
384				this.mOtrFingerprintToClipboardButton
385						.setOnClickListener(new View.OnClickListener() {
386
387							@Override
388							public void onClick(View v) {
389
390								if (copyTextToClipboard(fingerprint,R.string.otr_fingerprint)) {
391									Toast.makeText(
392											EditAccountActivity.this,
393											R.string.toast_message_otr_fingerprint,
394											Toast.LENGTH_SHORT).show();
395								}
396							}
397						});
398			} else {
399				this.mOtrFingerprintBox.setVisibility(View.GONE);
400			}
401		} else {
402			if (this.mAccount.errorStatus()) {
403				this.mAccountJid.setError(getString(this.mAccount
404						.getReadableStatusId()));
405				this.mAccountJid.requestFocus();
406			}
407			this.mStats.setVisibility(View.GONE);
408		}
409	}
410}