Statistics
| Branch: | Revision:

root / src / com / rackspace / cloud / android / ListAccountsActivity.java @ 05a718db

History | View | Annotate | Download (12.8 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.servers.api.client.Account;
40
import com.rackspace.cloud.servers.api.client.CloudServersException;
41
import com.rackspace.cloud.servers.api.client.http.Authentication;
42

    
43
//
44
public class ListAccountsActivity extends CloudListActivity{
45

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

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

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

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

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

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

    
91

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

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

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

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

    
137
                setAccountList();
138
        }
139

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

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

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

    
193
        }
194

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

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

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

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

    
227
        @Override 
228
        //in options menu, when add account is selected go to add account activity
229
        public boolean onOptionsItemSelected(MenuItem item) {
230
                switch (item.getItemId()) {
231
                case R.id.add_account:
232
                        Intent intent = new Intent(this, AddAccountActivity.class);
233
                        startActivityForResult(intent, 78); // arbitrary number; never used again
234
                        return true;
235
                case R.id.login_pithos:
236
                        Intent intent2 = new Intent(this, PithosLoginActivity.class);
237
                        //intent2.putExtra("login", "https://pithos.dev.grnet.gr/im/login");
238
                        //intent2.putExtra("auth", Preferences.PITHOS_DEV_SERVER);
239
                        intent2.putExtra("login", "https://plus.pithos.grnet.gr/im/login");
240
                        intent2.putExtra("auth", Preferences.PITHOS_SERVER);
241
                        startActivityForResult(intent2, 78); // arbitrary number; never used again
242
                        return true;
243

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

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

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

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

    
277
        class AccountAdapter extends ArrayAdapter<Account> {
278

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

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

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

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

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

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

    
297
                        return row;
298
                }
299
        }
300

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

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

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

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

    
355
                if (resultCode == RESULT_OK && requestCode == 78) {          
356
                        Account acc = new Account();
357
                        Bundle b = data.getBundleExtra("accountInfo");
358
                        acc.setPassword(b.getString("apiKey"));
359
                        acc.setUsername(b.getString("username"));
360
                        acc.setAuthServer(b.getString("server"));
361
                        Log.d("info", "the set server was " + b.getString("server"));
362
                        Log.d("info", "the server is " + acc.getAuthServer());
363
                        boolean found = false;
364
                        for(Account a : accounts){
365
                                if(a.getUsername().equals(acc.getUsername())&&a.getAuthServer().equals(acc.getAuthServer())){
366
                                        a.setPassword(acc.getPassword());
367
                                        found=true;
368
                                }
369
                        }
370
                        if(!found)
371
                                accounts.add(acc);
372
                        writeAccounts();
373
                        loadAccounts();
374
                }
375
        }        
376

    
377
        private void showAccountDialog() {
378
                app.setIsLoggingIn(true);
379
                authenticating = true;
380
                if(dialog == null || !dialog.isShowing()){
381
                        dialog = new ProgressDialog(this);
382
                        dialog.setProgressStyle(R.style.NewDialog);
383
                        dialog.setOnCancelListener(new OnCancelListener() {
384

    
385
                                @Override
386
                                public void onCancel(DialogInterface dialog) {
387
                                        app.setIsLoggingIn(false);
388
                                        //need to cancel the old task or we may get a double login
389
                                        task.cancel(true);
390
                                        hideAccountDialog();
391
                                }
392
                        });
393
                        dialog.getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
394
                        dialog.show();
395
                        dialog.setContentView(new ProgressBar(this), new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
396
                }
397

    
398
                
399
        }
400

    
401
        private void hideAccountDialog() {
402
                if(dialog != null){
403
                        dialog.dismiss();
404
                }
405
                authenticating = false;
406
        }
407

    
408
        private class AuthenticateTask extends AsyncTask<Void, Void, Boolean> {
409

    
410
                @Override
411
                protected void onPreExecute(){
412
                        Log.d("info", "Starting authenticate");
413
                        task = this;
414
                        showAccountDialog();
415
                }
416

    
417
                @Override
418
                protected Boolean doInBackground(Void... arg0) {
419
                        try {
420
                                return new Boolean(Authentication.authenticate(context));
421
                        } catch (CloudServersException e) {
422
                                e.printStackTrace();
423
                                return false;
424
                        }
425
                }
426

    
427
                @Override
428
                protected void onPostExecute(Boolean result) {
429
                        if (result.booleanValue()) {
430
                                //startActivity(tabViewIntent);
431
                                /*if(app.isLoggingIn()){
432
                                        new LoadImagesTask().execute((Void[]) null);
433
                                } else {
434
                                        hideAccountDialog();
435
                                }*/
436
                                hideAccountDialog();
437
                                if(app.isLoggingIn()){
438
                                        startActivityForResult(tabViewIntent, 187);
439
                                }
440
                        } else {
441
                                hideAccountDialog();
442
                                if(app.isLoggingIn()){
443
                                        showAlert("Login Failure", "Authentication failed.  Please check your User Name and API Key.");
444
                                }
445
                        }
446
                }
447
        }
448

    
449
        
450

    
451
        }