ChooseAccountTypeActivity.java revision 1121bb5e6ff20a2c694225300507ed486e04fea2
11121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana/*
21121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * Copyright (C) 2011 The Android Open Source Project
31121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana *
41121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * Licensed under the Apache License, Version 2.0 (the "License");
51121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * you may not use this file except in compliance with the License.
61121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * You may obtain a copy of the License at
71121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana *
81121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana *      http://www.apache.org/licenses/LICENSE-2.0
91121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana *
101121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * Unless required by applicable law or agreed to in writing, software
111121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * distributed under the License is distributed on an "AS IS" BASIS,
121121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * See the License for the specific language governing permissions and
141121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * limitations under the License.
151121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana */
161121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanapackage android.accounts;
171121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
181121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.app.Activity;
191121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.content.Context;
201121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.content.Intent;
211121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.content.pm.PackageManager;
221121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.content.res.Resources;
231121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.graphics.drawable.Drawable;
241121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.os.Bundle;
251121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.util.Log;
261121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.view.LayoutInflater;
271121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.view.View;
281121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.view.ViewGroup;
291121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.AdapterView;
301121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.ArrayAdapter;
311121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.ImageView;
321121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.ListView;
331121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport android.widget.TextView;
341121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport com.android.internal.R;
351121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
361121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.io.IOException;
371121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.ArrayList;
381121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.HashMap;
391121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.HashSet;
401121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.Map;
411121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.Set;
421121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
431121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana/**
441121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * @hide
451121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana */
461121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanapublic class ChooseAccountTypeActivity extends Activity implements AccountManagerCallback<Bundle> {
471121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private static final String TAG = "AccountManager";
481121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
491121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private HashMap<String, AuthInfo> mTypeToAuthenticatorInfo = new HashMap<String, AuthInfo>();
501121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private ArrayList<AuthInfo> mAuthenticatorInfosToDisplay;
511121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
521121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    @Override
531121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    public void onCreate(Bundle savedInstanceState) {
541121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        super.onCreate(savedInstanceState);
551121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        setContentView(R.layout.choose_account);
561121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
571121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // Read the validAccountTypes, if present, and add them to the setOfAllowableAccountTypes
581121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        Set<String> setOfAllowableAccountTypes = null;
591121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        ArrayList<String> validAccountTypes = getIntent().getStringArrayListExtra(
601121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_ARRAYLIST);
611121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        if (validAccountTypes != null) {
621121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            setOfAllowableAccountTypes = new HashSet<String>(validAccountTypes.size());
631121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            for (String type : validAccountTypes) {
641121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                setOfAllowableAccountTypes.add(type);
651121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
661121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
671121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
681121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // create a map of account authenticators
691121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        buildTypeToAuthDescriptionMap();
701121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
711121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // Create a list of authenticators that are allowable. Filter out those that
721121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // don't match the allowable account types, if provided.
731121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        mAuthenticatorInfosToDisplay = new ArrayList<AuthInfo>(mTypeToAuthenticatorInfo.size());
741121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        for (Map.Entry<String, AuthInfo> entry: mTypeToAuthenticatorInfo.entrySet()) {
751121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            final String type = entry.getKey();
761121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            final AuthInfo info = entry.getValue();
771121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            if (setOfAllowableAccountTypes != null
781121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    && !setOfAllowableAccountTypes.contains(type)) {
791121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                continue;
801121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
811121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            mAuthenticatorInfosToDisplay.add(info);
821121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
831121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
841121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        if (mAuthenticatorInfosToDisplay.isEmpty()) {
851121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            Bundle bundle = new Bundle();
861121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "no allowable account types");
871121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
881121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            finish();
891121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            return;
901121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
911121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
921121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        if (mAuthenticatorInfosToDisplay.size() == 1) {
931121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            runAddAccountForAuthenticator(mAuthenticatorInfosToDisplay.get(0));
941121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            return;
951121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
961121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
971121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // Setup the list
981121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        ListView list = (ListView) findViewById(android.R.id.list);
991121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // Use an existing ListAdapter that will map an array of strings to TextViews
1001121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        list.setAdapter(new AccountArrayAdapter(this,
1011121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                android.R.layout.simple_list_item_1, mAuthenticatorInfosToDisplay));
1021121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        list.setChoiceMode(ListView.CHOICE_MODE_NONE);
1031121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        list.setTextFilterEnabled(false);
1041121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
1051121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
1061121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                runAddAccountForAuthenticator(mAuthenticatorInfosToDisplay.get(position));
1071121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
1081121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        });
1091121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1101121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1111121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private void buildTypeToAuthDescriptionMap() {
1121121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) {
1131121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            String name = null;
1141121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            Drawable icon = null;
1151121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            try {
1161121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                Context authContext = createPackageContext(desc.packageName, 0);
1171121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                icon = authContext.getResources().getDrawable(desc.iconId);
1181121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                final CharSequence sequence = authContext.getResources().getText(desc.labelId);
1191121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                if (sequence != null) {
1201121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    name = sequence.toString();
1211121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                }
1221121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                name = sequence.toString();
1231121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            } catch (PackageManager.NameNotFoundException e) {
1241121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                // Nothing we can do much here, just log
1251121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                if (Log.isLoggable(TAG, Log.WARN)) {
1261121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    Log.w(TAG, "No icon name for account type " + desc.type);
1271121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                }
1281121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            } catch (Resources.NotFoundException e) {
1291121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                // Nothing we can do much here, just log
1301121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                if (Log.isLoggable(TAG, Log.WARN)) {
1311121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    Log.w(TAG, "No icon resource for account type " + desc.type);
1321121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                }
1331121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
1341121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            AuthInfo authInfo = new AuthInfo(desc, name, icon);
1351121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            mTypeToAuthenticatorInfo.put(desc.type, authInfo);
1361121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
1371121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1381121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1391121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    protected void runAddAccountForAuthenticator(AuthInfo authInfo) {
1401121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        Log.d(TAG, "selected account type " + authInfo.name);
1411121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        Bundle options = getIntent().getBundleExtra(
1421121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                ChooseTypeAndAccountActivity.EXTRA_ADD_ACCOUNT_OPTIONS_BUNDLE);
1431121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        AccountManager.get(this).addAccount(authInfo.desc.type, null, null, options,
1441121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                this, this, null);
1451121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1461121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1471121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    public void run(final AccountManagerFuture<Bundle> accountManagerFuture) {
1481121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        try {
1491121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            Bundle accountManagerResult = accountManagerFuture.getResult();
1501121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            Bundle bundle = new Bundle();
1511121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            bundle.putString(AccountManager.KEY_ACCOUNT_NAME,
1521121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    accountManagerResult.getString(AccountManager.KEY_ACCOUNT_NAME));
1531121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            bundle.putString(AccountManager.KEY_ACCOUNT_TYPE,
1541121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    accountManagerResult.getString(AccountManager.KEY_ACCOUNT_TYPE));
1551121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
1561121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            finish();
1571121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            return;
1581121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        } catch (OperationCanceledException e) {
1591121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            setResult(Activity.RESULT_CANCELED);
1601121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            finish();
1611121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            return;
1621121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        } catch (IOException e) {
1631121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        } catch (AuthenticatorException e) {
1641121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
1651121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        Bundle bundle = new Bundle();
1661121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "error communicating with server");
1671121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
1681121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        finish();
1691121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1701121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1711121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private static class AuthInfo {
1721121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        final AuthenticatorDescription desc;
1731121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        final String name;
1741121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        final Drawable drawable;
1751121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1761121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        AuthInfo(AuthenticatorDescription desc, String name, Drawable drawable) {
1771121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            this.desc = desc;
1781121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            this.name = name;
1791121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            this.drawable = drawable;
1801121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
1811121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1821121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1831121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private static class ViewHolder {
1841121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        ImageView icon;
1851121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        TextView text;
1861121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1871121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1881121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private static class AccountArrayAdapter extends ArrayAdapter<AuthInfo> {
1891121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        private LayoutInflater mLayoutInflater;
1901121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        private ArrayList<AuthInfo> mInfos;
1911121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1921121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        public AccountArrayAdapter(Context context, int textViewResourceId,
1931121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                ArrayList<AuthInfo> infos) {
1941121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            super(context, textViewResourceId, infos);
1951121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            mInfos = infos;
1961121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            mLayoutInflater = (LayoutInflater) context.getSystemService(
1971121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    Context.LAYOUT_INFLATER_SERVICE);
1981121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
1991121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
2001121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        @Override
2011121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        public View getView(int position, View convertView, ViewGroup parent) {
2021121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            ViewHolder holder;
2031121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
2041121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            if (convertView == null) {
2051121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null);
2061121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                holder = new ViewHolder();
2071121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                holder.text = (TextView) convertView.findViewById(R.id.account_row_text);
2081121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon);
2091121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                convertView.setTag(holder);
2101121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            } else {
2111121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                holder = (ViewHolder) convertView.getTag();
2121121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
2131121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
2141121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            holder.text.setText(mInfos.get(position).name);
2151121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            holder.icon.setImageDrawable(mInfos.get(position).drawable);
2161121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
2171121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            return convertView;
2181121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
2191121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
2201121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana}
221