1/*
2 * Copyright (C) 2012 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
17package com.android.settings.accounts;
18
19import android.accounts.Account;
20import android.accounts.AccountManager;
21import android.accounts.AuthenticatorDescription;
22import android.content.Context;
23import android.content.pm.PackageManager;
24import android.content.res.Resources;
25import android.graphics.drawable.Drawable;
26import android.os.AsyncTask;
27import android.util.Log;
28
29import java.util.ArrayList;
30import java.util.HashMap;
31import java.util.Map;
32
33public class AuthenticatorHelper {
34
35    private static final String TAG = "AuthenticatorHelper";
36    private Map<String, AuthenticatorDescription> mTypeToAuthDescription
37            = new HashMap<String, AuthenticatorDescription>();
38    private AuthenticatorDescription[] mAuthDescs;
39    private ArrayList<String> mEnabledAccountTypes = new ArrayList<String>();
40    private Map<String, Drawable> mAccTypeIconCache = new HashMap<String, Drawable>();
41
42    public AuthenticatorHelper() {
43    }
44
45    public String[] getEnabledAccountTypes() {
46        return mEnabledAccountTypes.toArray(new String[mEnabledAccountTypes.size()]);
47    }
48
49    public void preloadDrawableForType(final Context context, final String accountType) {
50        new AsyncTask<Void, Void, Void>() {
51            @Override
52            protected Void doInBackground(Void... params) {
53                getDrawableForType(context, accountType);
54                return null;
55            }
56        }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, (Void[]) null);
57    }
58
59    /**
60     * Gets an icon associated with a particular account type. If none found, return null.
61     * @param accountType the type of account
62     * @return a drawable for the icon or null if one cannot be found.
63     */
64    public Drawable getDrawableForType(Context context, final String accountType) {
65        Drawable icon = null;
66        synchronized (mAccTypeIconCache) {
67            if (mAccTypeIconCache.containsKey(accountType)) {
68                return mAccTypeIconCache.get(accountType);
69            }
70        }
71        if (mTypeToAuthDescription.containsKey(accountType)) {
72            try {
73                AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
74                Context authContext = context.createPackageContext(desc.packageName, 0);
75                icon = authContext.getResources().getDrawable(desc.iconId);
76                synchronized (mAccTypeIconCache) {
77                    mAccTypeIconCache.put(accountType, icon);
78                }
79            } catch (PackageManager.NameNotFoundException e) {
80            } catch (Resources.NotFoundException e) {
81            }
82        }
83        if (icon == null) {
84            icon = context.getPackageManager().getDefaultActivityIcon();
85        }
86        return icon;
87    }
88
89    /**
90     * Gets the label associated with a particular account type. If none found, return null.
91     * @param accountType the type of account
92     * @return a CharSequence for the label or null if one cannot be found.
93     */
94    public CharSequence getLabelForType(Context context, final String accountType) {
95        CharSequence label = null;
96        if (mTypeToAuthDescription.containsKey(accountType)) {
97            try {
98                AuthenticatorDescription desc = mTypeToAuthDescription.get(accountType);
99                Context authContext = context.createPackageContext(desc.packageName, 0);
100                label = authContext.getResources().getText(desc.labelId);
101            } catch (PackageManager.NameNotFoundException e) {
102                Log.w(TAG, "No label name for account type " + accountType);
103            } catch (Resources.NotFoundException e) {
104                Log.w(TAG, "No label icon for account type " + accountType);
105            }
106        }
107        return label;
108    }
109
110    /**
111     * Updates provider icons. Subclasses should call this in onCreate()
112     * and update any UI that depends on AuthenticatorDescriptions in onAuthDescriptionsUpdated().
113     */
114    public void updateAuthDescriptions(Context context) {
115        mAuthDescs = AccountManager.get(context).getAuthenticatorTypes();
116        for (int i = 0; i < mAuthDescs.length; i++) {
117            mTypeToAuthDescription.put(mAuthDescs[i].type, mAuthDescs[i]);
118        }
119    }
120
121    public void onAccountsUpdated(Context context, Account[] accounts) {
122        if (accounts == null) {
123            accounts = AccountManager.get(context).getAccounts();
124        }
125        mEnabledAccountTypes.clear();
126        mAccTypeIconCache.clear();
127        for (Account account: accounts) {
128            if (!mEnabledAccountTypes.contains(account.type)) {
129                mEnabledAccountTypes.add(account.type);
130            }
131        }
132    }
133
134    public boolean containsAccountType(String accountType) {
135        return mTypeToAuthDescription.containsKey(accountType);
136    }
137
138    public AuthenticatorDescription getAccountTypeDescription(String accountType) {
139        return mTypeToAuthDescription.get(accountType);
140    }
141
142    public boolean hasAccountPreferences(final String accountType) {
143        if (containsAccountType(accountType)) {
144            AuthenticatorDescription desc = getAccountTypeDescription(accountType);
145            if (desc != null && desc.accountPreferencesId != 0) {
146                return true;
147            }
148        }
149        return false;
150    }
151}
152