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