root / src / com / rackspace / cloud / android / ListAccountsActivity.java @ 378fe36a
History | View | Annotate | Download (15.9 kB)
1 |
package com.rackspace.cloud.android; |
---|---|
2 |
|
3 |
import java.io.FileInputStream; |
4 |
import java.io.FileNotFoundException; |
5 |
import java.io.FileOutputStream; |
6 |
import java.io.IOException; |
7 |
import java.io.ObjectInputStream; |
8 |
import java.io.ObjectOutputStream; |
9 |
import java.io.StreamCorruptedException; |
10 |
import java.util.ArrayList; |
11 |
|
12 |
import android.app.AlertDialog; |
13 |
import android.app.Dialog; |
14 |
import android.content.Context; |
15 |
import android.content.DialogInterface; |
16 |
import android.content.DialogInterface.OnCancelListener; |
17 |
import android.content.Intent; |
18 |
import android.os.AsyncTask; |
19 |
import android.os.Bundle; |
20 |
import android.util.Log; |
21 |
import android.view.ContextMenu; |
22 |
import android.view.ContextMenu.ContextMenuInfo; |
23 |
import android.view.LayoutInflater; |
24 |
import android.view.Menu; |
25 |
import android.view.MenuInflater; |
26 |
import android.view.MenuItem; |
27 |
import android.view.View; |
28 |
import android.view.ViewGroup; |
29 |
import android.widget.AdapterView.AdapterContextMenuInfo; |
30 |
import android.widget.ArrayAdapter; |
31 |
import android.widget.ImageView; |
32 |
import android.widget.ListView; |
33 |
import android.widget.TextView; |
34 |
|
35 |
import com.rackspace.cloud.servers.api.client.Account; |
36 |
import com.rackspace.cloud.servers.api.client.CloudServersException; |
37 |
import com.rackspace.cloud.servers.api.client.http.Authentication; |
38 |
|
39 |
//
|
40 |
public class ListAccountsActivity extends CloudListActivity { |
41 |
|
42 |
private final String FILENAME = "accounts.data"; |
43 |
private static final String PAGE_ROOT = "/Root"; |
44 |
|
45 |
private boolean authenticating; |
46 |
private ArrayList<Account> accounts; |
47 |
private Intent tabViewIntent;
|
48 |
private Dialog dialog; |
49 |
private Context context; |
50 |
// used to track the current asynctask
|
51 |
@SuppressWarnings("rawtypes") |
52 |
private AsyncTask task;
|
53 |
|
54 |
public void onCreate(Bundle savedInstanceState) { |
55 |
super.onCreate(savedInstanceState);
|
56 |
trackPageView(PAGE_ROOT); |
57 |
onRestoreInstanceState(savedInstanceState); |
58 |
registerForContextMenu(getListView()); |
59 |
context = getApplicationContext(); |
60 |
tabViewIntent = new Intent(this, TabViewActivity.class); |
61 |
} |
62 |
|
63 |
@Override
|
64 |
protected void onSaveInstanceState(Bundle outState) { |
65 |
super.onSaveInstanceState(outState);
|
66 |
outState.putBoolean("authenticating", authenticating);
|
67 |
outState.putSerializable("accounts", accounts);
|
68 |
|
69 |
// need to set authenticating back to true because it is set to false
|
70 |
// in hideAccountDialog()
|
71 |
if (authenticating) {
|
72 |
hideAccountDialog(); |
73 |
authenticating = true;
|
74 |
} |
75 |
writeAccounts(); |
76 |
} |
77 |
|
78 |
@SuppressWarnings("unchecked") |
79 |
@Override
|
80 |
protected void onRestoreInstanceState(Bundle state) { |
81 |
|
82 |
/*
|
83 |
* need reference to the app so you can access isLoggingIn
|
84 |
*/
|
85 |
|
86 |
if (state != null && state.containsKey("authenticating") |
87 |
&& state.getBoolean("authenticating")) {
|
88 |
showAccountDialog(); |
89 |
} else {
|
90 |
hideAccountDialog(); |
91 |
} |
92 |
if (state != null && state.containsKey("accounts")) { |
93 |
accounts = (ArrayList<Account>) state.getSerializable("accounts"); |
94 |
if (accounts.size() == 0) { |
95 |
displayNoAccountsCell(); |
96 |
} else {
|
97 |
getListView().setDividerHeight(1); // restore divider lines |
98 |
setListAdapter(new AccountAdapter());
|
99 |
} |
100 |
} else {
|
101 |
loadAccounts(); |
102 |
} |
103 |
} |
104 |
|
105 |
@Override
|
106 |
protected void onStart() { |
107 |
super.onStart();
|
108 |
if (authenticating) {
|
109 |
showAccountDialog(); |
110 |
} |
111 |
} |
112 |
|
113 |
@Override
|
114 |
protected void onStop() { |
115 |
super.onStop();
|
116 |
if (authenticating) {
|
117 |
hideAccountDialog(); |
118 |
authenticating = true;
|
119 |
} |
120 |
} |
121 |
|
122 |
private void loadAccounts() { |
123 |
// check and see if there are any in memory
|
124 |
if (accounts == null) { |
125 |
accounts = readAccounts(); |
126 |
} |
127 |
// if nothing was written before accounts will still be null
|
128 |
if (accounts == null) { |
129 |
accounts = new ArrayList<Account>(); |
130 |
} |
131 |
|
132 |
setAccountList(); |
133 |
} |
134 |
|
135 |
private void setAccountList() { |
136 |
if (accounts.size() == 0) { |
137 |
displayNoAccountsCell(); |
138 |
} else {
|
139 |
getListView().setDividerHeight(1); // restore divider lines |
140 |
this.setListAdapter(new AccountAdapter()); |
141 |
} |
142 |
} |
143 |
|
144 |
private void writeAccounts() { |
145 |
FileOutputStream fos;
|
146 |
ObjectOutputStream out = null; |
147 |
try {
|
148 |
fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
|
149 |
out = new ObjectOutputStream(fos); |
150 |
out.writeObject(accounts); |
151 |
out.flush(); |
152 |
out.close(); |
153 |
} catch (FileNotFoundException e) { |
154 |
showAlert("Error", "Could not save accounts."); |
155 |
e.printStackTrace(); |
156 |
} catch (IOException e) { |
157 |
showAlert("Error", "Could not save accounts."); |
158 |
e.printStackTrace(); |
159 |
} |
160 |
} |
161 |
|
162 |
private ArrayList<Account> readAccounts() { |
163 |
FileInputStream fis;
|
164 |
ObjectInputStream in;
|
165 |
try {
|
166 |
fis = openFileInput(FILENAME); |
167 |
in = new ObjectInputStream(fis); |
168 |
@SuppressWarnings("unchecked") |
169 |
ArrayList<Account> file = (ArrayList<Account>) in.readObject(); |
170 |
in.close(); |
171 |
return file;
|
172 |
} catch (FileNotFoundException e) { |
173 |
// showAlert("Error", "Could not load accounts.");
|
174 |
e.printStackTrace(); |
175 |
return null; |
176 |
} catch (StreamCorruptedException e) { |
177 |
showAlert("Error", "Could not load accounts."); |
178 |
e.printStackTrace(); |
179 |
} catch (IOException e) { |
180 |
showAlert("Error", "Could not load accounts."); |
181 |
e.printStackTrace(); |
182 |
} catch (ClassNotFoundException e) { |
183 |
showAlert("Error", "Could not load accounts."); |
184 |
e.printStackTrace(); |
185 |
} |
186 |
return null; |
187 |
|
188 |
} |
189 |
|
190 |
private void displayNoAccountsCell() { |
191 |
String a[] = new String[1]; |
192 |
a[0] = "No Accounts"; |
193 |
setListAdapter(new ArrayAdapter<String>(getApplicationContext(), |
194 |
R.layout.noaccountscell, R.id.no_accounts_label, a)); |
195 |
getListView().setTextFilterEnabled(true);
|
196 |
getListView().setDividerHeight(0); // hide the dividers so it won't look |
197 |
// like a list row
|
198 |
getListView().setItemsCanFocus(false);
|
199 |
} |
200 |
|
201 |
protected void onListItemClick(ListView l, View v, int position, long id) { |
202 |
if (accounts != null && accounts.size() > 0) { |
203 |
// setActivityIndicatorsVisibility(View.VISIBLE, v);
|
204 |
Account.setAccount(accounts.get(position)); |
205 |
Log.d("info", "the server is " |
206 |
+ Account.getAccount().getAuthServerV2()); |
207 |
login(); |
208 |
} |
209 |
} |
210 |
|
211 |
public void login() { |
212 |
// showActivityIndicators();
|
213 |
// setLoginPreferences();
|
214 |
new AuthenticateTask().execute((Void[]) null); |
215 |
} |
216 |
|
217 |
// setup menu for when menu button is pressed
|
218 |
public boolean onCreateOptionsMenu(Menu menu) { |
219 |
super.onCreateOptionsMenu(menu);
|
220 |
MenuInflater inflater = getMenuInflater(); |
221 |
inflater.inflate(R.menu.accounts_list_menu, menu); |
222 |
return true; |
223 |
} |
224 |
|
225 |
@Override
|
226 |
// in options menu, when add account is selected go to add account activity
|
227 |
public boolean onOptionsItemSelected(MenuItem item) { |
228 |
switch (item.getItemId()) {
|
229 |
case R.id.add_account:
|
230 |
Intent intent = new Intent(this, AddAccountActivity.class); |
231 |
startActivityForResult(intent, 78); // arbitrary number; never used |
232 |
// again
|
233 |
return true; |
234 |
/*
|
235 |
* case R.id.login_pithos:
|
236 |
*
|
237 |
* final CharSequence[] items = { "Pithos+ Dev", "Pithos + Staging",
|
238 |
* "Pithos +" };
|
239 |
*
|
240 |
* AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
241 |
* builder.setTitle("Select Pithos Environment");
|
242 |
* builder.setSingleChoiceItems(items, -1, new
|
243 |
* DialogInterface.OnClickListener() { public void
|
244 |
* onClick(DialogInterface dialog, int item) { String login; String
|
245 |
* auth; Log.d(getClass().getName(), "Item is :" + item); if (item
|
246 |
* == 0) { login = Preferences.LOGIN_PITHOS_DEV_SERVER; auth =
|
247 |
* Preferences.PITHOS_DEV_SERVER; } else if (item == 1) { login =
|
248 |
* Preferences.LOGIN_PITHOS_STAGING_SERVER; auth =
|
249 |
* Preferences.PITHOS_STAGING_SERVER; } else { login =
|
250 |
* Preferences.LOGIN_PITHOS_SERVER; auth =
|
251 |
* Preferences.PITHOS_SERVER;
|
252 |
*
|
253 |
*
|
254 |
* } Intent intent2 = new Intent( ListAccountsActivity.this,
|
255 |
* PithosLoginActivity.class); // intent2.putExtra("login", //
|
256 |
* "https://pithos.dev.grnet.gr/im/login"); //
|
257 |
* intent2.putExtra("auth", // Preferences.PITHOS_DEV_SERVER);
|
258 |
* Log.d("LOGIN_URL", login); Log.d("LOGIN_AUTH", auth);
|
259 |
* intent2.putExtra("login", login); intent2.putExtra("auth", auth);
|
260 |
* dialog.dismiss(); startActivityForResult(intent2, 78); } });
|
261 |
* AlertDialog alert2 = builder.create(); alert2.show();
|
262 |
*
|
263 |
* /* //Intent intent2 = new Intent(this,
|
264 |
* PithosLoginActivity.class); ////intent2.putExtra("login",
|
265 |
* //"https://pithos.dev.grnet.gr/im/login");
|
266 |
* ////intent2.putExtra("auth", Preferences.PITHOS_DEV_SERVER);
|
267 |
* //intent2.putExtra("login",
|
268 |
* //"https://plus.pithos.grnet.gr/im/login");
|
269 |
* //intent2.putExtra("auth", Preferences.PITHOS_SERVER);
|
270 |
* //startActivityForResult(intent2, 78); // arbitrary number; never
|
271 |
* //used again
|
272 |
*
|
273 |
* return true;
|
274 |
*/
|
275 |
|
276 |
// case R.id.contact_rackspace:
|
277 |
// startActivity(new Intent(this, Abo.class));
|
278 |
// return true;
|
279 |
|
280 |
// case R.id.add_password:
|
281 |
// startActivity(new Intent(this, CreatePasswordActivity.class));
|
282 |
// return true;
|
283 |
} |
284 |
return false; |
285 |
} |
286 |
|
287 |
// the context menu for a long press on an account
|
288 |
public void onCreateContextMenu(ContextMenu menu, View v, |
289 |
ContextMenuInfo menuInfo) { |
290 |
super.onCreateContextMenu(menu, v, menuInfo);
|
291 |
MenuInflater inflater = getMenuInflater(); |
292 |
inflater.inflate(R.menu.account_context_menu, menu); |
293 |
} |
294 |
|
295 |
// removes the selected account from account list if remove is clicked
|
296 |
public boolean onContextItemSelected(MenuItem item) { |
297 |
|
298 |
if (accounts.size() == 0) { |
299 |
displayNoAccountsCell(); |
300 |
return true; |
301 |
} else {
|
302 |
switch (item.getItemId()) {
|
303 |
case R.id.remove_account:
|
304 |
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item |
305 |
.getMenuInfo(); |
306 |
|
307 |
accounts.remove(info.position); |
308 |
writeAccounts(); |
309 |
loadAccounts(); |
310 |
return true; |
311 |
case R.id.view_account:
|
312 |
info = (AdapterContextMenuInfo) item.getMenuInfo(); |
313 |
Account acc = accounts.get(info.position); |
314 |
Intent intent = new Intent(this, AddAccountActivity.class); |
315 |
intent.putExtra("account_displayname", acc.getDisplayName());
|
316 |
intent.putExtra("account_token", acc.getPassword());
|
317 |
intent.putExtra("account_auth", acc.getAuthServer());
|
318 |
startActivityForResult(intent, 78);
|
319 |
return true; |
320 |
default:
|
321 |
return true; |
322 |
} |
323 |
} |
324 |
} |
325 |
|
326 |
class AccountAdapter extends ArrayAdapter<Account> { |
327 |
|
328 |
AccountAdapter() { |
329 |
super(ListAccountsActivity.this, R.layout.listaccountcell, accounts);
|
330 |
} |
331 |
|
332 |
public View getView(int position, View convertView, ViewGroup parent) { |
333 |
|
334 |
LayoutInflater inflater = getLayoutInflater(); |
335 |
View row = inflater
|
336 |
.inflate(R.layout.listaccountcell, parent, false);
|
337 |
|
338 |
TextView label = (TextView) row.findViewById(R.id.label); |
339 |
label.setText(accounts.get(position).getDisplayName()/* + " "
|
340 |
+ accounts.get(position).getUsername()*/);
|
341 |
|
342 |
TextView sublabel = (TextView) row.findViewById(R.id.sublabel); |
343 |
sublabel.setText(getAccountServer(accounts.get(position))); |
344 |
|
345 |
ImageView icon = (ImageView) row |
346 |
.findViewById(R.id.account_type_icon); |
347 |
icon.setImageResource(setAccountIcon(accounts.get(position))); |
348 |
|
349 |
return row;
|
350 |
} |
351 |
} |
352 |
|
353 |
public String getAccountServer(Account account) { |
354 |
String authServer = account.getAuthServer();
|
355 |
if (authServer == null) { |
356 |
authServer = account.getAuthServerV2(); |
357 |
} |
358 |
String result;
|
359 |
|
360 |
if (authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER) |
361 |
|| authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER_V2)) {
|
362 |
result = "Rackspace Cloud (UK)";
|
363 |
} else if (authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER) |
364 |
|| authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER_V2)) {
|
365 |
result = "Rackspace Cloud (US)";
|
366 |
} else if (authServer.equals(Preferences.PITHOS_SERVER)) { |
367 |
result = "Pithos+";
|
368 |
} else if (authServer.equals(Preferences.PITHOS_STAGING_SERVER)) { |
369 |
result = "Pithos+ Staging";
|
370 |
} else if (authServer.equals(Preferences.PITHOS_DEV_SERVER)) { |
371 |
result = "Pithos+ Dev";
|
372 |
} else {
|
373 |
result = "Custom:" + authServer;
|
374 |
// setCustomIcon();
|
375 |
} |
376 |
return result;
|
377 |
} |
378 |
|
379 |
// display rackspace logo for cloud accounts and openstack logo for others
|
380 |
private int setAccountIcon(Account account) { |
381 |
String authServer = account.getAuthServer();
|
382 |
if (authServer == null) { |
383 |
authServer = account.getAuthServerV2(); |
384 |
} |
385 |
if (authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER) |
386 |
|| authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER)
|
387 |
|| authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER_V2)
|
388 |
|| authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER_V2)) {
|
389 |
return R.drawable.rackspacecloud_icon;
|
390 |
} |
391 |
if (authServer.equals(Preferences.PITHOS_DEV_SERVER) |
392 |
|| authServer.equals(Preferences.PITHOS_SERVER)
|
393 |
|| authServer.equals(Preferences.PITHOS_STAGING_SERVER)) {
|
394 |
return R.drawable.pithos_icon;
|
395 |
} else {
|
396 |
return R.drawable.openstack_icon;
|
397 |
} |
398 |
} |
399 |
|
400 |
public void onActivityResult(int requestCode, int resultCode, Intent data) { |
401 |
super.onActivityResult(requestCode, resultCode, data);
|
402 |
|
403 |
if (requestCode == 187) { |
404 |
hideAccountDialog(); |
405 |
} |
406 |
|
407 |
if (resultCode == RESULT_OK && requestCode == 78) { |
408 |
if (data.getBundleExtra("serverused") != null) { |
409 |
String login;
|
410 |
String auth;
|
411 |
int item = data.getBundleExtra("serverused").getInt("item"); |
412 |
if (item == 2) { |
413 |
login = Preferences.LOGIN_PITHOS_DEV_SERVER;
|
414 |
auth = Preferences.PITHOS_DEV_SERVER;
|
415 |
} else if (item == 1) { |
416 |
login = Preferences.LOGIN_PITHOS_STAGING_SERVER;
|
417 |
auth = Preferences.PITHOS_STAGING_SERVER;
|
418 |
} else {
|
419 |
login = Preferences.LOGIN_PITHOS_SERVER;
|
420 |
auth = Preferences.PITHOS_SERVER;
|
421 |
} |
422 |
Intent intent2 = new Intent(ListAccountsActivity.this,
|
423 |
PithosLoginActivity.class); |
424 |
Log.d("LOGIN_URL", login);
|
425 |
Log.d("LOGIN_AUTH", auth);
|
426 |
intent2.putExtra("login", login);
|
427 |
intent2.putExtra("auth", auth);
|
428 |
startActivityForResult(intent2, 78);
|
429 |
return;
|
430 |
} |
431 |
|
432 |
Account acc = new Account();
|
433 |
Bundle b = data.getBundleExtra("accountInfo");
|
434 |
acc.setPassword(b.getString("apiKey"));
|
435 |
acc.setAuthServer(b.getString("server"));
|
436 |
if (b.getString("username") != null) |
437 |
acc.setUsername(b.getString("username"));
|
438 |
else {
|
439 |
acc.setDisplayName(b.getString("displayname"));
|
440 |
Account.setAccount(acc); |
441 |
acc.setUsername(Account.getUUIDForDisplayName( |
442 |
acc.getDisplayName(), ListAccountsActivity.this)); |
443 |
} |
444 |
if (b.getString("displayname") != null) { |
445 |
acc.setDisplayName(b.getString("displayname"));
|
446 |
} else {
|
447 |
Account.setAccount(acc); |
448 |
acc.setDisplayName(Account.getDisplayNameForUUID( |
449 |
acc.getUsername(), ListAccountsActivity.this)); |
450 |
} |
451 |
Log.d("info", "the set server was " + b.getString("server")); |
452 |
Log.d("info", "the server is " + acc.getAuthServer()); |
453 |
boolean found = false; |
454 |
for (Account a : accounts) {
|
455 |
if (a.getUsername().equals(acc.getUsername())
|
456 |
&& a.getAuthServer().equals(acc.getAuthServer())) { |
457 |
a.setPassword(acc.getPassword()); |
458 |
found = true;
|
459 |
break;
|
460 |
} |
461 |
} |
462 |
if (!found)
|
463 |
accounts.add(acc); |
464 |
writeAccounts(); |
465 |
loadAccounts(); |
466 |
} |
467 |
} |
468 |
|
469 |
private void showAccountDialog() { |
470 |
app.setIsLoggingIn(true);
|
471 |
authenticating = true;
|
472 |
if (dialog == null || !dialog.isShowing()) { |
473 |
dialog = CenteredProgressDialog.show(this, "", "", false, true, |
474 |
new OnCancelListener() {
|
475 |
@Override
|
476 |
public void onCancel(DialogInterface dialog) { |
477 |
app.setIsLoggingIn(false);
|
478 |
// need to cancel the old task or we may get a
|
479 |
// double login
|
480 |
task.cancel(true);
|
481 |
hideAccountDialog(); |
482 |
} |
483 |
}); |
484 |
dialog.show(); |
485 |
|
486 |
} |
487 |
|
488 |
} |
489 |
|
490 |
private void hideAccountDialog() { |
491 |
if (dialog != null) { |
492 |
dialog.dismiss(); |
493 |
} |
494 |
authenticating = false;
|
495 |
} |
496 |
|
497 |
private class AuthenticateTask extends AsyncTask<Void, Void, Boolean> { |
498 |
|
499 |
@Override
|
500 |
protected void onPreExecute() { |
501 |
Log.d("info", "Starting authenticate"); |
502 |
task = this;
|
503 |
showAccountDialog(); |
504 |
} |
505 |
|
506 |
@Override
|
507 |
protected Boolean doInBackground(Void... arg0) { |
508 |
try {
|
509 |
return new Boolean(Authentication.authenticate(context)); |
510 |
} catch (CloudServersException e) {
|
511 |
e.printStackTrace(); |
512 |
return false; |
513 |
} |
514 |
} |
515 |
|
516 |
@Override
|
517 |
protected void onPostExecute(Boolean result) { |
518 |
if (result.booleanValue()) {
|
519 |
// startActivity(tabViewIntent);
|
520 |
/*
|
521 |
* if(app.isLoggingIn()){ new LoadImagesTask().execute((Void[])
|
522 |
* null); } else { hideAccountDialog(); }
|
523 |
*/
|
524 |
hideAccountDialog(); |
525 |
if (app.isLoggingIn()) {
|
526 |
startActivityForResult(tabViewIntent, 187);
|
527 |
} |
528 |
} else {
|
529 |
hideAccountDialog(); |
530 |
if (app.isLoggingIn()) {
|
531 |
showAlert("Login Failure",
|
532 |
"Authentication failed. Please check your User Name and API Key.");
|
533 |
} |
534 |
} |
535 |
} |
536 |
} |
537 |
|
538 |
} |