Statistics
| Branch: | Revision:

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
}