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 android.accounts.Account;
2043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AccountManager;
2143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AccountManagerCallback;
2243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AccountManagerFuture;
2343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.AuthenticatorException;
2443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.accounts.OperationCanceledException;
2543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.app.Activity;
2643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.app.AlertDialog;
2743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.app.Dialog;
2843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.ContentResolver;
2943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.Context;
3043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.DialogInterface;
3143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.SyncAdapterType;
3243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.SyncInfo;
3343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.SyncStatusInfo;
3443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.pm.ProviderInfo;
3543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.net.ConnectivityManager;
3643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.os.Bundle;
370c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthallimport android.os.UserManager;
3843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.preference.Preference;
3943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.preference.PreferenceScreen;
4043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.text.TextUtils;
4143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.util.Log;
4243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.LayoutInflater;
4343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.Menu;
4443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.MenuInflater;
4543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.MenuItem;
4643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.View;
4743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.ViewGroup;
4843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.widget.ImageView;
4997d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkeyimport android.widget.ListView;
5043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.widget.TextView;
5143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
52ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunneimport com.android.settings.R;
5397d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkeyimport com.android.settings.Utils;
54ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunneimport com.google.android.collect.Lists;
55ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunneimport com.google.android.collect.Maps;
56ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne
5743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.io.IOException;
5843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.ArrayList;
59100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglioimport java.util.Collections;
6043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.Date;
6143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.HashMap;
6243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.List;
6343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
6443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasanipublic class AccountSyncSettings extends AccountPreferenceBase {
6543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
6643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public static final String ACCOUNT_KEY = "account";
67d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private static final int MENU_SYNC_NOW_ID       = Menu.FIRST;
68d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private static final int MENU_SYNC_CANCEL_ID    = Menu.FIRST + 1;
69d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private static final int MENU_REMOVE_ACCOUNT_ID = Menu.FIRST + 2;
7043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private static final int REALLY_REMOVE_DIALOG = 100;
7143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private static final int FAILED_REMOVAL_DIALOG = 101;
7243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private static final int CANT_DO_ONETIME_SYNC_DIALOG = 102;
7343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private TextView mUserId;
7443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private TextView mProviderId;
7543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private ImageView mProviderIcon;
7643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private TextView mErrorInfoView;
7743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private Account mAccount;
7843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    // List of all accounts, updated when accounts are added/removed
7943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    // We need to re-scan the accounts on sync events, in case sync state changes.
8043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private Account[] mAccounts;
8143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private ArrayList<SyncStateCheckBoxPreference> mCheckBoxes =
8243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                new ArrayList<SyncStateCheckBoxPreference>();
83193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu    private ArrayList<SyncAdapterType> mInvisibleAdapters = Lists.newArrayList();
8443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
8543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
8643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public Dialog onCreateDialog(final int id) {
8743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        Dialog dialog = null;
8843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (id == REALLY_REMOVE_DIALOG) {
8943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            dialog = new AlertDialog.Builder(getActivity())
9043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setTitle(R.string.really_remove_account_title)
9143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setMessage(R.string.really_remove_account_message)
9243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setNegativeButton(android.R.string.cancel, null)
9343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setPositiveButton(R.string.remove_account_label,
9443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        new DialogInterface.OnClickListener() {
950c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall                    @Override
9643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    public void onClick(DialogInterface dialog, int which) {
9743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        AccountManager.get(AccountSyncSettings.this.getActivity())
9843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                .removeAccount(mAccount,
9943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                new AccountManagerCallback<Boolean>() {
1000c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall                            @Override
10143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                            public void run(AccountManagerFuture<Boolean> future) {
102e88be4f6205b0e039de5ab32e4e3fbefd2dc926dAmith Yamasani                                // If already out of this screen, don't proceed.
103e88be4f6205b0e039de5ab32e4e3fbefd2dc926dAmith Yamasani                                if (!AccountSyncSettings.this.isResumed()) {
104e88be4f6205b0e039de5ab32e4e3fbefd2dc926dAmith Yamasani                                    return;
105e88be4f6205b0e039de5ab32e4e3fbefd2dc926dAmith Yamasani                                }
10643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                boolean failed = true;
10743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                try {
10843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    if (future.getResult() == true) {
10943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                        failed = false;
11043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    }
11143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                } catch (OperationCanceledException e) {
11243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    // handled below
11343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                } catch (IOException e) {
11443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    // handled below
11543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                } catch (AuthenticatorException e) {
11643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    // handled below
11743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                }
11863c91f0973c64fd6fb2b1654522b9dfee294eda7Tony Guo                                if (failed && getActivity() != null &&
11963c91f0973c64fd6fb2b1654522b9dfee294eda7Tony Guo                                        !getActivity().isFinishing()) {
12043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    showDialog(FAILED_REMOVAL_DIALOG);
12143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                } else {
12243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    finish();
12343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                }
12443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                            }
12543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        }, null);
12643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    }
12743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                })
12843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .create();
12943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        } else if (id == FAILED_REMOVAL_DIALOG) {
13043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            dialog = new AlertDialog.Builder(getActivity())
13143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setTitle(R.string.really_remove_account_title)
13243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setPositiveButton(android.R.string.ok, null)
13343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setMessage(R.string.remove_account_failed)
13443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .create();
13543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        } else if (id == CANT_DO_ONETIME_SYNC_DIALOG) {
13643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            dialog = new AlertDialog.Builder(getActivity())
13743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setTitle(R.string.cant_sync_dialog_title)
13843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setMessage(R.string.cant_sync_dialog_message)
13943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setPositiveButton(android.R.string.ok, null)
14043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .create();
14143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
14243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        return dialog;
14343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
14443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
14543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
14643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onCreate(Bundle icicle) {
14743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onCreate(icicle);
14843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
14943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        setHasOptionsMenu(true);
15043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
15143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
15243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
15343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public View onCreateView(LayoutInflater inflater, ViewGroup container,
15443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Bundle savedInstanceState) {
15543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        final View view = inflater.inflate(R.layout.account_sync_screen, container, false);
15697d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkey
15797d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkey        final ListView list = (ListView) view.findViewById(android.R.id.list);
15897d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkey        Utils.prepareCustomPreferencesList(container, view, list, false);
15997d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkey
16043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        initializeUi(view);
16143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
16243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        return view;
16343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
16443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
16543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    protected void initializeUi(final View rootView) {
16643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        addPreferencesFromResource(R.xml.account_sync_settings);
16743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
16843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mErrorInfoView = (TextView) rootView.findViewById(R.id.sync_settings_error_info);
16943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mErrorInfoView.setVisibility(View.GONE);
17043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
17143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mUserId = (TextView) rootView.findViewById(R.id.user_id);
17243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mProviderId = (TextView) rootView.findViewById(R.id.provider_id);
17343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mProviderIcon = (ImageView) rootView.findViewById(R.id.provider_icon);
17443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
17543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
17643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
17743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onActivityCreated(Bundle savedInstanceState) {
17843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onActivityCreated(savedInstanceState);
17943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
180ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        Bundle arguments = getArguments();
181ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        if (arguments == null) {
182ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne            Log.e(TAG, "No arguments provided when starting intent. ACCOUNT_KEY needed.");
183ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne            return;
184ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        }
185ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne
186ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        mAccount = (Account) arguments.getParcelable(ACCOUNT_KEY);
18743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (mAccount != null) {
18843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Got account: " + mAccount);
18943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            mUserId.setText(mAccount.name);
19043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            mProviderId.setText(mAccount.type);
19143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
19243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
19343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
19443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
19543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onResume() {
19643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        final Activity activity = getActivity();
19743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        AccountManager.get(activity).addOnAccountsUpdatedListener(this, null, false);
19843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        updateAuthDescriptions();
19943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        onAccountsUpdated(AccountManager.get(activity).getAccounts());
20043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
20143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onResume();
20243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
20343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
20443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
20543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onPause() {
20643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onPause();
20743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        AccountManager.get(getActivity()).removeOnAccountsUpdatedListener(this);
20843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
20943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
21043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void addSyncStateCheckBox(Account account, String authority) {
21143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        SyncStateCheckBoxPreference item =
21243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                new SyncStateCheckBoxPreference(getActivity(), account, authority);
21343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        item.setPersistent(false);
21443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        final ProviderInfo providerInfo = getPackageManager().resolveContentProvider(authority, 0);
21513ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia        if (providerInfo == null) {
21613ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia            return;
21713ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia        }
21813ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia        CharSequence providerLabel = providerInfo.loadLabel(getPackageManager());
21943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (TextUtils.isEmpty(providerLabel)) {
22043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Log.e(TAG, "Provider needs a label for authority '" + authority + "'");
22113ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia            return;
22243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
22343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        String title = getString(R.string.sync_item_title, providerLabel);
22443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        item.setTitle(title);
22543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        item.setKey(authority);
22643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mCheckBoxes.add(item);
22743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
22843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
22943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
23043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
23143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
23243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        MenuItem syncNow = menu.add(0, MENU_SYNC_NOW_ID, 0,
233d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                getString(R.string.sync_menu_sync_now))
2348472b1b60d7400a2a6dab8b54d1e1fd80659487fJustin Ho                .setIcon(R.drawable.ic_menu_refresh_holo_dark);
23543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        MenuItem syncCancel = menu.add(0, MENU_SYNC_CANCEL_ID, 0,
236d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                getString(R.string.sync_menu_sync_cancel))
23743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setIcon(com.android.internal.R.drawable.ic_menu_close_clear_cancel);
23843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
2390c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall        final UserManager um = (UserManager) getSystemService(Context.USER_SERVICE);
2400c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall        if (!um.hasUserRestriction(UserManager.DISALLOW_MODIFY_ACCOUNTS)) {
2410c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall            MenuItem removeAccount = menu.add(0, MENU_REMOVE_ACCOUNT_ID, 0,
2420c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall                    getString(R.string.remove_account_label))
2430c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall                    .setIcon(R.drawable.ic_menu_delete_holo_dark);
2440c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall            removeAccount.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER |
2450c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall                    MenuItem.SHOW_AS_ACTION_WITH_TEXT);
2460c5a401a58b30041d5fe712d78fccbd47f5b744dMaggie Benthall        }
247cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne        syncNow.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER |
248cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne                MenuItem.SHOW_AS_ACTION_WITH_TEXT);
249cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne        syncCancel.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER |
250cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne                MenuItem.SHOW_AS_ACTION_WITH_TEXT);
251d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
252d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        super.onCreateOptionsMenu(menu, inflater);
25343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
25443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
25543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
25643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onPrepareOptionsMenu(Menu menu) {
25743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onPrepareOptionsMenu(menu);
25843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        boolean syncActive = ContentResolver.getCurrentSync() != null;
25943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        menu.findItem(MENU_SYNC_NOW_ID).setVisible(!syncActive);
26043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        menu.findItem(MENU_SYNC_CANCEL_ID).setVisible(syncActive);
26143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
26243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
26343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
26443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public boolean onOptionsItemSelected(MenuItem item) {
26543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        switch (item.getItemId()) {
26643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            case MENU_SYNC_NOW_ID:
26743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                startSyncForEnabledProviders();
26843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                return true;
26943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            case MENU_SYNC_CANCEL_ID:
27043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                cancelSyncForEnabledProviders();
27143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                return true;
27243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            case MENU_REMOVE_ACCOUNT_ID:
27343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                showDialog(REALLY_REMOVE_DIALOG);
27443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                return true;
27543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
27643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        return super.onOptionsItemSelected(item);
27743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
27843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
27943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
28043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public boolean onPreferenceTreeClick(PreferenceScreen preferences, Preference preference) {
281ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio        if (preference instanceof SyncStateCheckBoxPreference) {
28243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            SyncStateCheckBoxPreference syncPref = (SyncStateCheckBoxPreference) preference;
28343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            String authority = syncPref.getAuthority();
28443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Account account = syncPref.getAccount();
28543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            boolean syncAutomatically = ContentResolver.getSyncAutomatically(account, authority);
28643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (syncPref.isOneTimeSyncMode()) {
28743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                requestOrCancelSync(account, authority, true);
28843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } else {
28943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                boolean syncOn = syncPref.isChecked();
29043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                boolean oldSyncState = syncAutomatically;
29143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (syncOn != oldSyncState) {
29243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // if we're enabling sync, this will request a sync as well
29343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    ContentResolver.setSyncAutomatically(account, authority, syncOn);
29443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // if the master sync switch is off, the request above will
29543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // get dropped.  when the user clicks on this toggle,
29643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // we want to force the sync, however.
29743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    if (!ContentResolver.getMasterSyncAutomatically() || !syncOn) {
29843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        requestOrCancelSync(account, authority, syncOn);
29943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    }
30043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                }
30143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
30243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            return true;
30343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        } else {
30443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            return super.onPreferenceTreeClick(preferences, preference);
30543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
30643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
30743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
30843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void startSyncForEnabledProviders() {
30943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        requestOrCancelSyncForEnabledProviders(true /* start them */);
31043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        getActivity().invalidateOptionsMenu();
31143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
31243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
31343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void cancelSyncForEnabledProviders() {
31443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        requestOrCancelSyncForEnabledProviders(false /* cancel them */);
31543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        getActivity().invalidateOptionsMenu();
31643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
31743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
31843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void requestOrCancelSyncForEnabledProviders(boolean startSync) {
31943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        // sync everything that the user has enabled
32043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        int count = getPreferenceScreen().getPreferenceCount();
32143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0; i < count; i++) {
32243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Preference pref = getPreferenceScreen().getPreference(i);
32343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (! (pref instanceof SyncStateCheckBoxPreference)) {
32443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                continue;
32543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
32643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            SyncStateCheckBoxPreference syncPref = (SyncStateCheckBoxPreference) pref;
32743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (!syncPref.isChecked()) {
32843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                continue;
32943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
33043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            requestOrCancelSync(syncPref.getAccount(), syncPref.getAuthority(), startSync);
33143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
33243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        // plus whatever the system needs to sync, e.g., invisible sync adapters
33343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (mAccount != null) {
334193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu            for (SyncAdapterType syncAdapter : mInvisibleAdapters) {
335193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                // invisible sync adapters' account type should be same as current account type
336193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                if (syncAdapter.accountType.equals(mAccount.type)) {
337193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                    requestOrCancelSync(mAccount, syncAdapter.authority, startSync);
338193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                }
33943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
34043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
34143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
34243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
34343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void requestOrCancelSync(Account account, String authority, boolean flag) {
34443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (flag) {
34543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Bundle extras = new Bundle();
34643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
34743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            ContentResolver.requestSync(account, authority, extras);
34843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        } else {
34943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            ContentResolver.cancelSync(account, authority);
35043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
35143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
35243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
35343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private boolean isSyncing(List<SyncInfo> currentSyncs, Account account, String authority) {
35443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (SyncInfo syncInfo : currentSyncs) {
35543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (syncInfo.account.equals(account) && syncInfo.authority.equals(authority)) {
35643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                return true;
35743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
35843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
35943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        return false;
36043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
36143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
36243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
36343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    protected void onSyncStateUpdated() {
364564e68aecef3d8d3e850bdb969c60a756208de83Amith Yamasani        if (!isResumed()) return;
365ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio        setFeedsState();
36631ffa0439d85b9abe06bd0ee35545524e36575fcFabrice Di Meglio    }
36731ffa0439d85b9abe06bd0ee35545524e36575fcFabrice Di Meglio
368ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio    private void setFeedsState() {
36943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        // iterate over all the preferences, setting the state properly for each
37043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        Date date = new Date();
37143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        List<SyncInfo> currentSyncs = ContentResolver.getCurrentSyncs();
37243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        boolean syncIsFailing = false;
37343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
37443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        // Refresh the sync status checkboxes - some syncs may have become active.
37543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        updateAccountCheckboxes(mAccounts);
37643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
37743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0, count = getPreferenceScreen().getPreferenceCount(); i < count; i++) {
37843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Preference pref = getPreferenceScreen().getPreference(i);
37943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (! (pref instanceof SyncStateCheckBoxPreference)) {
38043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                continue;
38143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
38243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            SyncStateCheckBoxPreference syncPref = (SyncStateCheckBoxPreference) pref;
38343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
38443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            String authority = syncPref.getAuthority();
38543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Account account = syncPref.getAccount();
38643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
387ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            SyncStatusInfo status = ContentResolver.getSyncStatus(account, authority);
388ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean syncEnabled = ContentResolver.getSyncAutomatically(account, authority);
389ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean authorityIsPending = status == null ? false : status.pending;
390ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean initialSync = status == null ? false : status.initialize;
391ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio
392ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean activelySyncing = isSyncing(currentSyncs, account, authority);
393ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean lastSyncFailed = status != null
394ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                    && status.lastFailureTime != 0
395ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                    && status.getLastFailureMesgAsInt(0)
396ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                       != ContentResolver.SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS;
397ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            if (!syncEnabled) lastSyncFailed = false;
398ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            if (lastSyncFailed && !activelySyncing && !authorityIsPending) {
399ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                syncIsFailing = true;
400ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            }
401ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            if (Log.isLoggable(TAG, Log.VERBOSE)) {
402ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                Log.d(TAG, "Update sync status: " + account + " " + authority +
403ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                        " active = " + activelySyncing + " pend =" +  authorityIsPending);
404ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            }
40543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
406ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            final long successEndTime = (status == null) ? 0 : status.lastSuccessTime;
407d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            if (!syncEnabled) {
408d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                syncPref.setSummary(R.string.sync_disabled);
409d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            } else if (activelySyncing) {
410d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                syncPref.setSummary(R.string.sync_in_progress);
411d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            } else if (successEndTime != 0) {
412ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                date.setTime(successEndTime);
413d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                final String timeString = formatSyncDate(date);
414d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                syncPref.setSummary(getResources().getString(R.string.last_synced, timeString));
41543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } else {
416ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                syncPref.setSummary("");
41743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
418ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            int syncState = ContentResolver.getIsSyncable(account, authority);
419ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio
420ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setActive(activelySyncing && (syncState >= 0) &&
421ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                    !initialSync);
422ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setPending(authorityIsPending && (syncState >= 0) &&
423ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                    !initialSync);
424ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio
425ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setFailed(lastSyncFailed);
426ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            ConnectivityManager connManager =
427ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
428ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            final boolean masterSyncAutomatically = ContentResolver.getMasterSyncAutomatically();
429ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            final boolean backgroundDataEnabled = connManager.getBackgroundDataSetting();
430ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            final boolean oneTimeSyncMode = !masterSyncAutomatically || !backgroundDataEnabled;
431ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setOneTimeSyncMode(oneTimeSyncMode);
432ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setChecked(oneTimeSyncMode || syncEnabled);
43343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
43443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mErrorInfoView.setVisibility(syncIsFailing ? View.VISIBLE : View.GONE);
43543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        getActivity().invalidateOptionsMenu();
43643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
43743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
43843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
43943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onAccountsUpdated(Account[] accounts) {
44043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onAccountsUpdated(accounts);
44143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mAccounts = accounts;
44243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        updateAccountCheckboxes(accounts);
44343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        onSyncStateUpdated();
44443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
44543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
44643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void updateAccountCheckboxes(Account[] accounts) {
44743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mInvisibleAdapters.clear();
44843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
44943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes();
45043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        HashMap<String, ArrayList<String>> accountTypeToAuthorities =
45143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Maps.newHashMap();
45243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0, n = syncAdapters.length; i < n; i++) {
45343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            final SyncAdapterType sa = syncAdapters[i];
45443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (sa.isUserVisible()) {
45543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                ArrayList<String> authorities = accountTypeToAuthorities.get(sa.accountType);
45643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (authorities == null) {
45743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    authorities = new ArrayList<String>();
45843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    accountTypeToAuthorities.put(sa.accountType, authorities);
45943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                }
46043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (Log.isLoggable(TAG, Log.VERBOSE)) {
46143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    Log.d(TAG, "onAccountUpdated: added authority " + sa.authority
46243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                            + " to accountType " + sa.accountType);
46343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                }
46443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                authorities.add(sa.authority);
46543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } else {
46643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                // keep track of invisible sync adapters, so sync now forces
46743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                // them to sync as well.
468193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                mInvisibleAdapters.add(sa);
46943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
47043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
47143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
47243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0, n = mCheckBoxes.size(); i < n; i++) {
47343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            getPreferenceScreen().removePreference(mCheckBoxes.get(i));
47443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
47543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mCheckBoxes.clear();
47643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
47743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0, n = accounts.length; i < n; i++) {
47843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            final Account account = accounts[i];
47943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (Log.isLoggable(TAG, Log.VERBOSE)) {
48043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                Log.d(TAG, "looking for sync adapters that match account " + account);
48143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
48243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            final ArrayList<String> authorities = accountTypeToAuthorities.get(account.type);
48343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (authorities != null && (mAccount == null || mAccount.equals(account))) {
48443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                for (int j = 0, m = authorities.size(); j < m; j++) {
48543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    final String authority = authorities.get(j);
48643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // We could check services here....
48743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    int syncState = ContentResolver.getIsSyncable(account, authority);
48843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
48943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        Log.d(TAG, "  found authority " + authority + " " + syncState);
49043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    }
49143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    if (syncState > 0) {
49243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        addSyncStateCheckBox(account, authority);
49343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    }
49443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                }
49543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
49643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
497100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio
498100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio        Collections.sort(mCheckBoxes);
499100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio        for (int i = 0, n = mCheckBoxes.size(); i < n; i++) {
500100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio            getPreferenceScreen().addPreference(mCheckBoxes.get(i));
501100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio        }
50243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
50343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
50443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    /**
50543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani     * Updates the titlebar with an icon for the provider type.
50643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani     */
50743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
50843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    protected void onAuthDescriptionsUpdated() {
50943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onAuthDescriptionsUpdated();
51043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        getPreferenceScreen().removeAll();
511ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        if (mAccount != null) {
512ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne            mProviderIcon.setImageDrawable(getDrawableForType(mAccount.type));
513ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne            mProviderId.setText(getLabelForType(mAccount.type));
51443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
51543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        addPreferencesFromResource(R.xml.account_sync_settings);
51643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
51743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
518d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    @Override
519d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    protected int getHelpResource() {
520d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        return R.string.help_url_accounts;
52143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
52243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani}
523