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.Intent;
3243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.SyncAdapterType;
3343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.SyncInfo;
3443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.SyncStatusInfo;
3543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.content.pm.ProviderInfo;
3643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.net.ConnectivityManager;
3743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.os.Bundle;
3843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.preference.Preference;
3943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.preference.PreferenceScreen;
4043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.text.TextUtils;
4143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.text.format.DateFormat;
4243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.util.Log;
4343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.LayoutInflater;
4443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.Menu;
4543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.MenuInflater;
4643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.MenuItem;
4743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.View;
4843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.view.ViewGroup;
4943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.widget.ImageView;
5097d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkeyimport android.widget.ListView;
5143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport android.widget.TextView;
5243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
53ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunneimport com.android.settings.R;
5497d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkeyimport com.android.settings.Utils;
55ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunneimport com.google.android.collect.Lists;
56ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunneimport com.google.android.collect.Maps;
57ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne
5843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.io.IOException;
5943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.ArrayList;
60100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglioimport java.util.Collections;
6143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.Date;
6243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.HashMap;
6343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasaniimport java.util.List;
6443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
6543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasanipublic class AccountSyncSettings extends AccountPreferenceBase {
6643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
6743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public static final String ACCOUNT_KEY = "account";
68d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private static final int MENU_SYNC_NOW_ID       = Menu.FIRST;
69d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private static final int MENU_SYNC_CANCEL_ID    = Menu.FIRST + 1;
70d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    private static final int MENU_REMOVE_ACCOUNT_ID = Menu.FIRST + 2;
7143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private static final int REALLY_REMOVE_DIALOG = 100;
7243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private static final int FAILED_REMOVAL_DIALOG = 101;
7343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private static final int CANT_DO_ONETIME_SYNC_DIALOG = 102;
7443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private TextView mUserId;
7543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private TextView mProviderId;
7643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private ImageView mProviderIcon;
7743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private TextView mErrorInfoView;
7843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private Account mAccount;
7943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    // List of all accounts, updated when accounts are added/removed
8043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    // We need to re-scan the accounts on sync events, in case sync state changes.
8143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private Account[] mAccounts;
8243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private ArrayList<SyncStateCheckBoxPreference> mCheckBoxes =
8343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                new ArrayList<SyncStateCheckBoxPreference>();
84193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu    private ArrayList<SyncAdapterType> mInvisibleAdapters = Lists.newArrayList();
8543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
8643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
8743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public Dialog onCreateDialog(final int id) {
8843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        Dialog dialog = null;
8943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (id == REALLY_REMOVE_DIALOG) {
9043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            dialog = new AlertDialog.Builder(getActivity())
9143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setTitle(R.string.really_remove_account_title)
9243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setMessage(R.string.really_remove_account_message)
9343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setNegativeButton(android.R.string.cancel, null)
9443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setPositiveButton(R.string.remove_account_label,
9543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        new DialogInterface.OnClickListener() {
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>() {
10043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                            public void run(AccountManagerFuture<Boolean> future) {
101e88be4f6205b0e039de5ab32e4e3fbefd2dc926dAmith Yamasani                                // If already out of this screen, don't proceed.
102e88be4f6205b0e039de5ab32e4e3fbefd2dc926dAmith Yamasani                                if (!AccountSyncSettings.this.isResumed()) {
103e88be4f6205b0e039de5ab32e4e3fbefd2dc926dAmith Yamasani                                    return;
104e88be4f6205b0e039de5ab32e4e3fbefd2dc926dAmith Yamasani                                }
10543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                boolean failed = true;
10643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                try {
10743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    if (future.getResult() == true) {
10843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                        failed = false;
10943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    }
11043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                } catch (OperationCanceledException e) {
11143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    // handled below
11243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                } catch (IOException e) {
11343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    // handled below
11443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                } catch (AuthenticatorException e) {
11543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    // handled below
11643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                }
11743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                if (failed) {
11843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    showDialog(FAILED_REMOVAL_DIALOG);
11943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                } else {
12043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                    finish();
12143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                                }
12243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                            }
12343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        }, null);
12443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    }
12543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                })
12643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .create();
12743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        } else if (id == FAILED_REMOVAL_DIALOG) {
12843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            dialog = new AlertDialog.Builder(getActivity())
12943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setTitle(R.string.really_remove_account_title)
13043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setPositiveButton(android.R.string.ok, null)
13143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setMessage(R.string.remove_account_failed)
13243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .create();
13343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        } else if (id == CANT_DO_ONETIME_SYNC_DIALOG) {
13443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            dialog = new AlertDialog.Builder(getActivity())
13543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setTitle(R.string.cant_sync_dialog_title)
13643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setMessage(R.string.cant_sync_dialog_message)
13743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setPositiveButton(android.R.string.ok, null)
13843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .create();
13943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
14043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        return dialog;
14143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
14243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
14343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
14443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onCreate(Bundle icicle) {
14543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onCreate(icicle);
14643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
14743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        setHasOptionsMenu(true);
14843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
14943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
15043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
15143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public View onCreateView(LayoutInflater inflater, ViewGroup container,
15243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Bundle savedInstanceState) {
15343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        final View view = inflater.inflate(R.layout.account_sync_screen, container, false);
15497d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkey
15597d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkey        final ListView list = (ListView) view.findViewById(android.R.id.list);
15697d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkey        Utils.prepareCustomPreferencesList(container, view, list, false);
15797d07fa3aedde44368818551dc789eaff7bfb047Jeff Sharkey
15843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        initializeUi(view);
15943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
16043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        return view;
16143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
16243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
16343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    protected void initializeUi(final View rootView) {
16443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        addPreferencesFromResource(R.xml.account_sync_settings);
16543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
16643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mErrorInfoView = (TextView) rootView.findViewById(R.id.sync_settings_error_info);
16743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mErrorInfoView.setVisibility(View.GONE);
16843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
16943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mUserId = (TextView) rootView.findViewById(R.id.user_id);
17043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mProviderId = (TextView) rootView.findViewById(R.id.provider_id);
17143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mProviderIcon = (ImageView) rootView.findViewById(R.id.provider_icon);
17243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
17343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
17443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
17543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onActivityCreated(Bundle savedInstanceState) {
17643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onActivityCreated(savedInstanceState);
17743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
178ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        Bundle arguments = getArguments();
179ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        if (arguments == null) {
180ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne            Log.e(TAG, "No arguments provided when starting intent. ACCOUNT_KEY needed.");
181ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne            return;
182ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        }
183ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne
184ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        mAccount = (Account) arguments.getParcelable(ACCOUNT_KEY);
18543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (mAccount != null) {
18643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "Got account: " + mAccount);
18743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            mUserId.setText(mAccount.name);
18843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            mProviderId.setText(mAccount.type);
18943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
19043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
19143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
19243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
19343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onResume() {
19443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        final Activity activity = getActivity();
19543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        AccountManager.get(activity).addOnAccountsUpdatedListener(this, null, false);
19643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        updateAuthDescriptions();
19743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        onAccountsUpdated(AccountManager.get(activity).getAccounts());
19843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
19943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onResume();
20043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
20143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
20243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
20343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onPause() {
20443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onPause();
20543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        AccountManager.get(getActivity()).removeOnAccountsUpdatedListener(this);
20643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
20743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
20843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void addSyncStateCheckBox(Account account, String authority) {
20943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        SyncStateCheckBoxPreference item =
21043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                new SyncStateCheckBoxPreference(getActivity(), account, authority);
21143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        item.setPersistent(false);
21243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        final ProviderInfo providerInfo = getPackageManager().resolveContentProvider(authority, 0);
21313ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia        if (providerInfo == null) {
21413ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia            return;
21513ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia        }
21613ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia        CharSequence providerLabel = providerInfo.loadLabel(getPackageManager());
21743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (TextUtils.isEmpty(providerLabel)) {
21843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Log.e(TAG, "Provider needs a label for authority '" + authority + "'");
21913ade46b5320f3c1982e8e9bc39508bb7fc647dbCarlos Valdivia            return;
22043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
22143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        String title = getString(R.string.sync_item_title, providerLabel);
22243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        item.setTitle(title);
22343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        item.setKey(authority);
22443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mCheckBoxes.add(item);
22543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
22643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
22743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
22843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
22943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
23043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        MenuItem syncNow = menu.add(0, MENU_SYNC_NOW_ID, 0,
231d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                getString(R.string.sync_menu_sync_now))
2328472b1b60d7400a2a6dab8b54d1e1fd80659487fJustin Ho                .setIcon(R.drawable.ic_menu_refresh_holo_dark);
23343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        MenuItem syncCancel = menu.add(0, MENU_SYNC_CANCEL_ID, 0,
234d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                getString(R.string.sync_menu_sync_cancel))
23543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                .setIcon(com.android.internal.R.drawable.ic_menu_close_clear_cancel);
236d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        MenuItem removeAccount = menu.add(0, MENU_REMOVE_ACCOUNT_ID, 0,
237d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                getString(R.string.remove_account_label))
238d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                .setIcon(R.drawable.ic_menu_delete_holo_dark);
23943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
240cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne        removeAccount.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER |
241cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne                MenuItem.SHOW_AS_ACTION_WITH_TEXT);
242cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne        syncNow.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER |
243cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne                MenuItem.SHOW_AS_ACTION_WITH_TEXT);
244cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne        syncCancel.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER |
245cd8e5246f1d538384dae87b8d2867ba3e44a6981Gilles Debunne                MenuItem.SHOW_AS_ACTION_WITH_TEXT);
246d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani
247d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        super.onCreateOptionsMenu(menu, inflater);
24843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
24943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
25043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
25143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onPrepareOptionsMenu(Menu menu) {
25243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onPrepareOptionsMenu(menu);
25343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        boolean syncActive = ContentResolver.getCurrentSync() != null;
25443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        menu.findItem(MENU_SYNC_NOW_ID).setVisible(!syncActive);
25543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        menu.findItem(MENU_SYNC_CANCEL_ID).setVisible(syncActive);
25643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
25743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
25843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
25943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public boolean onOptionsItemSelected(MenuItem item) {
26043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        switch (item.getItemId()) {
26143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            case MENU_SYNC_NOW_ID:
26243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                startSyncForEnabledProviders();
26343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                return true;
26443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            case MENU_SYNC_CANCEL_ID:
26543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                cancelSyncForEnabledProviders();
26643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                return true;
26743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            case MENU_REMOVE_ACCOUNT_ID:
26843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                showDialog(REALLY_REMOVE_DIALOG);
26943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                return true;
27043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
27143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        return super.onOptionsItemSelected(item);
27243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
27343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
27443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
27543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public boolean onPreferenceTreeClick(PreferenceScreen preferences, Preference preference) {
276ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio        if (preference instanceof SyncStateCheckBoxPreference) {
27743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            SyncStateCheckBoxPreference syncPref = (SyncStateCheckBoxPreference) preference;
27843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            String authority = syncPref.getAuthority();
27943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Account account = syncPref.getAccount();
28043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            boolean syncAutomatically = ContentResolver.getSyncAutomatically(account, authority);
28143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (syncPref.isOneTimeSyncMode()) {
28243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                requestOrCancelSync(account, authority, true);
28343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } else {
28443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                boolean syncOn = syncPref.isChecked();
28543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                boolean oldSyncState = syncAutomatically;
28643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (syncOn != oldSyncState) {
28743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // if we're enabling sync, this will request a sync as well
28843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    ContentResolver.setSyncAutomatically(account, authority, syncOn);
28943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // if the master sync switch is off, the request above will
29043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // get dropped.  when the user clicks on this toggle,
29143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // we want to force the sync, however.
29243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    if (!ContentResolver.getMasterSyncAutomatically() || !syncOn) {
29343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        requestOrCancelSync(account, authority, syncOn);
29443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    }
29543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                }
29643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
29743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            return true;
29843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        } else {
29943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            return super.onPreferenceTreeClick(preferences, preference);
30043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
30143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
30243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
30343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void startSyncForEnabledProviders() {
30443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        requestOrCancelSyncForEnabledProviders(true /* start them */);
30543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        getActivity().invalidateOptionsMenu();
30643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
30743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
30843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void cancelSyncForEnabledProviders() {
30943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        requestOrCancelSyncForEnabledProviders(false /* cancel them */);
31043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        getActivity().invalidateOptionsMenu();
31143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
31243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
31343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void requestOrCancelSyncForEnabledProviders(boolean startSync) {
31443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        // sync everything that the user has enabled
31543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        int count = getPreferenceScreen().getPreferenceCount();
31643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0; i < count; i++) {
31743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Preference pref = getPreferenceScreen().getPreference(i);
31843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (! (pref instanceof SyncStateCheckBoxPreference)) {
31943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                continue;
32043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
32143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            SyncStateCheckBoxPreference syncPref = (SyncStateCheckBoxPreference) pref;
32243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (!syncPref.isChecked()) {
32343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                continue;
32443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
32543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            requestOrCancelSync(syncPref.getAccount(), syncPref.getAuthority(), startSync);
32643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
32743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        // plus whatever the system needs to sync, e.g., invisible sync adapters
32843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (mAccount != null) {
329193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu            for (SyncAdapterType syncAdapter : mInvisibleAdapters) {
330193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                // invisible sync adapters' account type should be same as current account type
331193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                if (syncAdapter.accountType.equals(mAccount.type)) {
332193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                    requestOrCancelSync(mAccount, syncAdapter.authority, startSync);
333193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                }
33443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
33543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
33643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
33743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
33843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void requestOrCancelSync(Account account, String authority, boolean flag) {
33943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        if (flag) {
34043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Bundle extras = new Bundle();
34143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            extras.putBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, true);
34243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            ContentResolver.requestSync(account, authority, extras);
34343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        } else {
34443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            ContentResolver.cancelSync(account, authority);
34543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
34643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
34743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
34843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private boolean isSyncing(List<SyncInfo> currentSyncs, Account account, String authority) {
34943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (SyncInfo syncInfo : currentSyncs) {
35043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (syncInfo.account.equals(account) && syncInfo.authority.equals(authority)) {
35143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                return true;
35243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
35343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
35443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        return false;
35543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
35643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
35743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
35843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    protected void onSyncStateUpdated() {
359564e68aecef3d8d3e850bdb969c60a756208de83Amith Yamasani        if (!isResumed()) return;
360ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio        setFeedsState();
36131ffa0439d85b9abe06bd0ee35545524e36575fcFabrice Di Meglio    }
36231ffa0439d85b9abe06bd0ee35545524e36575fcFabrice Di Meglio
363ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio    private void setFeedsState() {
36443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        // iterate over all the preferences, setting the state properly for each
36543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        Date date = new Date();
36643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        List<SyncInfo> currentSyncs = ContentResolver.getCurrentSyncs();
36743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        boolean syncIsFailing = false;
36843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
36943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        // Refresh the sync status checkboxes - some syncs may have become active.
37043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        updateAccountCheckboxes(mAccounts);
37143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
37243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0, count = getPreferenceScreen().getPreferenceCount(); i < count; i++) {
37343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Preference pref = getPreferenceScreen().getPreference(i);
37443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (! (pref instanceof SyncStateCheckBoxPreference)) {
37543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                continue;
37643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
37743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            SyncStateCheckBoxPreference syncPref = (SyncStateCheckBoxPreference) pref;
37843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
37943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            String authority = syncPref.getAuthority();
38043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Account account = syncPref.getAccount();
38143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
382ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            SyncStatusInfo status = ContentResolver.getSyncStatus(account, authority);
383ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean syncEnabled = ContentResolver.getSyncAutomatically(account, authority);
384ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean authorityIsPending = status == null ? false : status.pending;
385ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean initialSync = status == null ? false : status.initialize;
386ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio
387ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean activelySyncing = isSyncing(currentSyncs, account, authority);
388ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            boolean lastSyncFailed = status != null
389ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                    && status.lastFailureTime != 0
390ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                    && status.getLastFailureMesgAsInt(0)
391ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                       != ContentResolver.SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS;
392ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            if (!syncEnabled) lastSyncFailed = false;
393ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            if (lastSyncFailed && !activelySyncing && !authorityIsPending) {
394ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                syncIsFailing = true;
395ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            }
396ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            if (Log.isLoggable(TAG, Log.VERBOSE)) {
397ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                Log.d(TAG, "Update sync status: " + account + " " + authority +
398ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                        " active = " + activelySyncing + " pend =" +  authorityIsPending);
399ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            }
40043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
401ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            final long successEndTime = (status == null) ? 0 : status.lastSuccessTime;
402d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            if (!syncEnabled) {
403d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                syncPref.setSummary(R.string.sync_disabled);
404d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            } else if (activelySyncing) {
405d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                syncPref.setSummary(R.string.sync_in_progress);
406d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani            } else if (successEndTime != 0) {
407ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                date.setTime(successEndTime);
408d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                final String timeString = formatSyncDate(date);
409d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani                syncPref.setSummary(getResources().getString(R.string.last_synced, timeString));
41043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } else {
411ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                syncPref.setSummary("");
41243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
413ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            int syncState = ContentResolver.getIsSyncable(account, authority);
414ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio
415ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setActive(activelySyncing && (syncState >= 0) &&
416ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                    !initialSync);
417ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setPending(authorityIsPending && (syncState >= 0) &&
418ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                    !initialSync);
419ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio
420ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setFailed(lastSyncFailed);
421ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            ConnectivityManager connManager =
422ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio                (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
423ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            final boolean masterSyncAutomatically = ContentResolver.getMasterSyncAutomatically();
424ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            final boolean backgroundDataEnabled = connManager.getBackgroundDataSetting();
425ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            final boolean oneTimeSyncMode = !masterSyncAutomatically || !backgroundDataEnabled;
426ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setOneTimeSyncMode(oneTimeSyncMode);
427ce9f77bb558434b9daa40304d3eb8a7201865ac8Fabrice Di Meglio            syncPref.setChecked(oneTimeSyncMode || syncEnabled);
42843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
42943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mErrorInfoView.setVisibility(syncIsFailing ? View.VISIBLE : View.GONE);
43043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        getActivity().invalidateOptionsMenu();
43143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
43243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
43343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
43443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    public void onAccountsUpdated(Account[] accounts) {
43543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onAccountsUpdated(accounts);
43643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mAccounts = accounts;
43743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        updateAccountCheckboxes(accounts);
43843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        onSyncStateUpdated();
43943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
44043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
44143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    private void updateAccountCheckboxes(Account[] accounts) {
44243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mInvisibleAdapters.clear();
44343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
44443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes();
44543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        HashMap<String, ArrayList<String>> accountTypeToAuthorities =
44643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            Maps.newHashMap();
44743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0, n = syncAdapters.length; i < n; i++) {
44843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            final SyncAdapterType sa = syncAdapters[i];
44943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (sa.isUserVisible()) {
45043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                ArrayList<String> authorities = accountTypeToAuthorities.get(sa.accountType);
45143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (authorities == null) {
45243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    authorities = new ArrayList<String>();
45343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    accountTypeToAuthorities.put(sa.accountType, authorities);
45443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                }
45543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                if (Log.isLoggable(TAG, Log.VERBOSE)) {
45643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    Log.d(TAG, "onAccountUpdated: added authority " + sa.authority
45743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                            + " to accountType " + sa.accountType);
45843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                }
45943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                authorities.add(sa.authority);
46043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            } else {
46143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                // keep track of invisible sync adapters, so sync now forces
46243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                // them to sync as well.
463193821e6e850d1fb76d01e369856a35d00fc9bedZhenguo Fu                mInvisibleAdapters.add(sa);
46443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
46543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
46643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
46743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0, n = mCheckBoxes.size(); i < n; i++) {
46843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            getPreferenceScreen().removePreference(mCheckBoxes.get(i));
46943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
47043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        mCheckBoxes.clear();
47143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
47243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        for (int i = 0, n = accounts.length; i < n; i++) {
47343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            final Account account = accounts[i];
47443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (Log.isLoggable(TAG, Log.VERBOSE)) {
47543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                Log.d(TAG, "looking for sync adapters that match account " + account);
47643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
47743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            final ArrayList<String> authorities = accountTypeToAuthorities.get(account.type);
47843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            if (authorities != null && (mAccount == null || mAccount.equals(account))) {
47943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                for (int j = 0, m = authorities.size(); j < m; j++) {
48043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    final String authority = authorities.get(j);
48143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    // We could check services here....
48243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    int syncState = ContentResolver.getIsSyncable(account, authority);
48343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
48443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        Log.d(TAG, "  found authority " + authority + " " + syncState);
48543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    }
48643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    if (syncState > 0) {
48743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                        addSyncStateCheckBox(account, authority);
48843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                    }
48943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani                }
49043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani            }
49143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
492100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio
493100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio        Collections.sort(mCheckBoxes);
494100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio        for (int i = 0, n = mCheckBoxes.size(); i < n; i++) {
495100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio            getPreferenceScreen().addPreference(mCheckBoxes.get(i));
496100d51fbe9ba23088398f06848ba99a9cfb1c5a9Fabrice Di Meglio        }
49743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
49843c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
49943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    /**
50043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani     * Updates the titlebar with an icon for the provider type.
50143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani     */
50243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    @Override
50343c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    protected void onAuthDescriptionsUpdated() {
50443c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        super.onAuthDescriptionsUpdated();
50543c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        getPreferenceScreen().removeAll();
506ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne        if (mAccount != null) {
507ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne            mProviderIcon.setImageDrawable(getDrawableForType(mAccount.type));
508ab189bd9a6bb023e0574e52a129f86c2b12b4d93Gilles Debunne            mProviderId.setText(getLabelForType(mAccount.type));
50943c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        }
51043c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani        addPreferencesFromResource(R.xml.account_sync_settings);
51143c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
51243c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani
513d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    @Override
514d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani    protected int getHelpResource() {
515d1ab82807aae63926b35f66080a1f7a75c00b95bAmith Yamasani        return R.string.help_url_accounts;
51643c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani    }
51743c697854c7e373fbc1dae8b7a5259a32de346b4Amith Yamasani}
518