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.util.ArrayList;
371121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.HashMap;
381121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.HashSet;
391121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.Map;
401121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintanaimport java.util.Set;
411121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
421121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana/**
431121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana * @hide
441121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana */
459bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintanapublic class ChooseAccountTypeActivity extends Activity {
460c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana    private static final String TAG = "AccountChooser";
471121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
481121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private HashMap<String, AuthInfo> mTypeToAuthenticatorInfo = new HashMap<String, AuthInfo>();
491121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private ArrayList<AuthInfo> mAuthenticatorInfosToDisplay;
501121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
511121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    @Override
521121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    public void onCreate(Bundle savedInstanceState) {
531121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        super.onCreate(savedInstanceState);
541121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
550c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana        if (Log.isLoggable(TAG, Log.VERBOSE)) {
560c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana            Log.v(TAG, "ChooseAccountTypeActivity.onCreate(savedInstanceState="
570c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana                    + savedInstanceState + ")");
580c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana        }
590c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana
601121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // Read the validAccountTypes, if present, and add them to the setOfAllowableAccountTypes
611121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        Set<String> setOfAllowableAccountTypes = null;
62a77253a417e885f87280901a3519412262758412Fred Quintana        String[] validAccountTypes = getIntent().getStringArrayExtra(
63b04fe4e82abb073b4e5d82563b0882cea0dcc139Fred Quintana                ChooseTypeAndAccountActivity.EXTRA_ALLOWABLE_ACCOUNT_TYPES_STRING_ARRAY);
641121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        if (validAccountTypes != null) {
65a77253a417e885f87280901a3519412262758412Fred Quintana            setOfAllowableAccountTypes = new HashSet<String>(validAccountTypes.length);
661121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            for (String type : validAccountTypes) {
671121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                setOfAllowableAccountTypes.add(type);
681121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
691121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
701121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
711121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // create a map of account authenticators
721121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        buildTypeToAuthDescriptionMap();
731121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
741121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // Create a list of authenticators that are allowable. Filter out those that
751121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // don't match the allowable account types, if provided.
761121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        mAuthenticatorInfosToDisplay = new ArrayList<AuthInfo>(mTypeToAuthenticatorInfo.size());
771121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        for (Map.Entry<String, AuthInfo> entry: mTypeToAuthenticatorInfo.entrySet()) {
781121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            final String type = entry.getKey();
791121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            final AuthInfo info = entry.getValue();
801121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            if (setOfAllowableAccountTypes != null
811121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    && !setOfAllowableAccountTypes.contains(type)) {
821121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                continue;
831121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
841121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            mAuthenticatorInfosToDisplay.add(info);
851121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
861121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
871121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        if (mAuthenticatorInfosToDisplay.isEmpty()) {
881121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            Bundle bundle = new Bundle();
891121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            bundle.putString(AccountManager.KEY_ERROR_MESSAGE, "no allowable account types");
901121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
911121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            finish();
921121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            return;
931121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
941121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
951121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        if (mAuthenticatorInfosToDisplay.size() == 1) {
969bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana            setResultAndFinish(mAuthenticatorInfosToDisplay.get(0).desc.type);
971121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            return;
981121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
991121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1009bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana        setContentView(R.layout.choose_account_type);
1011121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // Setup the list
1021121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        ListView list = (ListView) findViewById(android.R.id.list);
1031121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        // Use an existing ListAdapter that will map an array of strings to TextViews
1041121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        list.setAdapter(new AccountArrayAdapter(this,
1051121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                android.R.layout.simple_list_item_1, mAuthenticatorInfosToDisplay));
1061121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        list.setChoiceMode(ListView.CHOICE_MODE_NONE);
1071121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        list.setTextFilterEnabled(false);
1081121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
1091121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
1109bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana                setResultAndFinish(mAuthenticatorInfosToDisplay.get(position).desc.type);
1111121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
1121121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        });
1131121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1141121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1159bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana    private void setResultAndFinish(final String type) {
1169bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana        Bundle bundle = new Bundle();
1179bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana        bundle.putString(AccountManager.KEY_ACCOUNT_TYPE, type);
1189bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana        setResult(Activity.RESULT_OK, new Intent().putExtras(bundle));
1190c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana        if (Log.isLoggable(TAG, Log.VERBOSE)) {
1200c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana            Log.v(TAG, "ChooseAccountTypeActivity.setResultAndFinish: "
1210c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana                    + "selected account type " + type);
1220c65ba4cd9ef82069ef44f046e934b2daa64d023Fred Quintana        }
1239bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana        finish();
1249bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana    }
1259bbdd0bf5006512a000b0d3e6bd6ee2998a2e48bFred Quintana
1261121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private void buildTypeToAuthDescriptionMap() {
1271121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) {
1281121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            String name = null;
1291121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            Drawable icon = null;
1301121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            try {
1311121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                Context authContext = createPackageContext(desc.packageName, 0);
1328eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette                icon = authContext.getDrawable(desc.iconId);
1331121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                final CharSequence sequence = authContext.getResources().getText(desc.labelId);
1341121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                if (sequence != null) {
1351121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    name = sequence.toString();
1361121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                }
1371121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                name = sequence.toString();
1381121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            } catch (PackageManager.NameNotFoundException e) {
1391121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                // Nothing we can do much here, just log
1401121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                if (Log.isLoggable(TAG, Log.WARN)) {
1411121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    Log.w(TAG, "No icon name for account type " + desc.type);
1421121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                }
1431121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            } catch (Resources.NotFoundException e) {
1441121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                // Nothing we can do much here, just log
1451121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                if (Log.isLoggable(TAG, Log.WARN)) {
1461121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    Log.w(TAG, "No icon resource for account type " + desc.type);
1471121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                }
1481121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
1491121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            AuthInfo authInfo = new AuthInfo(desc, name, icon);
1501121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            mTypeToAuthenticatorInfo.put(desc.type, authInfo);
1511121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
1521121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1531121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1541121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private static class AuthInfo {
1551121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        final AuthenticatorDescription desc;
1561121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        final String name;
1571121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        final Drawable drawable;
1581121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1591121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        AuthInfo(AuthenticatorDescription desc, String name, Drawable drawable) {
1601121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            this.desc = desc;
1611121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            this.name = name;
1621121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            this.drawable = drawable;
1631121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
1641121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1651121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1661121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private static class ViewHolder {
1671121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        ImageView icon;
1681121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        TextView text;
1691121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
1701121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1711121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    private static class AccountArrayAdapter extends ArrayAdapter<AuthInfo> {
1721121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        private LayoutInflater mLayoutInflater;
1731121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        private ArrayList<AuthInfo> mInfos;
1741121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1751121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        public AccountArrayAdapter(Context context, int textViewResourceId,
1761121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                ArrayList<AuthInfo> infos) {
1771121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            super(context, textViewResourceId, infos);
1781121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            mInfos = infos;
1791121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            mLayoutInflater = (LayoutInflater) context.getSystemService(
1801121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                    Context.LAYOUT_INFLATER_SERVICE);
1811121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
1821121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1831121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        @Override
1841121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        public View getView(int position, View convertView, ViewGroup parent) {
1851121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            ViewHolder holder;
1861121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1871121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            if (convertView == null) {
1881121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                convertView = mLayoutInflater.inflate(R.layout.choose_account_row, null);
1891121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                holder = new ViewHolder();
1901121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                holder.text = (TextView) convertView.findViewById(R.id.account_row_text);
1911121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                holder.icon = (ImageView) convertView.findViewById(R.id.account_row_icon);
1921121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                convertView.setTag(holder);
1931121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            } else {
1941121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana                holder = (ViewHolder) convertView.getTag();
1951121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            }
1961121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
1971121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            holder.text.setText(mInfos.get(position).name);
1981121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            holder.icon.setImageDrawable(mInfos.get(position).drawable);
1991121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana
2001121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana            return convertView;
2011121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana        }
2021121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana    }
2031121bb5e6ff20a2c694225300507ed486e04fea2Fred Quintana}
204