1package eu.siacs.conversations.ui;
2
3import java.util.ArrayList;
4import java.util.List;
5
6import eu.siacs.conversations.R;
7import eu.siacs.conversations.entities.Account;
8import eu.siacs.conversations.services.XmppConnectionService.OnAccountUpdate;
9import eu.siacs.conversations.ui.EditAccountDialog.EditAccountListener;
10import eu.siacs.conversations.ui.adapter.AccountAdapter;
11import eu.siacs.conversations.xmpp.XmppConnection;
12import android.app.Activity;
13import android.app.AlertDialog;
14import android.content.DialogInterface;
15import android.content.DialogInterface.OnClickListener;
16import android.content.Intent;
17import android.os.Bundle;
18import android.os.SystemClock;
19import android.view.ActionMode;
20import android.view.Menu;
21import android.view.MenuInflater;
22import android.view.MenuItem;
23import android.view.View;
24import android.widget.AdapterView;
25import android.widget.AdapterView.OnItemClickListener;
26import android.widget.AdapterView.OnItemLongClickListener;
27import android.widget.ListView;
28import android.widget.TextView;
29
30public class ManageAccountActivity extends XmppActivity {
31
32 protected boolean isActionMode = false;
33 protected ActionMode actionMode;
34 protected Account selectedAccountForActionMode = null;
35 protected ManageAccountActivity activity = this;
36
37 protected boolean firstrun = true;
38
39 protected List<Account> accountList = new ArrayList<Account>();
40 protected ListView accountListView;
41 protected AccountAdapter mAccountAdapter;
42 protected OnAccountUpdate accountChanged = new OnAccountUpdate() {
43
44 @Override
45 public void onAccountUpdate() {
46 accountList.clear();
47 accountList.addAll(xmppConnectionService.getAccounts());
48 runOnUiThread(new Runnable() {
49
50 @Override
51 public void run() {
52 mAccountAdapter.notifyDataSetChanged();
53 }
54 });
55 }
56 };
57
58 protected ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
59
60 @Override
61 public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
62 if (selectedAccountForActionMode
63 .isOptionSet(Account.OPTION_DISABLED)) {
64 menu.findItem(R.id.mgmt_account_enable).setVisible(true);
65 menu.findItem(R.id.mgmt_account_disable).setVisible(false);
66 } else {
67 menu.findItem(R.id.mgmt_account_disable).setVisible(true);
68 menu.findItem(R.id.mgmt_account_enable).setVisible(false);
69 }
70 return true;
71 }
72
73 @Override
74 public void onDestroyActionMode(ActionMode mode) {
75 // TODO Auto-generated method stub
76
77 }
78
79 @Override
80 public boolean onCreateActionMode(ActionMode mode, Menu menu) {
81 MenuInflater inflater = mode.getMenuInflater();
82 inflater.inflate(R.menu.manageaccounts_context, menu);
83 return true;
84 }
85
86 @Override
87 public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
88 if (item.getItemId() == R.id.mgmt_account_edit) {
89 editAccount(selectedAccountForActionMode);
90 } else if (item.getItemId() == R.id.mgmt_account_disable) {
91 selectedAccountForActionMode.setOption(Account.OPTION_DISABLED,
92 true);
93 xmppConnectionService
94 .updateAccount(selectedAccountForActionMode);
95 mode.finish();
96 } else if (item.getItemId() == R.id.mgmt_account_enable) {
97 selectedAccountForActionMode.setOption(Account.OPTION_DISABLED,
98 false);
99 xmppConnectionService
100 .updateAccount(selectedAccountForActionMode);
101 mode.finish();
102 } else if (item.getItemId() == R.id.mgmt_account_publish_avatar) {
103 startActivity(new Intent(getApplicationContext(), PublishProfilePictureActivity.class));
104 } else if (item.getItemId() == R.id.mgmt_account_delete) {
105 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
106 builder.setTitle(getString(R.string.mgmt_account_are_you_sure));
107 builder.setIconAttribute(android.R.attr.alertDialogIcon);
108 builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text));
109 builder.setPositiveButton(getString(R.string.delete),
110 new OnClickListener() {
111
112 @Override
113 public void onClick(DialogInterface dialog,
114 int which) {
115 xmppConnectionService
116 .deleteAccount(selectedAccountForActionMode);
117 selectedAccountForActionMode = null;
118 mode.finish();
119 }
120 });
121 builder.setNegativeButton(getString(R.string.cancel), null);
122 builder.create().show();
123 } else if (item.getItemId() == R.id.mgmt_account_announce_pgp) {
124 if (activity.hasPgp()) {
125 mode.finish();
126 announcePgp(selectedAccountForActionMode, null);
127 } else {
128 activity.showInstallPgpDialog();
129 }
130 } else if (item.getItemId() == R.id.mgmt_otr_key) {
131 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
132 builder.setTitle("OTR Fingerprint");
133 String fingerprintTxt = selectedAccountForActionMode
134 .getOtrFingerprint(getApplicationContext());
135 View view = (View) getLayoutInflater().inflate(
136 R.layout.otr_fingerprint, null);
137 if (fingerprintTxt != null) {
138 TextView fingerprint = (TextView) view
139 .findViewById(R.id.otr_fingerprint);
140 TextView noFingerprintView = (TextView) view
141 .findViewById(R.id.otr_no_fingerprint);
142 fingerprint.setText(fingerprintTxt);
143 fingerprint.setVisibility(View.VISIBLE);
144 noFingerprintView.setVisibility(View.GONE);
145 }
146 builder.setView(view);
147 builder.setPositiveButton(getString(R.string.done), null);
148 builder.create().show();
149 } else if (item.getItemId() == R.id.mgmt_account_info) {
150 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
151 builder.setTitle(getString(R.string.account_info));
152 if (selectedAccountForActionMode.getStatus() == Account.STATUS_ONLINE) {
153 XmppConnection xmpp = selectedAccountForActionMode
154 .getXmppConnection();
155 long connectionAge = (SystemClock.elapsedRealtime() - xmpp.lastConnect) / 60000;
156 long sessionAge = (SystemClock.elapsedRealtime() - xmpp.lastSessionStarted) / 60000;
157 long connectionAgeHours = connectionAge / 60;
158 long sessionAgeHours = sessionAge / 60;
159 View view = (View) getLayoutInflater().inflate(
160 R.layout.server_info, null);
161 TextView connection = (TextView) view
162 .findViewById(R.id.connection);
163 TextView session = (TextView) view
164 .findViewById(R.id.session);
165 TextView pcks_sent = (TextView) view
166 .findViewById(R.id.pcks_sent);
167 TextView pcks_received = (TextView) view
168 .findViewById(R.id.pcks_received);
169 TextView carbon = (TextView) view.findViewById(R.id.carbon);
170 TextView stream = (TextView) view.findViewById(R.id.stream);
171 TextView roster = (TextView) view.findViewById(R.id.roster);
172 TextView presences = (TextView) view
173 .findViewById(R.id.number_presences);
174 presences.setText(selectedAccountForActionMode
175 .countPresences() + "");
176 pcks_received.setText("" + xmpp.getReceivedStanzas());
177 pcks_sent.setText("" + xmpp.getSentStanzas());
178 if (connectionAgeHours >= 2) {
179 connection.setText(connectionAgeHours + " "
180 + getString(R.string.hours));
181 } else {
182 connection.setText(connectionAge + " "
183 + getString(R.string.mins));
184 }
185 if (xmpp.hasFeatureStreamManagment()) {
186 if (sessionAgeHours >= 2) {
187 session.setText(sessionAgeHours + " "
188 + getString(R.string.hours));
189 } else {
190 session.setText(sessionAge + " "
191 + getString(R.string.mins));
192 }
193 stream.setText(getString(R.string.yes));
194 } else {
195 stream.setText(getString(R.string.no));
196 session.setText(connection.getText());
197 }
198 if (xmpp.hasFeaturesCarbon()) {
199 carbon.setText(getString(R.string.yes));
200 } else {
201 carbon.setText(getString(R.string.no));
202 }
203 if (xmpp.hasFeatureRosterManagment()) {
204 roster.setText(getString(R.string.yes));
205 } else {
206 roster.setText(getString(R.string.no));
207 }
208 builder.setView(view);
209 } else {
210 builder.setMessage(getString(R.string.mgmt_account_account_offline));
211 }
212 builder.setPositiveButton(getString(R.string.hide), null);
213 builder.create().show();
214 }
215 return true;
216 }
217
218 };
219
220 @Override
221 protected void onCreate(Bundle savedInstanceState) {
222
223 super.onCreate(savedInstanceState);
224
225 setContentView(R.layout.manage_accounts);
226
227 accountListView = (ListView) findViewById(R.id.account_list);
228 final XmppActivity activity = this;
229 this.mAccountAdapter = new AccountAdapter(this, accountList);
230 accountListView.setAdapter(this.mAccountAdapter);
231 accountListView.setOnItemClickListener(new OnItemClickListener() {
232
233 @Override
234 public void onItemClick(AdapterView<?> arg0, View view,
235 int position, long arg3) {
236 if (!isActionMode) {
237 Account account = accountList.get(position);
238 if (account.getStatus() == Account.STATUS_OFFLINE) {
239 activity.xmppConnectionService.reconnectAccount(
240 accountList.get(position), true);
241 } else if (account.getStatus() == Account.STATUS_ONLINE) {
242 activity.startActivity(new Intent(activity
243 .getApplicationContext(),
244 StartConversationActivity.class));
245 } else if (account.getStatus() != Account.STATUS_DISABLED) {
246 editAccount(account);
247 }
248 } else {
249 selectedAccountForActionMode = accountList.get(position);
250 actionMode.invalidate();
251 }
252 }
253 });
254 accountListView
255 .setOnItemLongClickListener(new OnItemLongClickListener() {
256
257 @Override
258 public boolean onItemLongClick(AdapterView<?> arg0,
259 View view, int position, long arg3) {
260 if (!isActionMode) {
261 accountListView
262 .setChoiceMode(ListView.CHOICE_MODE_SINGLE);
263 accountListView.setItemChecked(position, true);
264 selectedAccountForActionMode = accountList
265 .get(position);
266 actionMode = activity
267 .startActionMode(mActionModeCallback);
268 return true;
269 } else {
270 return false;
271 }
272 }
273 });
274 }
275
276 @Override
277 protected void onStop() {
278 if (xmppConnectionServiceBound) {
279 xmppConnectionService.removeOnAccountListChangedListener();
280 }
281 super.onStop();
282 }
283
284 @Override
285 void onBackendConnected() {
286 xmppConnectionService.setOnAccountListChangedListener(accountChanged);
287 this.accountList.clear();
288 this.accountList.addAll(xmppConnectionService.getAccounts());
289 mAccountAdapter.notifyDataSetChanged();
290 if ((this.accountList.size() == 0) && (this.firstrun)) {
291 getActionBar().setDisplayHomeAsUpEnabled(false);
292 getActionBar().setHomeButtonEnabled(false);
293 addAccount();
294 this.firstrun = false;
295 }
296 }
297
298 @Override
299 public boolean onCreateOptionsMenu(Menu menu) {
300 getMenuInflater().inflate(R.menu.manageaccounts, menu);
301 return true;
302 }
303
304 @Override
305 public boolean onOptionsItemSelected(MenuItem item) {
306 switch (item.getItemId()) {
307 case R.id.action_add_account:
308 addAccount();
309 break;
310 default:
311 break;
312 }
313 return super.onOptionsItemSelected(item);
314 }
315
316 @Override
317 public boolean onNavigateUp() {
318 if (xmppConnectionService.getConversations().size() == 0) {
319 Intent contactsIntent = new Intent(this,
320 StartConversationActivity.class);
321 contactsIntent.setFlags(
322 // if activity exists in stack, pop the stack and go back to it
323 Intent.FLAG_ACTIVITY_CLEAR_TOP |
324 // otherwise, make a new task for it
325 Intent.FLAG_ACTIVITY_NEW_TASK |
326 // don't use the new activity animation; finish
327 // animation runs instead
328 Intent.FLAG_ACTIVITY_NO_ANIMATION);
329 startActivity(contactsIntent);
330 finish();
331 return true;
332 } else {
333 return super.onNavigateUp();
334 }
335 }
336
337 private void editAccount(Account account) {
338 EditAccountDialog dialog = new EditAccountDialog();
339 dialog.setAccount(account);
340 dialog.setEditAccountListener(new EditAccountListener() {
341
342 @Override
343 public void onAccountEdited(Account account) {
344 xmppConnectionService.updateAccount(account);
345 if (actionMode != null) {
346 actionMode.finish();
347 }
348 }
349 });
350 dialog.show(getFragmentManager(), "edit_account");
351 dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this);
352
353 }
354
355 protected void addAccount() {
356 final Activity activity = this;
357 EditAccountDialog dialog = new EditAccountDialog();
358 dialog.setEditAccountListener(new EditAccountListener() {
359
360 @Override
361 public void onAccountEdited(Account account) {
362 xmppConnectionService.createAccount(account);
363 activity.getActionBar().setDisplayHomeAsUpEnabled(true);
364 activity.getActionBar().setHomeButtonEnabled(true);
365 }
366 });
367 dialog.show(getFragmentManager(), "add_account");
368 dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this);
369 }
370
371 @Override
372 public void onActionModeStarted(ActionMode mode) {
373 super.onActionModeStarted(mode);
374 this.isActionMode = true;
375 }
376
377 @Override
378 public void onActionModeFinished(ActionMode mode) {
379 super.onActionModeFinished(mode);
380 this.isActionMode = false;
381 accountListView.clearChoices();
382 accountListView.requestLayout();
383 accountListView.post(new Runnable() {
384 @Override
385 public void run() {
386 accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
387 }
388 });
389 }
390
391 @Override
392 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
393 super.onActivityResult(requestCode, resultCode, data);
394 if (resultCode == RESULT_OK) {
395 if (requestCode == REQUEST_ANNOUNCE_PGP) {
396 announcePgp(selectedAccountForActionMode, null);
397 }
398 }
399 }
400}