1 /*
2  * Copyright (C) 2009 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.accounts;
17 
18 import android.app.Activity;
19 import android.content.Context;
20 import android.content.pm.PackageManager;
21 import android.content.res.Resources;
22 import android.graphics.drawable.Drawable;
23 import android.os.Bundle;
24 import android.os.Parcelable;
25 import android.util.Log;
26 import android.view.LayoutInflater;
27 import android.view.View;
28 import android.view.ViewGroup;
29 import android.widget.AdapterView;
30 import android.widget.ArrayAdapter;
31 import android.widget.ImageView;
32 import android.widget.ListView;
33 import android.widget.TextView;
34 import com.android.internal.R;
35 
36 import java.util.HashMap;
37 
38 /**
39  * @hide
40  */
41 public class ChooseAccountActivity extends Activity {
42 
43     private static final String TAG = "AccountManager";
44 
45     private Parcelable[] mAccounts = null;
46     private AccountManagerResponse mAccountManagerResponse = null;
47     private Bundle mResult;
48 
49     private HashMap<String, AuthenticatorDescription> mTypeToAuthDescription
50             = new HashMap<String, AuthenticatorDescription>();
51 
52     @Override
onCreate(Bundle savedInstanceState)53     public void onCreate(Bundle savedInstanceState) {
54         super.onCreate(savedInstanceState);
55         // TODO This activity is only used by getAuthTokenByFeatures and can not see
56         // VISIBILITY_USER_MANAGED_NOT_VISIBLE accounts. It should be moved to account managed
57         // service.
58         mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS);
59         mAccountManagerResponse =
60                 getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE);
61 
62         // KEY_ACCOUNTS is a required parameter
63         if (mAccounts == null) {
64             setResult(RESULT_CANCELED);
65             finish();
66             return;
67         }
68 
69         getAuthDescriptions();
70 
71         AccountInfo[] mAccountInfos = new AccountInfo[mAccounts.length];
72         for (int i = 0; i < mAccounts.length; i++) {
73             mAccountInfos[i] = new AccountInfo(((Account) mAccounts[i]).name,
74                     getDrawableForType(((Account) mAccounts[i]).type));
75         }
76 
77         setContentView(R.layout.choose_account);
78 
79         // Setup the list
80         ListView list = findViewById(android.R.id.list);
81         // Use an existing ListAdapter that will map an array of strings to TextViews
82         list.setAdapter(new AccountArrayAdapter(this,
83                 android.R.layout.simple_list_item_1, mAccountInfos));
84         list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
85         list.setTextFilterEnabled(true);
86         list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
87             public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
88                 onListItemClick((ListView)parent, v, position, id);
89             }
90         });
91     }
92 
getAuthDescriptions()93     private void getAuthDescriptions() {
94         for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) {
95             mTypeToAuthDescription.put(desc.type, desc);
96         }
97     }
98 
getDrawableForType(String accountType)99     private Drawable getDrawableForType(String accountType) {
100         Drawable icon = null;
101         if(mTypeToAuthDescription.containsKey(accountType)) {
102             try {
103                 AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
104                 Context authContext = createPackageContext(desc.packageName, 0);
105                 icon = authContext.getDrawable(desc.iconId);
106             } catch (PackageManager.NameNotFoundException e) {
107                 // Nothing we can do much here, just log
108                 if (Log.isLoggable(TAG, Log.WARN)) {
109                     Log.w(TAG, "No icon name for account type " + accountType);
110                 }
111             } catch (Resources.NotFoundException e) {
112                 // Nothing we can do much here, just log
113                 if (Log.isLoggable(TAG, Log.WARN)) {
114                     Log.w(TAG, "No icon resource for account type " + accountType);
115                 }
116             }
117         }
118         return icon;
119     }
120 
onListItemClick(ListView l, View v, int position, long id)121     protected void onListItemClick(ListView l, View v, int position, long id) {
122         Account account = (Account) mAccounts[position];
123         Log.d(TAG, "selected account " + account);
124         Bundle bundle = new Bundle();
125         bundle.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
126         bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
127         mResult = bundle;
128         finish();
129     }
130 
finish()131     public void finish() {
132         if (mAccountManagerResponse != null) {
133             if (mResult != null) {
134                 mAccountManagerResponse.onResult(mResult);
135             } else {
136                 mAccountManagerResponse.onError(AccountManager.ERROR_CODE_CANCELED, "canceled");
137             }
138         }
139         super.finish();
140     }
141 
142     private static class AccountInfo {
143         final String name;
144         final Drawable drawable;
145 
AccountInfo(String name, Drawable drawable)146         AccountInfo(String name, Drawable drawable) {
147             this.name = name;
148             this.drawable = drawable;
149         }
150     }
151 
152     private static class ViewHolder {
153         ImageView icon;
154         TextView text;
155     }
156 
157     private static class AccountArrayAdapter extends ArrayAdapter<AccountInfo> {
158         private LayoutInflater mLayoutInflater;
159         private AccountInfo[] mInfos;
160 
AccountArrayAdapter(Context context, int textViewResourceId, AccountInfo[] infos)161         public AccountArrayAdapter(Context context, int textViewResourceId, AccountInfo[] infos) {
162             super(context, textViewResourceId, infos);
163             mInfos = infos;
164             mLayoutInflater = (LayoutInflater) context.getSystemService(
165                     Context.LAYOUT_INFLATER_SERVICE);
166         }
167 
168         @Override
getView(int position, View convertView, ViewGroup parent)169         public View getView(int position, View convertView, ViewGroup parent) {
170             ViewHolder holder;
171 
172             if (convertView == null) {
173                 convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null);
174                 holder = new ViewHolder();
175                 holder.text = (TextView) convertView.findViewById(R.id.account_row_text);
176                 holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon);
177                 convertView.setTag(holder);
178             } else {
179                 holder = (ViewHolder) convertView.getTag();
180             }
181 
182             holder.text.setText(mInfos[position].name);
183             holder.icon.setImageDrawable(mInfos[position].drawable);
184 
185             return convertView;
186         }
187     }
188 }
189