143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani/* 243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Copyright (C) 2008 The Android Open Source Project 343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * 443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Licensed under the Apache License, Version 2.0 (the "License"); 543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * you may not use this file except in compliance with the License. 643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * You may obtain a copy of the License at 743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * 843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * http://www.apache.org/licenses/LICENSE-2.0 943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * 1043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Unless required by applicable law or agreed to in writing, software 1143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * distributed under the License is distributed on an "AS IS" BASIS, 1243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * See the License for the specific language governing permissions and 1443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * limitations under the License. 1543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani */ 1643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 1743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasanipackage com.android.settings.accounts; 1843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 1943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.ArrayList; 20d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport java.util.Date; 2143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.HashMap; 2243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.Map; 2343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 2443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport com.android.settings.SettingsPreferenceFragment; 2543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport com.google.android.collect.Maps; 2643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 2743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.Account; 2843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AccountManager; 2943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AuthenticatorDescription; 3043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.OnAccountsUpdateListener; 31d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.app.Activity; 3243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.ContentResolver; 3343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.Context; 3443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.SyncAdapterType; 3543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.SyncStatusObserver; 3643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.pm.PackageManager; 37d26321eecb481528c5e54a608f2f3c4cc26d8a77Brian Carlstromimport android.content.res.Resources; 3843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.graphics.drawable.Drawable; 3943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.os.Bundle; 4043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.os.Handler; 4143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.preference.PreferenceActivity; 4243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.preference.PreferenceScreen; 43d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasaniimport android.text.format.DateFormat; 4443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.util.Log; 4543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 4643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniclass AccountPreferenceBase extends SettingsPreferenceFragment 4743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani implements OnAccountsUpdateListener { 4843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 4943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani protected static final String TAG = "AccountSettings"; 5043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani public static final String AUTHORITIES_FILTER_KEY = "authorities"; 5143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani public static final String ACCOUNT_TYPES_FILTER_KEY = "account_types"; 5243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani private final Handler mHandler = new Handler(); 5343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani private Object mStatusChangeListenerHandle; 5443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani private HashMap<String, ArrayList<String>> mAccountTypeToAuthorities = null; 55d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani private AuthenticatorHelper mAuthenticatorHelper = new AuthenticatorHelper(); 56d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani private java.text.DateFormat mDateFormat; 57d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani private java.text.DateFormat mTimeFormat; 5843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 5943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani /** 6043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Overload to handle account updates. 6143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani */ 6243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani public void onAccountsUpdated(Account[] accounts) { 6343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 6443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 6543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 6643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani /** 6743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Overload to handle authenticator description updates 6843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani */ 6943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani protected void onAuthDescriptionsUpdated() { 7043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 7143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 7243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 7343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani /** 7443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Overload to handle sync state updates. 7543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani */ 7643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani protected void onSyncStateUpdated() { 7743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 7843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 7943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 8043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani @Override 81d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani public void onActivityCreated(Bundle savedInstanceState) { 82d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani super.onActivityCreated(savedInstanceState); 83d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani 84d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani final Activity activity = getActivity(); 85d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani 86d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani mDateFormat = DateFormat.getDateFormat(activity); 87d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani mTimeFormat = DateFormat.getTimeFormat(activity); 88d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani } 89d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani 90d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani @Override 9143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani public void onResume() { 9243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani super.onResume(); 9343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani mStatusChangeListenerHandle = ContentResolver.addStatusChangeListener( 9443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani ContentResolver.SYNC_OBSERVER_TYPE_ACTIVE 9543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani | ContentResolver.SYNC_OBSERVER_TYPE_STATUS 9643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani | ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, 9743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani mSyncStatusObserver); 9843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani onSyncStateUpdated(); 9943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 10043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 10143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani @Override 10243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani public void onPause() { 10343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani super.onPause(); 10443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani ContentResolver.removeStatusChangeListener(mStatusChangeListenerHandle); 10543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 10643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 10743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani private SyncStatusObserver mSyncStatusObserver = new SyncStatusObserver() { 10843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani public void onStatusChanged(int which) { 10943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani mHandler.post(new Runnable() { 11043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani public void run() { 11143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani onSyncStateUpdated(); 11243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 11343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani }); 11443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 11543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani }; 11643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 11743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani public ArrayList<String> getAuthoritiesForAccountType(String type) { 11843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani if (mAccountTypeToAuthorities == null) { 11943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani mAccountTypeToAuthorities = Maps.newHashMap(); 12043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes(); 12143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani for (int i = 0, n = syncAdapters.length; i < n; i++) { 12243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani final SyncAdapterType sa = syncAdapters[i]; 12343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani ArrayList<String> authorities = mAccountTypeToAuthorities.get(sa.accountType); 12443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani if (authorities == null) { 12543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani authorities = new ArrayList<String>(); 12643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani mAccountTypeToAuthorities.put(sa.accountType, authorities); 12743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 12843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani if (Log.isLoggable(TAG, Log.VERBOSE)) { 129d26321eecb481528c5e54a608f2f3c4cc26d8a77Brian Carlstrom Log.d(TAG, "added authority " + sa.authority + " to accountType " 13043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani + sa.accountType); 13143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 13243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani authorities.add(sa.authority); 13343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 13443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 13543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani return mAccountTypeToAuthorities.get(type); 13643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 13743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 13843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani /** 13943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * Gets the preferences.xml file associated with a particular account type. 14043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * @param accountType the type of account 14143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani * @return a PreferenceScreen inflated from accountPreferenceId. 14243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani */ 143d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani public PreferenceScreen addPreferencesForType(final String accountType, 144d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani PreferenceScreen parent) { 14543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani PreferenceScreen prefs = null; 146d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani if (mAuthenticatorHelper.containsAccountType(accountType)) { 14743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani AuthenticatorDescription desc = null; 14843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani try { 149d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani desc = mAuthenticatorHelper.getAccountTypeDescription(accountType); 15043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani if (desc != null && desc.accountPreferencesId != 0) { 15143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani Context authContext = getActivity().createPackageContext(desc.packageName, 0); 15243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani prefs = getPreferenceManager().inflateFromResource(authContext, 153d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani desc.accountPreferencesId, parent); 15443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 15543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } catch (PackageManager.NameNotFoundException e) { 15643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani Log.w(TAG, "Couldn't load preferences.xml file from " + desc.packageName); 157d26321eecb481528c5e54a608f2f3c4cc26d8a77Brian Carlstrom } catch (Resources.NotFoundException e) { 158d26321eecb481528c5e54a608f2f3c4cc26d8a77Brian Carlstrom Log.w(TAG, "Couldn't load preferences.xml file from " + desc.packageName); 15943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 16043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 16143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani return prefs; 16243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 16343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani 164d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani public void updateAuthDescriptions() { 165d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani mAuthenticatorHelper.updateAuthDescriptions(getActivity()); 16643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani onAuthDescriptionsUpdated(); 16743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani } 168d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani 169d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani protected Drawable getDrawableForType(final String accountType) { 170d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani return mAuthenticatorHelper.getDrawableForType(getActivity(), accountType); 171d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani } 172d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani 173d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani protected CharSequence getLabelForType(final String accountType) { 174d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani return mAuthenticatorHelper.getLabelForType(getActivity(), accountType); 175d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani } 176d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani 177d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani protected String formatSyncDate(Date date) { 178d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani // TODO: Switch to using DateUtils.formatDateTime 179d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani return mDateFormat.format(date) + " " + mTimeFormat.format(date); 180d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani } 18143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani} 182