Statistics
| Branch: | Revision:

root / src / com / rackspace / cloud / android / ListAccountsActivity.java @ 7dbfc514

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
import java.util.TreeMap;
12

    
13
import android.app.ProgressDialog;
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.view.ViewGroup.LayoutParams;
30
import android.view.WindowManager;
31
import android.widget.AdapterView.AdapterContextMenuInfo;
32
import android.widget.ArrayAdapter;
33
import android.widget.ImageView;
34
import android.widget.ListView;
35
import android.widget.ProgressBar;
36
import android.widget.TextView;
37

    
38
import com.rackspace.cloud.android.R;
39
import com.rackspace.cloud.loadbalancer.api.client.Algorithm;
40
import com.rackspace.cloud.loadbalancer.api.client.AlgorithmManager;
41
import com.rackspace.cloud.loadbalancer.api.client.Protocol;
42
import com.rackspace.cloud.loadbalancer.api.client.ProtocolManager;
43
import com.rackspace.cloud.servers.api.client.Account;
44
import com.rackspace.cloud.servers.api.client.CloudServersException;
45
import com.rackspace.cloud.servers.api.client.Flavor;
46
import com.rackspace.cloud.servers.api.client.FlavorManager;
47
import com.rackspace.cloud.servers.api.client.Image;
48
import com.rackspace.cloud.servers.api.client.ImageManager;
49
import com.rackspace.cloud.servers.api.client.http.Authentication;
50

    
51
//
52
public class ListAccountsActivity extends CloudListActivity{
53

    
54
        private final String FILENAME = "accounts.data";
55
        private static final String PAGE_ROOT = "/Root";
56
        
57
        private boolean authenticating;
58
        private ArrayList<Account> accounts;
59
        private Intent tabViewIntent;
60
        private ProgressDialog dialog;
61
        private Context context;
62
        //used to track the current asynctask
63
        @SuppressWarnings("rawtypes")
64
        private AsyncTask task;
65

    
66
        public void onCreate(Bundle savedInstanceState) {
67
                super.onCreate(savedInstanceState);
68
                trackPageView(PAGE_ROOT);
69
                onRestoreInstanceState(savedInstanceState);
70
                registerForContextMenu(getListView());
71
                context = getApplicationContext();
72
                tabViewIntent = new Intent(this, TabViewActivity.class);
73
        }
74

    
75
        @Override
76
        protected void onSaveInstanceState(Bundle outState) {
77
                super.onSaveInstanceState(outState);
78
                outState.putBoolean("authenticating", authenticating);
79
                outState.putSerializable("accounts", accounts);
80

    
81
                //need to set authenticating back to true because it is set to false
82
                //in hideAccountDialog()
83
                if(authenticating){
84
                        hideAccountDialog();
85
                        authenticating = true;
86
                }
87
                writeAccounts();
88
        }
89

    
90
        @SuppressWarnings("unchecked")
91
        @Override
92
        protected void onRestoreInstanceState(Bundle state) {
93

    
94
                /*
95
                 * need reference to the app so you can access
96
                 * isLoggingIn
97
                 */
98

    
99

    
100
                if (state != null && state.containsKey("authenticating") && state.getBoolean("authenticating")) {
101
                        showAccountDialog();
102
                } else {
103
                        hideAccountDialog();
104
                }
105
                if (state != null && state.containsKey("accounts")) {
106
                        accounts = (ArrayList<Account>)state.getSerializable("accounts");
107
                        if (accounts.size() == 0) {
108
                                displayNoAccountsCell();
109
                        } else {
110
                                getListView().setDividerHeight(1); // restore divider lines 
111
                                setListAdapter(new AccountAdapter());
112
                        }
113
                } else {
114
                        loadAccounts();        
115
                }         
116
        }
117

    
118
        @Override
119
        protected void onStart(){
120
                super.onStart();
121
                if(authenticating){
122
                        showAccountDialog();
123
                }
124
        }
125

    
126
        @Override
127
        protected void onStop(){
128
                super.onStop();
129
                if(authenticating){
130
                        hideAccountDialog();
131
                        authenticating = true;
132
                }
133
        }
134

    
135
        private void loadAccounts() {
136
                //check and see if there are any in memory
137
                if(accounts == null){
138
                        accounts = readAccounts();
139
                }
140
                //if nothing was written before accounts will still be null
141
                if(accounts == null){
142
                        accounts = new ArrayList<Account>();
143
                }
144

    
145
                setAccountList();
146
        }
147

    
148
        private void setAccountList() {
149
                if (accounts.size() == 0) {
150
                        displayNoAccountsCell();
151
                } else {
152
                        getListView().setDividerHeight(1); // restore divider lines 
153
                        this.setListAdapter(new AccountAdapter());
154
                }
155
        }
156

    
157
        private void writeAccounts(){
158
                FileOutputStream fos;
159
                ObjectOutputStream out = null;
160
                try{
161
                        fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
162
                        out = new ObjectOutputStream(fos);
163
                        out.writeObject(accounts);
164
                        out.flush();
165
                        out.close();
166
                } catch (FileNotFoundException e) {
167
                        showAlert("Error", "Could not save accounts.");
168
                        e.printStackTrace();
169
                } catch (IOException e) {
170
                        showAlert("Error", "Could not save accounts.");
171
                        e.printStackTrace();
172
                }
173
        }
174

    
175
        private ArrayList<Account> readAccounts(){
176
                FileInputStream fis;
177
                ObjectInputStream in;
178
                try {
179
                        fis = openFileInput(FILENAME);
180
                        in = new ObjectInputStream(fis);
181
                        @SuppressWarnings("unchecked")
182
                        ArrayList<Account> file = (ArrayList<Account>)in.readObject();
183
                        in.close();
184
                        return file; 
185
                } catch (FileNotFoundException e) {
186
                        //showAlert("Error", "Could not load accounts.");
187
                        e.printStackTrace();
188
                        return null;
189
                } catch (StreamCorruptedException e) {
190
                        showAlert("Error", "Could not load accounts.");
191
                        e.printStackTrace();
192
                } catch (IOException e) {
193
                        showAlert("Error", "Could not load accounts.");
194
                        e.printStackTrace();
195
                } catch (ClassNotFoundException e) {
196
                        showAlert("Error", "Could not load accounts.");
197
                        e.printStackTrace();
198
                }
199
                return null;
200

    
201
        }
202

    
203
        private void displayNoAccountsCell() {
204
                String a[] = new String[1];
205
                a[0] = "No Accounts";
206
                setListAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.noaccountscell, R.id.no_accounts_label, a));
207
                getListView().setTextFilterEnabled(true);
208
                getListView().setDividerHeight(0); // hide the dividers so it won't look like a list row
209
                getListView().setItemsCanFocus(false);
210
        }
211

    
212
        protected void onListItemClick(ListView l, View v, int position, long id) {
213
                if (accounts != null && accounts.size() > 0) {
214
                        //setActivityIndicatorsVisibility(View.VISIBLE, v);
215
                        Account.setAccount(accounts.get(position));
216
                        Log.d("info", "the server is " + Account.getAccount().getAuthServerV2());
217
                        login();
218
                }                
219
        }
220

    
221
        public void login() {
222
                //showActivityIndicators();
223
                //setLoginPreferences();
224
                new AuthenticateTask().execute((Void[]) null);
225
        }
226

    
227
        //setup menu for when menu button is pressed
228
        public boolean onCreateOptionsMenu(Menu menu) {
229
                super.onCreateOptionsMenu(menu);
230
                MenuInflater inflater = getMenuInflater();
231
                inflater.inflate(R.menu.accounts_list_menu, menu);
232
                return true;
233
        } 
234

    
235
        @Override 
236
        //in options menu, when add account is selected go to add account activity
237
        public boolean onOptionsItemSelected(MenuItem item) {
238
                switch (item.getItemId()) {
239
                case R.id.add_account:
240
                        startActivityForResult(new Intent(this, AddAccountActivity.class), 78); // arbitrary number; never used again
241
                        return true;
242

    
243
                case R.id.contact_rackspace:
244
                        startActivity(new Intent(this, ContactActivity.class));
245
                        return true;
246

    
247
                case R.id.add_password:
248
                        startActivity(new Intent(this, CreatePasswordActivity.class));
249
                        return true;
250
                }        
251
                return false;
252
        } 
253

    
254
        //the context menu for a long press on an account
255
        public void onCreateContextMenu(ContextMenu menu, View v,
256
                        ContextMenuInfo menuInfo) {
257
                super.onCreateContextMenu(menu, v, menuInfo);
258
                MenuInflater inflater = getMenuInflater();
259
                inflater.inflate(R.menu.account_context_menu, menu);
260
        }
261

    
262
        //removes the selected account from account list if remove is clicked
263
        public boolean onContextItemSelected(MenuItem item) {
264
                if (accounts.size() == 0) {
265
                        displayNoAccountsCell();
266
                        return true;
267
                } else {
268
                        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
269
                        accounts.remove(info.position);
270
                        writeAccounts();
271
                        loadAccounts();
272
                        return true;
273
                }
274
        }
275

    
276
        class AccountAdapter extends ArrayAdapter<Account> {
277

    
278
                AccountAdapter() {
279
                        super(ListAccountsActivity.this, R.layout.listaccountcell, accounts);
280
                }
281

    
282
                public View getView(int position, View convertView, ViewGroup parent) {
283

    
284
                        LayoutInflater inflater = getLayoutInflater();
285
                        View row = inflater.inflate(R.layout.listaccountcell, parent, false);
286

    
287
                        TextView label = (TextView) row.findViewById(R.id.label);
288
                        label.setText(accounts.get(position).getUsername());
289

    
290
                        TextView sublabel = (TextView) row.findViewById(R.id.sublabel);
291
                        sublabel.setText(getAccountServer(accounts.get(position)));
292

    
293
                        ImageView icon = (ImageView) row.findViewById(R.id.account_type_icon);
294
                        icon.setImageResource(setAccountIcon(accounts.get(position)));
295

    
296
                        return row;
297
                }
298
        }
299

    
300
        public String getAccountServer(Account account){
301
                String authServer = account.getAuthServer();
302
                if(authServer == null){
303
                        authServer = account.getAuthServerV2();
304
                }
305
                String result;
306
                                
307
                if(authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER) || authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER_V2)){
308
                        result = "Rackspace Cloud (UK)";
309
                }
310
                else if(authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER) || authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER_V2)){
311
                        result = "Rackspace Cloud (US)";
312
                }
313
                else if(authServer.equals(Preferences.PITHOS_SERVER)){
314
                        result = "Pithos+";
315
                }
316
                else if(authServer.equals(Preferences.PITHOS_DEV_SERVER)){
317
                        result = "Pithos+ Dev";
318
                }
319
                else{
320
                        result = "Custom:" +authServer;
321
                        //setCustomIcon();
322
                }
323
                return result;
324
        }
325

    
326
        //display rackspace logo for cloud accounts and openstack logo for others
327
        private int setAccountIcon(Account account){
328
                String authServer = account.getAuthServer();
329
                if(authServer == null){
330
                        authServer = account.getAuthServerV2();
331
                }
332
                if(authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER) 
333
                                || authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER)
334
                                || authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER_V2)
335
                                                || authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER_V2)){
336
                        return R.drawable.rackspacecloud_icon;
337
                }
338
                if(authServer.equals(Preferences.PITHOS_DEV_SERVER) 
339
                                || authServer.equals(Preferences.PITHOS_SERVER)){
340
                        return R.drawable.pithos_icon;
341
                }
342
                else{
343
                        return R.drawable.openstack_icon;
344
                }
345
        }
346

    
347
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
348
                super.onActivityResult(requestCode, resultCode, data);
349

    
350
                if(requestCode == 187){
351
                        hideAccountDialog(); 
352
                }
353

    
354
                if (resultCode == RESULT_OK && requestCode == 78) {          
355
                        Account acc = new Account();
356
                        Bundle b = data.getBundleExtra("accountInfo");
357
                        acc.setPassword(b.getString("apiKey"));
358
                        acc.setUsername(b.getString("username"));
359
                        acc.setAuthServerV2(b.getString("server"));
360
                        Log.d("info", "the set server was " + b.getString("server"));
361
                        Log.d("info", "the server is " + acc.getAuthServerV2());
362
                        accounts.add(acc);
363
                        writeAccounts();
364
                        loadAccounts();
365
                }
366
        }        
367

    
368
        private void showAccountDialog() {
369
                app.setIsLoggingIn(true);
370
                authenticating = true;
371
                if(dialog == null || !dialog.isShowing()){
372
                        dialog = new ProgressDialog(this);
373
                        dialog.setProgressStyle(R.style.NewDialog);
374
                        dialog.setOnCancelListener(new OnCancelListener() {
375

    
376
                                @Override
377
                                public void onCancel(DialogInterface dialog) {
378
                                        app.setIsLoggingIn(false);
379
                                        //need to cancel the old task or we may get a double login
380
                                        task.cancel(true);
381
                                        hideAccountDialog();
382
                                }
383
                        });
384
                        dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
385
                        dialog.show();
386
                        dialog.setContentView(new ProgressBar(this), new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
387
                }
388

    
389
                
390
        }
391

    
392
        private void hideAccountDialog() {
393
                if(dialog != null){
394
                        dialog.dismiss();
395
                }
396
                authenticating = false;
397
        }
398

    
399
        private class AuthenticateTask extends AsyncTask<Void, Void, Boolean> {
400

    
401
                @Override
402
                protected void onPreExecute(){
403
                        Log.d("info", "Starting authenticate");
404
                        task = this;
405
                        showAccountDialog();
406
                }
407

    
408
                @Override
409
                protected Boolean doInBackground(Void... arg0) {
410
                        try {
411
                                return new Boolean(Authentication.authenticate(context));
412
                        } catch (CloudServersException e) {
413
                                e.printStackTrace();
414
                                return false;
415
                        }
416
                }
417

    
418
                @Override
419
                protected void onPostExecute(Boolean result) {
420
                        if (result.booleanValue()) {
421
                                //startActivity(tabViewIntent);
422
                                if(app.isLoggingIn()){
423
                                        new LoadImagesTask().execute((Void[]) null);
424
                                } else {
425
                                        hideAccountDialog();
426
                                }
427
                        } else {
428
                                hideAccountDialog();
429
                                if(app.isLoggingIn()){
430
                                        showAlert("Login Failure", "Authentication failed.  Please check your User Name and API Key.");
431
                                }
432
                        }
433
                }
434
        }
435

    
436
        private class LoadImagesTask extends AsyncTask<Void, Void, ArrayList<Image>> {
437
 
438
                @Override
439
                protected void onPreExecute(){
440
                        Log.d("info", "Starting Images");
441
                        task = this;
442
                }
443
                
444
                @Override
445
                protected ArrayList<Image> doInBackground(Void... arg0) {
446
                        return (new ImageManager()).createList(true, context);
447
                }
448

    
449
                @Override
450
                protected void onPostExecute(ArrayList<Image> result) {
451
                        if (result != null && result.size() > 0) {
452
                                TreeMap<String, Image> imageMap = new TreeMap<String, Image>();
453
                                for (int i = 0; i < result.size(); i++) {
454
                                        Image image = result.get(i);
455
                                        imageMap.put(image.getId(), image);
456
                                }
457
                                Image.setImages(imageMap);
458
                                if(app.isLoggingIn()){
459
                                        new LoadProtocolsTask().execute((Void[]) null); 
460
                                } else {
461
                                        hideAccountDialog();
462
                                }
463
                        } else {
464
                                hideAccountDialog();
465
                                if(app.isLoggingIn()){
466
                                        showAlert("Login Failure", "There was a problem loading server images.  Please try again.");
467
                                }
468
                        }
469
                }
470
        }
471

    
472
        private class LoadProtocolsTask extends AsyncTask<Void, Void, ArrayList<Protocol>> {
473

    
474
                @Override
475
                protected void onPreExecute(){
476
                        Log.d("info", "Starting protcols");
477
                        task = this;
478
                }
479
                
480
                @Override
481
                protected ArrayList<Protocol> doInBackground(Void... arg0) {
482
                        return (new ProtocolManager()).createList(context);
483
                }
484

    
485
                @Override
486
                protected void onPostExecute(ArrayList<Protocol> result) {
487
                        if (result != null && result.size() > 0) {
488
                                Protocol.setProtocols(result);
489
                                if(app.isLoggingIn()){
490
                                        new LoadAlgorithmsTask().execute((Void[]) null);
491
                                } else {
492
                                        hideAccountDialog();
493
                                }
494
                        } else {
495
                                hideAccountDialog();
496
                                if(app.isLoggingIn()){
497
                                        showAlert("Login Failure", "There was a problem loading load balancer protocols.  Please try again.");
498
                                }
499
                        }
500
                }
501
        }
502

    
503
        private class LoadAlgorithmsTask extends AsyncTask<Void, Void, ArrayList<Algorithm>> {
504

    
505
                protected void onPreExecute(){
506
                        Log.d("info", "Starting algorithms");
507
                        task = this;
508
                }
509
                
510
                @Override
511
                protected ArrayList<Algorithm> doInBackground(Void... arg0) {
512
                        return (new AlgorithmManager()).createList(context);
513
                }
514

    
515
                @Override
516
                protected void onPostExecute(ArrayList<Algorithm> result) {
517
                        if (result != null && result.size() > 0) {
518
                                Algorithm.setAlgorithms(result);
519
                                if(app.isLoggingIn()){
520
                                        new LoadFlavorsTask().execute((Void[]) null);
521
                                } else {
522
                                        hideAccountDialog();
523
                                }
524
                        } else {
525
                                hideAccountDialog();
526
                                if(app.isLoggingIn()){
527
                                        showAlert("Login Failure", "There was a problem loading load balancer algorithms.  Please try again.");
528
                                }
529
                        }
530
                }
531
        }
532

    
533
        private class LoadFlavorsTask extends AsyncTask<Void, Void, ArrayList<Flavor>> {
534

    
535
                protected void onPreExecute(){
536
                        Log.d("info", "Starting flavors");
537
                        task = this;
538
                }
539
                
540
                @Override
541
                protected ArrayList<Flavor> doInBackground(Void... arg0) {
542
                        return (new FlavorManager()).createList(true, context);
543
                }
544

    
545
                @Override
546
                protected void onPostExecute(ArrayList<Flavor> result) {
547
                        if (result != null && result.size() > 0) {
548
                                TreeMap<String, Flavor> flavorMap = new TreeMap<String, Flavor>();
549
                                for (int i = 0; i < result.size(); i++) {
550
                                        Flavor flavor = result.get(i);
551
                                        flavorMap.put(flavor.getId(), flavor);
552
                                }
553
                                Flavor.setFlavors(flavorMap);
554
                                hideAccountDialog();
555
                                if(app.isLoggingIn()){
556
                                        startActivityForResult(tabViewIntent, 187);
557
                                }
558
                        } else {
559
                                hideAccountDialog();
560
                                if(app.isLoggingIn()){
561
                                        showAlert("Login Failure", "There was a problem loading server flavors.  Please try again.");
562
                                }
563
                        }
564
                }
565
        }
566

    
567

    
568

    
569

    
570

    
571
}