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 */
16package android.accounts;
17
18import android.app.Activity;
19import android.content.Context;
20import android.content.pm.PackageManager;
21import android.content.res.Resources;
22import android.graphics.drawable.Drawable;
23import android.os.Bundle;
24import android.os.Parcelable;
25import android.util.Log;
26import android.view.LayoutInflater;
27import android.view.View;
28import android.view.ViewGroup;
29import android.widget.AdapterView;
30import android.widget.ArrayAdapter;
31import android.widget.ImageView;
32import android.widget.ListView;
33import android.widget.TextView;
34import com.android.internal.R;
35
36import java.util.HashMap;
37
38/**
39 * @hide
40 */
41public 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
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
91    private void getAuthDescriptions() {
92        for(AuthenticatorDescription desc : AccountManager.get(this).getAuthenticatorTypes()) {
93            mTypeToAuthDescription.put(desc.type, desc);
94        }
95    }
96
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.getResources().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
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
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
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
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
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