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.adapter.AccountAdapter;
10import eu.siacs.conversations.xmpp.XmppConnection;
11import android.app.AlertDialog;
12import android.content.DialogInterface;
13import android.content.DialogInterface.OnClickListener;
14import android.content.Intent;
15import android.os.Bundle;
16import android.os.SystemClock;
17import android.view.ActionMode;
18import android.view.Menu;
19import android.view.MenuInflater;
20import android.view.MenuItem;
21import android.view.View;
22import android.widget.AdapterView;
23import android.widget.AdapterView.OnItemClickListener;
24import android.widget.AdapterView.OnItemLongClickListener;
25import android.widget.ListView;
26import android.widget.TextView;
27
28public class ManageAccountActivity extends XmppActivity {
29
30 protected boolean isActionMode = false;
31 protected ActionMode actionMode;
32 protected Account selectedAccountForActionMode = null;
33 protected ManageAccountActivity activity = this;
34
35 protected boolean firstrun = true;
36
37 protected List<Account> accountList = new ArrayList<Account>();
38 protected ListView accountListView;
39 protected AccountAdapter mAccountAdapter;
40 protected OnAccountUpdate accountChanged = new OnAccountUpdate() {
41
42 @Override
43 public void onAccountUpdate() {
44 accountList.clear();
45 accountList.addAll(xmppConnectionService.getAccounts());
46 runOnUiThread(new Runnable() {
47
48 @Override
49 public void run() {
50 mAccountAdapter.notifyDataSetChanged();
51 }
52 });
53 }
54 };
55
56 protected ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
57
58 @Override
59 public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
60 if (selectedAccountForActionMode
61 .isOptionSet(Account.OPTION_DISABLED)) {
62 menu.findItem(R.id.mgmt_account_enable).setVisible(true);
63 menu.findItem(R.id.mgmt_account_disable).setVisible(false);
64 } else {
65 menu.findItem(R.id.mgmt_account_disable).setVisible(true);
66 menu.findItem(R.id.mgmt_account_enable).setVisible(false);
67 }
68 return true;
69 }
70
71 @Override
72 public void onDestroyActionMode(ActionMode mode) {
73 // TODO Auto-generated method stub
74
75 }
76
77 @Override
78 public boolean onCreateActionMode(ActionMode mode, Menu menu) {
79 MenuInflater inflater = mode.getMenuInflater();
80 inflater.inflate(R.menu.manageaccounts_context, menu);
81 return true;
82 }
83
84 @Override
85 public boolean onActionItemClicked(final ActionMode mode, MenuItem item) {
86 if (item.getItemId() == R.id.mgmt_account_edit) {
87 editAccount(selectedAccountForActionMode);
88 } else if (item.getItemId() == R.id.mgmt_account_disable) {
89 selectedAccountForActionMode.setOption(Account.OPTION_DISABLED,
90 true);
91 xmppConnectionService
92 .updateAccount(selectedAccountForActionMode);
93 mode.finish();
94 } else if (item.getItemId() == R.id.mgmt_account_enable) {
95 selectedAccountForActionMode.setOption(Account.OPTION_DISABLED,
96 false);
97 xmppConnectionService
98 .updateAccount(selectedAccountForActionMode);
99 mode.finish();
100 } else if (item.getItemId() == R.id.mgmt_account_publish_avatar) {
101 Intent intent = new Intent(getApplicationContext(), PublishProfilePictureActivity.class);
102 intent.putExtra("account", selectedAccountForActionMode.getJid());
103 startActivity(intent);
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.getFeatures().sm()) {
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.getFeatures().carbons()) {
199 carbon.setText(getString(R.string.yes));
200 } else {
201 carbon.setText(getString(R.string.no));
202 }
203 if (xmpp.getFeatures().rosterVersioning()) {
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 editAccount(accountList.get(position));
238 } else {
239 selectedAccountForActionMode = accountList.get(position);
240 actionMode.invalidate();
241 }
242 }
243 });
244 accountListView
245 .setOnItemLongClickListener(new OnItemLongClickListener() {
246
247 @Override
248 public boolean onItemLongClick(AdapterView<?> arg0,
249 View view, int position, long arg3) {
250 if (!isActionMode) {
251 accountListView
252 .setChoiceMode(ListView.CHOICE_MODE_SINGLE);
253 accountListView.setItemChecked(position, true);
254 selectedAccountForActionMode = accountList
255 .get(position);
256 actionMode = activity
257 .startActionMode(mActionModeCallback);
258 return true;
259 } else {
260 return false;
261 }
262 }
263 });
264 }
265
266 @Override
267 protected void onStop() {
268 if (xmppConnectionServiceBound) {
269 xmppConnectionService.removeOnAccountListChangedListener();
270 }
271 super.onStop();
272 }
273
274 @Override
275 void onBackendConnected() {
276 xmppConnectionService.setOnAccountListChangedListener(accountChanged);
277 this.accountList.clear();
278 this.accountList.addAll(xmppConnectionService.getAccounts());
279 mAccountAdapter.notifyDataSetChanged();
280 if ((this.accountList.size() == 0) && (this.firstrun)) {
281 getActionBar().setDisplayHomeAsUpEnabled(false);
282 getActionBar().setHomeButtonEnabled(false);
283 this.firstrun = false;
284 }
285 }
286
287 @Override
288 public boolean onCreateOptionsMenu(Menu menu) {
289 getMenuInflater().inflate(R.menu.manageaccounts, menu);
290 return true;
291 }
292
293 @Override
294 public boolean onOptionsItemSelected(MenuItem item) {
295 switch (item.getItemId()) {
296 case R.id.action_add_account:
297 startActivity(new Intent(getApplicationContext(), EditAccountActivity.class));
298 break;
299 default:
300 break;
301 }
302 return super.onOptionsItemSelected(item);
303 }
304
305 @Override
306 public boolean onNavigateUp() {
307 if (xmppConnectionService.getConversations().size() == 0) {
308 Intent contactsIntent = new Intent(this,
309 StartConversationActivity.class);
310 contactsIntent.setFlags(
311 // if activity exists in stack, pop the stack and go back to it
312 Intent.FLAG_ACTIVITY_CLEAR_TOP |
313 // otherwise, make a new task for it
314 Intent.FLAG_ACTIVITY_NEW_TASK |
315 // don't use the new activity animation; finish
316 // animation runs instead
317 Intent.FLAG_ACTIVITY_NO_ANIMATION);
318 startActivity(contactsIntent);
319 finish();
320 return true;
321 } else {
322 return super.onNavigateUp();
323 }
324 }
325
326 private void editAccount(Account account) {
327 Intent intent = new Intent(this, EditAccountActivity.class);
328 intent.putExtra("jid", account.getJid());
329 startActivity(intent);
330 }
331
332 @Override
333 public void onActionModeStarted(ActionMode mode) {
334 super.onActionModeStarted(mode);
335 this.isActionMode = true;
336 }
337
338 @Override
339 public void onActionModeFinished(ActionMode mode) {
340 super.onActionModeFinished(mode);
341 this.isActionMode = false;
342 accountListView.clearChoices();
343 accountListView.requestLayout();
344 accountListView.post(new Runnable() {
345 @Override
346 public void run() {
347 accountListView.setChoiceMode(ListView.CHOICE_MODE_NONE);
348 }
349 });
350 }
351
352 @Override
353 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
354 super.onActivityResult(requestCode, resultCode, data);
355 if (resultCode == RESULT_OK) {
356 if (requestCode == REQUEST_ANNOUNCE_PGP) {
357 announcePgp(selectedAccountForActionMode, null);
358 }
359 }
360 }
361}