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