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 
56         mAccounts = getIntent().getParcelableArrayExtra(AccountManager.KEY_ACCOUNTS);
57         mAccountManagerResponse =
58                 getIntent().getParcelableExtra(AccountManager.KEY_ACCOUNT_MANAGER_RESPONSE);
59 
60         // KEY_ACCOUNTS is a required parameter
61         if (mAccounts == null) {
62             setResult(RESULT_CANCELED);
63             finish();
64             return;
65         }
66 
67         getAuthDescriptions();
68 
69         AccountInfo[] mAccountInfos = new AccountInfo[mAccounts.length];
70         for (int i = 0; i < mAccounts.length; i++) {
71             mAccountInfos[i] = new AccountInfo(((Account) mAccounts[i]).name,
72                     getDrawableForType(((Account) mAccounts[i]).type));
73         }
74 
75         setContentView(R.layout.choose_account);
76 
77         // Setup the list
78         ListView list = (ListView) findViewById(android.R.id.list);
79         // Use an existing ListAdapter that will map an array of strings to TextViews
80         list.setAdapter(new AccountArrayAdapter(this,
81                 android.R.layout.simple_list_item_1, mAccountInfos));
82         list.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
83         list.setTextFilterEnabled(true);
84         list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
85             public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
86                 onListItemClick((ListView)parent, v, position, id);
87             }
88         });
89     }
90 
getAuthDescriptions()91     private void getAuthDescriptions() {
92         for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) {
93             mTypeToAuthDescription.put(desc.type, desc);
94         }
95     }
96 
getDrawableForType(String accountType)97     private Drawable getDrawableForType(String accountType) {
98         Drawable icon = null;
99         if(mTypeToAuthDescription.containsKey(accountType)) {
100             try {
101                 AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
102                 Context authContext = createPackageContext(desc.packageName, 0);
103                 icon = authContext.getDrawable(desc.iconId);
104             } catch (PackageManager.NameNotFoundException e) {
105                 // Nothing we can do much here, just log
106                 if (Log.isLoggable(TAG, Log.WARN)) {
107                     Log.w(TAG, "No icon name for account type " + accountType);
108                 }
109             } catch (Resources.NotFoundException e) {
110                 // Nothing we can do much here, just log
111                 if (Log.isLoggable(TAG, Log.WARN)) {
112                     Log.w(TAG, "No icon resource for account type " + accountType);
113                 }
114             }
115         }
116         return icon;
117     }
118 
onListItemClick(ListView l, View v, int position, long id)119     protected void onListItemClick(ListView l, View v, int position, long id) {
120         Account account = (Account) mAccounts[position];
121         Log.d(TAG, "selected account " + account);
122         Bundle bundle = new Bundle();
123         bundle.putString(AccountManager.KEY_ACCOUNT_NAME, account.name);
124         bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, account.type);
125         mResult = bundle;
126         finish();
127     }
128 
finish()129     public void finish() {
130         if (mAccountManagerResponse != null) {
131             if (mResult != null) {
132                 mAccountManagerResponse.onResult(mResult);
133             } else {
134                 mAccountManagerResponse.onError(AccountManager.ERROR_CODE_CANCELED, "canceled");
135             }
136         }
137         super.finish();
138     }
139 
140     private static class AccountInfo {
141         final String name;
142         final Drawable drawable;
143 
AccountInfo(String name, Drawable drawable)144         AccountInfo(String name, Drawable drawable) {
145             this.name = name;
146             this.drawable = drawable;
147         }
148     }
149 
150     private static class ViewHolder {
151         ImageView icon;
152         TextView text;
153     }
154 
155     private static class AccountArrayAdapter extends ArrayAdapter<AccountInfo> {
156         private LayoutInflater mLayoutInflater;
157         private AccountInfo[] mInfos;
158 
AccountArrayAdapter(Context context, int textViewResourceId, AccountInfo[] infos)159         public AccountArrayAdapter(Context context, int textViewResourceId, AccountInfo[] infos) {
160             super(context, textViewResourceId, infos);
161             mInfos = infos;
162             mLayoutInflater = (LayoutInflater) context.getSystemService(
163                     Context.LAYOUT_INFLATER_SERVICE);
164         }
165 
166         @Override
getView(int position, View convertView, ViewGroup parent)167         public View getView(int position, View convertView, ViewGroup parent) {
168             ViewHolder holder;
169 
170             if (convertView == null) {
171                 convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null);
172                 holder = new ViewHolder();
173                 holder.text = (TextView) convertView.findViewById(R.id.account_row_text);
174                 holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon);
175                 convertView.setTag(holder);
176             } else {
177                 holder = (ViewHolder) convertView.getTag();
178             }
179 
180             holder.text.setText(mInfos[position].name);
181             holder.icon.setImageDrawable(mInfos[position].drawable);
182 
183             return convertView;
184         }
185     }
186 }
187