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 Intent intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class);
104 intent.putExtra("account", selectedAccountForActionMode.getJid());
105 startActivity(intent);
106 } else if (item.getItemId() == R.id.mgmt_account_delete) {
107 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
108 builder.setTitle(getString(R.string.mgmt_account_are_you_sure));
109 builder.setIconAttribute(android.R.attr.alertDialogIcon);
110 builder.setMessage(getString(R.string.mgmt_account_delete_confirm_text));
111 builder.setPositiveButton(getString(R.string.delete),
112 new OnClickListener() {
113
114 @Override
115 public void onClick(DialogInterface dialog,
116 int which) {
117 xmppConnectionService
118 .deleteAccount(selectedAccountForActionMode);
119 selectedAccountForActionMode = null;
120 mode.finish();
121 }
122 });
123 builder.setNegativeButton(getString(R.string.cancel), null);
124 builder.create().show();
125 } else if (item.getItemId() == R.id.mgmt_account_announce_pgp) {
126 if (activity.hasPgp()) {
127 mode.finish();
128 announcePgp(selectedAccountForActionMode, null);
129 } else {
130 activity.showInstallPgpDialog();
131 }
132 } else if (item.getItemId() == R.id.mgmt_otr_key) {
133 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
134 builder.setTitle("OTR Fingerprint");
135 String fingerprintTxt = selectedAccountForActionMode
136 .getOtrFingerprint(getApplicationContext());
137 View view = (View) getLayoutInflater().inflate(
138 R.layout.otr_fingerprint, null);
139 if (fingerprintTxt != null) {
140 TextView fingerprint = (TextView) view
141 .findViewById(R.id.otr_fingerprint);
142 TextView noFingerprintView = (TextView) view
143 .findViewById(R.id.otr_no_fingerprint);
144 fingerprint.setText(fingerprintTxt);
145 fingerprint.setVisibility(View.VISIBLE);
146 noFingerprintView.setVisibility(View.GONE);
147 }
148 builder.setView(view);
149 builder.setPositiveButton(getString(R.string.done), null);
150 builder.create().show();
151 } else if (item.getItemId() == R.id.mgmt_account_info) {
152 AlertDialog.Builder builder = new AlertDialog.Builder(activity);
153 builder.setTitle(getString(R.string.account_info));
154 if (selectedAccountForActionMode.getStatus() == Account.STATUS_ONLINE) {
155 XmppConnection xmpp = selectedAccountForActionMode
156 .getXmppConnection();
157 long connectionAge = (SystemClock.elapsedRealtime() - xmpp.lastConnect) / 60000;
158 long sessionAge = (SystemClock.elapsedRealtime() - xmpp.lastSessionStarted) / 60000;
159 long connectionAgeHours = connectionAge / 60;
160 long sessionAgeHours = sessionAge / 60;
161 View view = (View) getLayoutInflater().inflate(
162 R.layout.server_info, null);
163 TextView connection = (TextView) view
164 .findViewById(R.id.connection);
165 TextView session = (TextView) view
166 .findViewById(R.id.session);
167 TextView pcks_sent = (TextView) view
168 .findViewById(R.id.pcks_sent);
169 TextView pcks_received = (TextView) view
170 .findViewById(R.id.pcks_received);
171 TextView carbon = (TextView) view.findViewById(R.id.carbon);
172 TextView stream = (TextView) view.findViewById(R.id.stream);
173 TextView roster = (TextView) view.findViewById(R.id.roster);
174 TextView presences = (TextView) view
175 .findViewById(R.id.number_presences);
176 presences.setText(selectedAccountForActionMode
177 .countPresences() + "");
178 pcks_received.setText("" + xmpp.getReceivedStanzas());
179 pcks_sent.setText("" + xmpp.getSentStanzas());
180 if (connectionAgeHours >= 2) {
181 connection.setText(connectionAgeHours + " "
182 + getString(R.string.hours));
183 } else {
184 connection.setText(connectionAge + " "
185 + getString(R.string.mins));
186 }
187 if (xmpp.getFeatures().sm()) {
188 if (sessionAgeHours >= 2) {
189 session.setText(sessionAgeHours + " "
190 + getString(R.string.hours));
191 } else {
192 session.setText(sessionAge + " "
193 + getString(R.string.mins));
194 }
195 stream.setText(getString(R.string.yes));
196 } else {
197 stream.setText(getString(R.string.no));
198 session.setText(connection.getText());
199 }
200 if (xmpp.getFeatures().carbons()) {
201 carbon.setText(getString(R.string.yes));
202 } else {
203 carbon.setText(getString(R.string.no));
204 }
205 if (xmpp.getFeatures().rosterVersioning()) {
206 roster.setText(getString(R.string.yes));
207 } else {
208 roster.setText(getString(R.string.no));
209 }
210 builder.setView(view);
211 } else {
212 builder.setMessage(getString(R.string.mgmt_account_account_offline));
213 }
214 builder.setPositiveButton(getString(R.string.hide), null);
215 builder.create().show();
216 }
217 return true;
218 }
219
220 };
221
222 @Override
223 protected void onCreate(Bundle savedInstanceState) {
224
225 super.onCreate(savedInstanceState);
226
227 setContentView(R.layout.manage_accounts);
228
229 accountListView = (ListView) findViewById(R.id.account_list);
230 final XmppActivity activity = this;
231 this.mAccountAdapter = new AccountAdapter(this, accountList);
232 accountListView.setAdapter(this.mAccountAdapter);
233 accountListView.setOnItemClickListener(new OnItemClickListener() {
234
235 @Override
236 public void onItemClick(AdapterView<?> arg0, View view,
237 int position, long arg3) {
238 if (!isActionMode) {
239 Account account = accountList.get(position);
240 if (account.getStatus() == Account.STATUS_OFFLINE) {
241 activity.xmppConnectionService.reconnectAccount(
242 accountList.get(position), true);
243 } else if (account.getStatus() == Account.STATUS_ONLINE) {
244 activity.startActivity(new Intent(activity
245 .getApplicationContext(),
246 StartConversationActivity.class));
247 } else if (account.getStatus() != Account.STATUS_DISABLED) {
248 editAccount(account);
249 }
250 } else {
251 selectedAccountForActionMode = accountList.get(position);
252 actionMode.invalidate();
253 }
254 }
255 });
256 accountListView
257 .setOnItemLongClickListener(new OnItemLongClickListener() {
258
259 @Override
260 public boolean onItemLongClick(AdapterView<?> arg0,
261 View view, int position, long arg3) {
262 if (!isActionMode) {
263 accountListView
264 .setChoiceMode(ListView.CHOICE_MODE_SINGLE);
265 accountListView.setItemChecked(position, true);
266 selectedAccountForActionMode = accountList
267 .get(position);
268 actionMode = activity
269 .startActionMode(mActionModeCallback);
270 return true;
271 } else {
272 return false;
273 }
274 }
275 });
276 }
277
278 @Override
279 protected void onStop() {
280 if (xmppConnectionServiceBound) {
281 xmppConnectionService.removeOnAccountListChangedListener();
282 }
283 super.onStop();
284 }
285
286 @Override
287 void onBackendConnected() {
288 xmppConnectionService.setOnAccountListChangedListener(accountChanged);
289 this.accountList.clear();
290 this.accountList.addAll(xmppConnectionService.getAccounts());
291 mAccountAdapter.notifyDataSetChanged();
292 if ((this.accountList.size() == 0) && (this.firstrun)) {
293 getActionBar().setDisplayHomeAsUpEnabled(false);
294 getActionBar().setHomeButtonEnabled(false);
295 addAccount();
296 this.firstrun = false;
297 }
298 }
299
300 @Override
301 public boolean onCreateOptionsMenu(Menu menu) {
302 getMenuInflater().inflate(R.menu.manageaccounts, menu);
303 return true;
304 }
305
306 @Override
307 public boolean onOptionsItemSelected(MenuItem item) {
308 switch (item.getItemId()) {
309 case R.id.action_add_account:
310 addAccount();
311 break;
312 default:
313 break;
314 }
315 return super.onOptionsItemSelected(item);
316 }
317
318 @Override
319 public boolean onNavigateUp() {
320 if (xmppConnectionService.getConversations().size() == 0) {
321 Intent contactsIntent = new Intent(this,
322 StartConversationActivity.class);
323 contactsIntent.setFlags(
324 // if activity exists in stack, pop the stack and go back to it
325 Intent.FLAG_ACTIVITY_CLEAR_TOP |
326 // otherwise, make a new task for it
327 Intent.FLAG_ACTIVITY_NEW_TASK |
328 // don't use the new activity animation; finish
329 // animation runs instead
330 Intent.FLAG_ACTIVITY_NO_ANIMATION);
331 startActivity(contactsIntent);
332 finish();
333 return true;
334 } else {
335 return super.onNavigateUp();
336 }
337 }
338
339 private void editAccount(Account account) {
340 EditAccountDialog dialog = new EditAccountDialog();
341 dialog.setAccount(account);
342 dialog.setEditAccountListener(new EditAccountListener() {
343
344 @Override
345 public void onAccountEdited(Account account) {
346 xmppConnectionService.updateAccount(account);
347 if (actionMode != null) {
348 actionMode.finish();
349 }
350 }
351 });
352 dialog.show(getFragmentManager(), "edit_account");
353 dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this);
354
355 }
356
357 protected void addAccount() {
358 final Activity activity = this;
359 EditAccountDialog dialog = new EditAccountDialog();
360 dialog.setEditAccountListener(new EditAccountListener() {
361
362 @Override
363 public void onAccountEdited(Account account) {
364 xmppConnectionService.createAccount(account);
365 activity.getActionBar().setDisplayHomeAsUpEnabled(true);
366 activity.getActionBar().setHomeButtonEnabled(true);
367 }
368 });
369 dialog.show(getFragmentManager(), "add_account");
370 dialog.setKnownHosts(xmppConnectionService.getKnownHosts(), this);
371 }
372
373 @Override
374 public void onActionModeStarted(ActionMode mode) {
375 super.onActionModeStarted(mode);
376 this.isActionMode = true;
377 }
378
379 @Override
380 public void onActionModeFinished(ActionMode mode) {
381 super.onActionModeFinished(mode);
382 this.isActionMode = false;
383 accountListView.clearChoices();
384 accountListView.requestLayout();
385 accountListView.post(new Runnable() {
386 @Override
387 public void run() {
388 accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
389 }
390 });
391 }
392
393 @Override
394 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
395 super.onActivityResult(requestCode, resultCode, data);
396 if (resultCode == RESULT_OK) {
397 if (requestCode == REQUEST_ANNOUNCE_PGP) {
398 announcePgp(selectedAccountForActionMode, null);
399 }
400 }
401 }
402}