EditAccountActivity.java

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