Statistics
| Branch: | Revision:

root / src / com / rackspace / cloud / android / ListAccountsActivity.java @ d79ae700

History | View | Annotate | Download (14.4 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.AlertDialog;
14
import android.app.ProgressDialog;
15
import android.content.Context;
16
import android.content.DialogInterface;
17
import android.content.DialogInterface.OnCancelListener;
18
import android.content.Intent;
19
import android.os.AsyncTask;
20
import android.os.Bundle;
21
import android.util.Log;
22
import android.view.ContextMenu;
23
import android.view.ContextMenu.ContextMenuInfo;
24
import android.view.LayoutInflater;
25
import android.view.Menu;
26
import android.view.MenuInflater;
27
import android.view.MenuItem;
28
import android.view.View;
29
import android.view.ViewGroup;
30
import android.view.ViewGroup.LayoutParams;
31
import android.view.WindowManager;
32
import android.widget.AdapterView.AdapterContextMenuInfo;
33
import android.widget.ArrayAdapter;
34
import android.widget.ImageView;
35
import android.widget.ListView;
36
import android.widget.ProgressBar;
37
import android.widget.TextView;
38

    
39
import com.rackspace.cloud.android.R;
40
import com.rackspace.cloud.servers.api.client.Account;
41
import com.rackspace.cloud.servers.api.client.CloudServersException;
42
import com.rackspace.cloud.servers.api.client.http.Authentication;
43

    
44
//
45
public class ListAccountsActivity extends CloudListActivity{
46

    
47
        private final String FILENAME = "accounts.data";
48
        private static final String PAGE_ROOT = "/Root";
49
        
50
        private boolean authenticating;
51
        private ArrayList<Account> accounts;
52
        private Intent tabViewIntent;
53
        private ProgressDialog dialog;
54
        private Context context;
55
        //used to track the current asynctask
56
        @SuppressWarnings("rawtypes")
57
        private AsyncTask task;
58

    
59
        public void onCreate(Bundle savedInstanceState) {
60
                super.onCreate(savedInstanceState);
61
                trackPageView(PAGE_ROOT);
62
                onRestoreInstanceState(savedInstanceState);
63
                registerForContextMenu(getListView());
64
                context = getApplicationContext();
65
                tabViewIntent = new Intent(this, TabViewActivity.class);
66
        }
67

    
68
        @Override
69
        protected void onSaveInstanceState(Bundle outState) {
70
                super.onSaveInstanceState(outState);
71
                outState.putBoolean("authenticating", authenticating);
72
                outState.putSerializable("accounts", accounts);
73

    
74
                //need to set authenticating back to true because it is set to false
75
                //in hideAccountDialog()
76
                if(authenticating){
77
                        hideAccountDialog();
78
                        authenticating = true;
79
                }
80
                writeAccounts();
81
        }
82

    
83
        @SuppressWarnings("unchecked")
84
        @Override
85
        protected void onRestoreInstanceState(Bundle state) {
86

    
87
                /*
88
                 * need reference to the app so you can access
89
                 * isLoggingIn
90
                 */
91

    
92

    
93
                if (state != null && state.containsKey("authenticating") && state.getBoolean("authenticating")) {
94
                        showAccountDialog();
95
                } else {
96
                        hideAccountDialog();
97
                }
98
                if (state != null && state.containsKey("accounts")) {
99
                        accounts = (ArrayList<Account>)state.getSerializable("accounts");
100
                        if (accounts.size() == 0) {
101
                                displayNoAccountsCell();
102
                        } else {
103
                                getListView().setDividerHeight(1); // restore divider lines 
104
                                setListAdapter(new AccountAdapter());
105
                        }
106
                } else {
107
                        loadAccounts();        
108
                }         
109
        }
110

    
111
        @Override
112
        protected void onStart(){
113
                super.onStart();
114
                if(authenticating){
115
                        showAccountDialog();
116
                }
117
        }
118

    
119
        @Override
120
        protected void onStop(){
121
                super.onStop();
122
                if(authenticating){
123
                        hideAccountDialog();
124
                        authenticating = true;
125
                }
126
        }
127

    
128
        private void loadAccounts() {
129
                //check and see if there are any in memory
130
                if(accounts == null){
131
                        accounts = readAccounts();
132
                }
133
                //if nothing was written before accounts will still be null
134
                if(accounts == null){
135
                        accounts = new ArrayList<Account>();
136
                }
137

    
138
                setAccountList();
139
        }
140

    
141
        private void setAccountList() {
142
                if (accounts.size() == 0) {
143
                        displayNoAccountsCell();
144
                } else {
145
                        getListView().setDividerHeight(1); // restore divider lines 
146
                        this.setListAdapter(new AccountAdapter());
147
                }
148
        }
149

    
150
        private void writeAccounts(){
151
                FileOutputStream fos;
152
                ObjectOutputStream out = null;
153
                try{
154
                        fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
155
                        out = new ObjectOutputStream(fos);
156
                        out.writeObject(accounts);
157
                        out.flush();
158
                        out.close();
159
                } catch (FileNotFoundException e) {
160
                        showAlert("Error", "Could not save accounts.");
161
                        e.printStackTrace();
162
                } catch (IOException e) {
163
                        showAlert("Error", "Could not save accounts.");
164
                        e.printStackTrace();
165
                }
166
        }
167

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

    
194
        }
195

    
196
        private void displayNoAccountsCell() {
197
                String a[] = new String[1];
198
                a[0] = "No Accounts";
199
                setListAdapter(new ArrayAdapter<String>(getApplicationContext(), R.layout.noaccountscell, R.id.no_accounts_label, a));
200
                getListView().setTextFilterEnabled(true);
201
                getListView().setDividerHeight(0); // hide the dividers so it won't look like a list row
202
                getListView().setItemsCanFocus(false);
203
        }
204

    
205
        protected void onListItemClick(ListView l, View v, int position, long id) {
206
                if (accounts != null && accounts.size() > 0) {
207
                        //setActivityIndicatorsVisibility(View.VISIBLE, v);
208
                        Account.setAccount(accounts.get(position));
209
                        Log.d("info", "the server is " + Account.getAccount().getAuthServerV2());
210
                        login();
211
                }                
212
        }
213

    
214
        public void login() {
215
                //showActivityIndicators();
216
                //setLoginPreferences();
217
                new AuthenticateTask().execute((Void[]) null);
218
        }
219

    
220
        //setup menu for when menu button is pressed
221
        public boolean onCreateOptionsMenu(Menu menu) {
222
                super.onCreateOptionsMenu(menu);
223
                MenuInflater inflater = getMenuInflater();
224
                inflater.inflate(R.menu.accounts_list_menu, menu);
225
                return true;
226
        } 
227

    
228
        @Override 
229
        //in options menu, when add account is selected go to add account activity
230
        public boolean onOptionsItemSelected(MenuItem item) {
231
                switch (item.getItemId()) {
232
                case R.id.add_account:
233
                        Intent intent = new Intent(this, AddAccountActivity.class);
234
                        startActivityForResult(intent, 78); // arbitrary number; never used again
235
                        return true;
236
                case R.id.login_pithos:
237
                        
238
                                final CharSequence[] items = {"Pithos+ Dev", "Pithos + Staging", "Pithos +"};
239

    
240
                                AlertDialog.Builder builder = new AlertDialog.Builder(this);
241
                                builder.setTitle("Select Pithos Environment");
242
                                builder.setSingleChoiceItems(items, -1, new DialogInterface.OnClickListener() {
243
                                    public void onClick(DialogInterface dialog, int item) {
244
                                    String login;
245
                                    String auth;
246
                                    Log.d(getClass().getName(),"Item is :"+item);
247
                                       if(item ==0){
248
                                               login=Preferences.LOGIN_PITHOS_DEV_SERVER;
249
                                               auth= Preferences.PITHOS_DEV_SERVER;
250
                                       }
251
                                       else if(item ==1){
252
                                               login=Preferences.LOGIN_PITHOS_STAGING_SERVER;
253
                                               auth= Preferences.PITHOS_STAGING_SERVER;
254
                                       }
255
                                       else{
256
                                               login=Preferences.LOGIN_PITHOS_SERVER;
257
                                               auth= Preferences.PITHOS_SERVER;
258
                                       }
259
                                       Intent intent2 = new Intent(ListAccountsActivity.this, PithosLoginActivity.class);
260
                                                //intent2.putExtra("login", "https://pithos.dev.grnet.gr/im/login");
261
                                                //intent2.putExtra("auth", Preferences.PITHOS_DEV_SERVER);
262
                                       Log.d("LOGIN_URL",login);
263
                                       Log.d("LOGIN_AUTH",auth);
264
                                                intent2.putExtra("login", login);
265
                                                intent2.putExtra("auth", auth);
266
                                                dialog.dismiss();
267
                                                startActivityForResult(intent2, 78);
268
                                    }
269
                                });
270
                                AlertDialog alert2 = builder.create();
271
                                alert2.show();
272
                                
273
                        /*
274
                        Intent intent2 = new Intent(this, PithosLoginActivity.class);
275
                        //intent2.putExtra("login", "https://pithos.dev.grnet.gr/im/login");
276
                        //intent2.putExtra("auth", Preferences.PITHOS_DEV_SERVER);
277
                        intent2.putExtra("login", "https://plus.pithos.grnet.gr/im/login");
278
                        intent2.putExtra("auth", Preferences.PITHOS_SERVER);
279
                        startActivityForResult(intent2, 78); // arbitrary number; never used again
280
                        */
281
                        return true;
282

    
283
//                case R.id.contact_rackspace:
284
//                        startActivity(new Intent(this, Abo.class));
285
//                        return true;
286

    
287
//                case R.id.add_password:
288
//                        startActivity(new Intent(this, CreatePasswordActivity.class));
289
//                        return true;
290
                }        
291
                return false;
292
        } 
293

    
294
        //the context menu for a long press on an account
295
        public void onCreateContextMenu(ContextMenu menu, View v,
296
                        ContextMenuInfo menuInfo) {
297
                super.onCreateContextMenu(menu, v, menuInfo);
298
                MenuInflater inflater = getMenuInflater();
299
                inflater.inflate(R.menu.account_context_menu, menu);
300
        }
301

    
302
        //removes the selected account from account list if remove is clicked
303
        public boolean onContextItemSelected(MenuItem item) {
304
                if (accounts.size() == 0) {
305
                        displayNoAccountsCell();
306
                        return true;
307
                } else {
308
                        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
309
                        accounts.remove(info.position);
310
                        writeAccounts();
311
                        loadAccounts();
312
                        return true;
313
                }
314
        }
315

    
316
        class AccountAdapter extends ArrayAdapter<Account> {
317

    
318
                AccountAdapter() {
319
                        super(ListAccountsActivity.this, R.layout.listaccountcell, accounts);
320
                }
321

    
322
                public View getView(int position, View convertView, ViewGroup parent) {
323

    
324
                        LayoutInflater inflater = getLayoutInflater();
325
                        View row = inflater.inflate(R.layout.listaccountcell, parent, false);
326

    
327
                        TextView label = (TextView) row.findViewById(R.id.label);
328
                        label.setText(accounts.get(position).getUsername());
329

    
330
                        TextView sublabel = (TextView) row.findViewById(R.id.sublabel);
331
                        sublabel.setText(getAccountServer(accounts.get(position)));
332

    
333
                        ImageView icon = (ImageView) row.findViewById(R.id.account_type_icon);
334
                        icon.setImageResource(setAccountIcon(accounts.get(position)));
335

    
336
                        return row;
337
                }
338
        }
339

    
340
        public String getAccountServer(Account account){
341
                String authServer = account.getAuthServer();
342
                if(authServer == null){
343
                        authServer = account.getAuthServerV2();
344
                }
345
                String result;
346
                                
347
                if(authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER) || authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER_V2)){
348
                        result = "Rackspace Cloud (UK)";
349
                }
350
                else if(authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER) || authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER_V2)){
351
                        result = "Rackspace Cloud (US)";
352
                }
353
                else if(authServer.equals(Preferences.PITHOS_SERVER)){
354
                        result = "Pithos+";
355
                }
356
                else if(authServer.equals(Preferences.PITHOS_STAGING_SERVER)){
357
                        result = "Pithos+ Staging";
358
                }
359
                else if(authServer.equals(Preferences.PITHOS_DEV_SERVER)){
360
                        result = "Pithos+ Dev";
361
                }
362
                else{
363
                        result = "Custom:" +authServer;
364
                        //setCustomIcon();
365
                }
366
                return result;
367
        }
368

    
369
        //display rackspace logo for cloud accounts and openstack logo for others
370
        private int setAccountIcon(Account account){
371
                String authServer = account.getAuthServer();
372
                if(authServer == null){
373
                        authServer = account.getAuthServerV2();
374
                }
375
                if(authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER) 
376
                                || authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER)
377
                                || authServer.equals(Preferences.COUNTRY_US_AUTH_SERVER_V2)
378
                                                || authServer.equals(Preferences.COUNTRY_UK_AUTH_SERVER_V2)){
379
                        return R.drawable.rackspacecloud_icon;
380
                }
381
                if(authServer.equals(Preferences.PITHOS_DEV_SERVER) 
382
                                || authServer.equals(Preferences.PITHOS_SERVER)|| authServer.equals(Preferences.PITHOS_STAGING_SERVER)){
383
                        return R.drawable.pithos_icon;
384
                }
385
                else{
386
                        return R.drawable.openstack_icon;
387
                }
388
        }
389

    
390
        public void onActivityResult(int requestCode, int resultCode, Intent data) {
391
                super.onActivityResult(requestCode, resultCode, data);
392

    
393
                if(requestCode == 187){
394
                        hideAccountDialog(); 
395
                }
396

    
397
                if (resultCode == RESULT_OK && requestCode == 78) {          
398
                        Account acc = new Account();
399
                        Bundle b = data.getBundleExtra("accountInfo");
400
                        acc.setPassword(b.getString("apiKey"));
401
                        acc.setUsername(b.getString("username"));
402
                        acc.setAuthServer(b.getString("server"));
403
                        Log.d("info", "the set server was " + b.getString("server"));
404
                        Log.d("info", "the server is " + acc.getAuthServer());
405
                        boolean found = false;
406
                        for(Account a : accounts){
407
                                if(a.getUsername().equals(acc.getUsername())&&a.getAuthServer().equals(acc.getAuthServer())){
408
                                        a.setPassword(acc.getPassword());
409
                                        found=true;
410
                                }
411
                        }
412
                        if(!found)
413
                                accounts.add(acc);
414
                        writeAccounts();
415
                        loadAccounts();
416
                }
417
        }        
418

    
419
        private void showAccountDialog() {
420
                app.setIsLoggingIn(true);
421
                authenticating = true;
422
                if(dialog == null || !dialog.isShowing()){
423
                        dialog = new ProgressDialog(this);
424
                        dialog.setProgressStyle(R.style.NewDialog);
425
                        dialog.setOnCancelListener(new OnCancelListener() {
426

    
427
                                @Override
428
                                public void onCancel(DialogInterface dialog) {
429
                                        app.setIsLoggingIn(false);
430
                                        //need to cancel the old task or we may get a double login
431
                                        task.cancel(true);
432
                                        hideAccountDialog();
433
                                }
434
                        });
435
                        dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
436
                        dialog.show();
437
                        dialog.setContentView(new ProgressBar(this), new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
438
                }
439

    
440
                
441
        }
442

    
443
        private void hideAccountDialog() {
444
                if(dialog != null){
445
                        dialog.dismiss();
446
                }
447
                authenticating = false;
448
        }
449

    
450
        private class AuthenticateTask extends AsyncTask<Void, Void, Boolean> {
451

    
452
                @Override
453
                protected void onPreExecute(){
454
                        Log.d("info", "Starting authenticate");
455
                        task = this;
456
                        showAccountDialog();
457
                }
458

    
459
                @Override
460
                protected Boolean doInBackground(Void... arg0) {
461
                        try {
462
                                return new Boolean(Authentication.authenticate(context));
463
                        } catch (CloudServersException e) {
464
                                e.printStackTrace();
465
                                return false;
466
                        }
467
                }
468

    
469
                @Override
470
                protected void onPostExecute(Boolean result) {
471
                        if (result.booleanValue()) {
472
                                //startActivity(tabViewIntent);
473
                                /*if(app.isLoggingIn()){
474
                                        new LoadImagesTask().execute((Void[]) null);
475
                                } else {
476
                                        hideAccountDialog();
477
                                }*/
478
                                hideAccountDialog();
479
                                if(app.isLoggingIn()){
480
                                        startActivityForResult(tabViewIntent, 187);
481
                                }
482
                        } else {
483
                                hideAccountDialog();
484
                                if(app.isLoggingIn()){
485
                                        showAlert("Login Failure", "Authentication failed.  Please check your User Name and API Key.");
486
                                }
487
                        }
488
                }
489
        }
490

    
491
        
492

    
493
        }