Home | History | Annotate | Download | only in accounts
      1 /*
      2  * Copyright (C) 2011 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.Intent;
     21 import android.content.pm.PackageManager;
     22 import android.content.res.Resources;
     23 import android.graphics.drawable.Drawable;
     24 import android.os.Bundle;
     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.ArrayList;
     37 import java.util.HashMap;
     38 import java.util.HashSet;
     39 import java.util.Map;
     40 import java.util.Set;
     41 
     42 /**
     43  * @hide
     44  */
     45 public class ChooseAccountTypeActivity extends Activity {
     46     private static final String TAG = "AccountChooser";
     47 
     48     private HashMap<String, AuthInfo> mTypeToAuthenticatorInfo = new HashMap<String, AuthInfo>();
     49     private ArrayList<AuthInfo> mAuthenticatorInfosToDisplay;
     50 
     51     @Override
     52     public void onCreate(Bundle savedInstanceState) {
     53         super.onCreate(savedInstanceState);
     54 
     55         if (Log.isLoggable(TAG, Log.VERBOSE)) {
     56             Log.v(TAG, "ChooseAccountTypeActivity.onCreate(savedInstanceState="
     57                     + savedInstanceState + ")");
     58         }
     59 
     60         // Read the validAccountTypes, if present, and add them to the setOfAllowableAccountTypes
     61         Set<String> setOfAllowableAccountTypes = null;
     62         String[] validAccountTypes = getIntent().getStringArrayExtra(
     63                 ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY);
     64         if (validAccountTypes != null) {
     65             setOfAllowableAccountTypes = new HashSet<String>(validAccountTypes.length);
     66             for (String type : validAccountTypes) {
     67                 setOfAllowableAccountTypes.add(type);
     68             }
     69         }
     70 
     71         // create a map of account authenticators
     72         buildTypeToAuthDescriptionMap();
     73 
     74         // Create a list of authenticators that are allowable. Filter out those that
     75         // don't match the allowable account types, if provided.
     76         mAuthenticatorInfosToDisplay = new ArrayList<AuthInfo>(mTypeToAuthenticatorInfo.size());
     77         for (Map.Entry<String, AuthInfo> entry: mTypeToAuthenticatorInfo.entrySet()) {
     78             final String type = entry.getKey();
     79             final AuthInfo info = entry.getValue();
     80             if (setOfAllowableAccountTypes != null
     81                     && !setOfAllowableAccountTypes.contains(type)) {
     82                 continue;
     83             }
     84             mAuthenticatorInfosToDisplay.add(info);
     85         }
     86 
     87         if (mAuthenticatorInfosToDisplay.isEmpty()) {
     88             Bundle bundle = new Bundle();
     89             bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "no allowable account types");
     90             setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
     91             finish();
     92             return;
     93         }
     94 
     95         if (mAuthenticatorInfosToDisplay.size() == 1) {
     96             setResultAndFinish(mAuthenticatorInfosToDisplay.get(0).desc.type);
     97             return;
     98         }
     99 
    100         setContentView(R.layout.choose_account_type);
    101         // Setup the list
    102         ListView list = (ListView) findViewById(android.R.id.list);
    103         // Use an existing ListAdapter that will map an array of strings to TextViews
    104         list.setAdapter(new AccountArrayAdapter(this,
    105                 android.R.layout.simple_list_item_1, mAuthenticatorInfosToDisplay));
    106         list.setChoiceMode(ListView.CHOICE_MODE_NONE);
    107         list.setTextFilterEnabled(false);
    108         list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    109             public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
    110                 setResultAndFinish(mAuthenticatorInfosToDisplay.get(position).desc.type);
    111             }
    112         });
    113     }
    114 
    115     private void setResultAndFinish(final String type) {
    116         Bundle bundle = new Bundle();
    117         bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, type);
    118         setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
    119         if (Log.isLoggable(TAG, Log.VERBOSE)) {
    120             Log.v(TAG, "ChooseAccountTypeActivity.setResultAndFinish: "
    121                     + "selected account type " + type);
    122         }
    123         finish();
    124     }
    125 
    126     private void buildTypeToAuthDescriptionMap() {
    127         for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) {
    128             String name = null;
    129             Drawable icon = null;
    130             try {
    131                 Context authContext = createPackageContext(desc.packageName, 0);
    132                 icon = authContext.getResources().getDrawable(desc.iconId);
    133                 final CharSequence sequence = authContext.getResources().getText(desc.labelId);
    134                 if (sequence != null) {
    135                     name = sequence.toString();
    136                 }
    137                 name = sequence.toString();
    138             } catch (PackageManager.NameNotFoundException e) {
    139                 // Nothing we can do much here, just log
    140                 if (Log.isLoggable(TAG, Log.WARN)) {
    141                     Log.w(TAG, "No icon name for account type " + desc.type);
    142                 }
    143             } catch (Resources.NotFoundException e) {
    144                 // Nothing we can do much here, just log
    145                 if (Log.isLoggable(TAG, Log.WARN)) {
    146                     Log.w(TAG, "No icon resource for account type " + desc.type);
    147                 }
    148             }
    149             AuthInfo authInfo = new AuthInfo(desc, name, icon);
    150             mTypeToAuthenticatorInfo.put(desc.type, authInfo);
    151         }
    152     }
    153 
    154     private static class AuthInfo {
    155         final AuthenticatorDescription desc;
    156         final String name;
    157         final Drawable drawable;
    158 
    159         AuthInfo(AuthenticatorDescription desc, String name, Drawable drawable) {
    160             this.desc = desc;
    161             this.name = name;
    162             this.drawable = drawable;
    163         }
    164     }
    165 
    166     private static class ViewHolder {
    167         ImageView icon;
    168         TextView text;
    169     }
    170 
    171     private static class AccountArrayAdapter extends ArrayAdapter<AuthInfo> {
    172         private LayoutInflater mLayoutInflater;
    173         private ArrayList<AuthInfo> mInfos;
    174 
    175         public AccountArrayAdapter(Context context, int textViewResourceId,
    176                 ArrayList<AuthInfo> infos) {
    177             super(context, textViewResourceId, infos);
    178             mInfos = infos;
    179             mLayoutInflater = (LayoutInflater) context.getSystemService(
    180                     Context.LAYOUT_INFLATER_SERVICE);
    181         }
    182 
    183         @Override
    184         public View getView(int position, View convertView, ViewGroup parent) {
    185             ViewHolder holder;
    186 
    187             if (convertView == null) {
    188                 convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null);
    189                 holder = new ViewHolder();
    190                 holder.text = (TextView) convertView.findViewById(R.id.account_row_text);
    191                 holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon);
    192                 convertView.setTag(holder);
    193             } else {
    194                 holder = (ViewHolder) convertView.getTag();
    195             }
    196 
    197             holder.text.setText(mInfos.get(position).name);
    198             holder.icon.setImageDrawable(mInfos.get(position).drawable);
    199 
    200             return convertView;
    201         }
    202     }
    203 }
    204