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