Home | History | Annotate | Download | only in settings
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.settings;
     18 
     19 import com.android.providers.subscribedfeeds.R;
     20 
     21 import android.accounts.AccountManager;
     22 import android.accounts.Account;
     23 import android.app.AlertDialog;
     24 import android.app.Dialog;
     25 import android.content.SyncInfo;
     26 import android.content.ContentResolver;
     27 import android.content.Context;
     28 import android.content.DialogInterface;
     29 import android.content.Intent;
     30 import android.content.SyncAdapterType;
     31 import android.content.SyncStatusInfo;
     32 import android.graphics.drawable.Drawable;
     33 import android.net.ConnectivityManager;
     34 import android.os.Bundle;
     35 import android.preference.CheckBoxPreference;
     36 import android.preference.Preference;
     37 import android.preference.PreferenceCategory;
     38 import android.preference.PreferenceScreen;
     39 import android.view.View;
     40 import android.widget.Button;
     41 import android.widget.TextView;
     42 import android.util.Log;
     43 
     44 import java.util.ArrayList;
     45 import java.util.HashSet;
     46 
     47 public class ManageAccountsSettings extends AccountPreferenceBase implements View.OnClickListener {
     48     private static final String AUTO_SYNC_CHECKBOX_KEY = "syncAutomaticallyCheckBox";
     49     private static final String MANAGE_ACCOUNTS_CATEGORY_KEY = "manageAccountsCategory";
     50     private static final String BACKGROUND_DATA_CHECKBOX_KEY = "backgroundDataCheckBox";
     51     private static final int DIALOG_DISABLE_BACKGROUND_DATA = 1;
     52 
     53     private CheckBoxPreference mBackgroundDataCheckBox;
     54     private PreferenceCategory mManageAccountsCategory;
     55     private String[] mAuthorities;
     56     private TextView mErrorInfoView;
     57     private Button mAddAccountButton;
     58     private CheckBoxPreference mAutoSyncCheckbox;
     59 
     60     @Override
     61     public void onCreate(Bundle icicle) {
     62         super.onCreate(icicle);
     63 
     64         setContentView(R.layout.manage_accounts_screen);
     65         addPreferencesFromResource(R.xml.manage_accounts_settings);
     66 
     67         mErrorInfoView = (TextView)findViewById(R.id.sync_settings_error_info);
     68         mErrorInfoView.setVisibility(View.GONE);
     69         mErrorInfoView.setCompoundDrawablesWithIntrinsicBounds(
     70                 getResources().getDrawable(R.drawable.ic_list_syncerror), null, null, null);
     71 
     72         mBackgroundDataCheckBox = (CheckBoxPreference) findPreference(BACKGROUND_DATA_CHECKBOX_KEY);
     73         mAutoSyncCheckbox = (CheckBoxPreference) findPreference(AUTO_SYNC_CHECKBOX_KEY);
     74 
     75         mManageAccountsCategory =
     76                 (PreferenceCategory) findPreference(MANAGE_ACCOUNTS_CATEGORY_KEY);
     77         mAuthorities = getIntent().getStringArrayExtra(AUTHORITIES_FILTER_KEY);
     78         mAddAccountButton = (Button) findViewById(R.id.add_account_button);
     79         mAddAccountButton.setOnClickListener(this);
     80 
     81         AccountManager.get(this).addOnAccountsUpdatedListener(this, null, true);
     82         updateAuthDescriptions();
     83     }
     84 
     85     @Override
     86     public void onDestroy() {
     87         AccountManager.get(this).removeOnAccountsUpdatedListener(this);
     88         super.onDestroy();
     89     }
     90 
     91     @Override
     92     public boolean onPreferenceTreeClick(PreferenceScreen preferences, Preference preference) {
     93         if (preference == mBackgroundDataCheckBox) {
     94             ConnectivityManager connManager =
     95                     (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
     96             boolean oldBackgroundDataSetting = connManager.getBackgroundDataSetting();
     97             boolean backgroundDataSetting = mBackgroundDataCheckBox.isChecked();
     98             if (oldBackgroundDataSetting != backgroundDataSetting) {
     99                 if (backgroundDataSetting) {
    100                     setBackgroundDataInt(true);
    101                     onSyncStateUpdated();
    102                 } else {
    103                     // This will get unchecked only if the user hits "Ok"
    104                     mBackgroundDataCheckBox.setChecked(true);
    105                     showDialog(DIALOG_DISABLE_BACKGROUND_DATA);
    106                 }
    107             }
    108         } else if (preference == mAutoSyncCheckbox) {
    109             ContentResolver.setMasterSyncAutomatically(mAutoSyncCheckbox.isChecked());
    110             onSyncStateUpdated();
    111         } else {
    112             return false;
    113         }
    114         return true;
    115     }
    116 
    117     @Override
    118     protected Dialog onCreateDialog(int id) {
    119         switch (id) {
    120             case DIALOG_DISABLE_BACKGROUND_DATA:
    121                 final CheckBoxPreference pref =
    122                     (CheckBoxPreference) findPreference(BACKGROUND_DATA_CHECKBOX_KEY);
    123                 return new AlertDialog.Builder(this)
    124                         .setTitle(R.string.background_data_dialog_title)
    125                         .setIcon(android.R.drawable.ic_dialog_alert)
    126                         .setMessage(R.string.background_data_dialog_message)
    127                         .setPositiveButton(android.R.string.ok,
    128                                     new DialogInterface.OnClickListener() {
    129                                 public void onClick(DialogInterface dialog, int which) {
    130                                     setBackgroundDataInt(false);
    131                                     pref.setChecked(false);
    132                                     onSyncStateUpdated();
    133                                 }
    134                             })
    135                         .setNegativeButton(android.R.string.cancel, null)
    136                         .create();
    137         }
    138 
    139         return null;
    140     }
    141 
    142     private void setBackgroundDataInt(boolean enabled) {
    143         ConnectivityManager connManager =
    144                 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    145         connManager.setBackgroundDataSetting(enabled);
    146     }
    147 
    148     @Override
    149     protected void onSyncStateUpdated() {
    150         // Set background connection state
    151         ConnectivityManager connManager =
    152                 (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    153         boolean backgroundDataSetting = connManager.getBackgroundDataSetting();
    154         mBackgroundDataCheckBox.setChecked(backgroundDataSetting);
    155         boolean masterSyncAutomatically = ContentResolver.getMasterSyncAutomatically();
    156         mAutoSyncCheckbox.setChecked(masterSyncAutomatically);
    157 
    158         // iterate over all the preferences, setting the state properly for each
    159         SyncInfo currentSync = ContentResolver.getCurrentSync();
    160 
    161         boolean anySyncFailed = false; // true if sync on any account failed
    162 
    163         // only track userfacing sync adapters when deciding if account is synced or not
    164         final SyncAdapterType[] syncAdapters = ContentResolver.getSyncAdapterTypes();
    165         HashSet<String> userFacing = new HashSet<String>();
    166         for (int k = 0, n = syncAdapters.length; k < n; k++) {
    167             final SyncAdapterType sa = syncAdapters[k];
    168             if (sa.isUserVisible()) {
    169                 userFacing.add(sa.authority);
    170             }
    171         }
    172         for (int i = 0, count = mManageAccountsCategory.getPreferenceCount(); i < count; i++) {
    173             Preference pref = mManageAccountsCategory.getPreference(i);
    174             if (! (pref instanceof AccountPreference)) {
    175                 continue;
    176             }
    177 
    178             AccountPreference accountPref = (AccountPreference) pref;
    179             Account account = accountPref.getAccount();
    180             int syncCount = 0;
    181             boolean syncIsFailing = false;
    182             final ArrayList<String> authorities = accountPref.getAuthorities();
    183             if (authorities != null) {
    184                 for (String authority : authorities) {
    185                     SyncStatusInfo status = ContentResolver.getSyncStatus(account, authority);
    186                     boolean syncEnabled = ContentResolver.getSyncAutomatically(account, authority)
    187                             && masterSyncAutomatically
    188                             && backgroundDataSetting
    189                             && (ContentResolver.getIsSyncable(account, authority) > 0);
    190                     boolean authorityIsPending = ContentResolver.isSyncPending(account, authority);
    191                     boolean activelySyncing = currentSync != null
    192                             && currentSync.authority.equals(authority)
    193                             && new Account(currentSync.account.name, currentSync.account.type).equals(account);
    194                     boolean lastSyncFailed = status != null
    195                             && syncEnabled
    196                             && status.lastFailureTime != 0
    197                             && status.getLastFailureMesgAsInt(0)
    198                                != ContentResolver.SYNC_ERROR_SYNC_ALREADY_IN_PROGRESS;
    199                     if (lastSyncFailed && !activelySyncing && !authorityIsPending) {
    200                         syncIsFailing = true;
    201                         anySyncFailed = true;
    202                     }
    203                     syncCount += syncEnabled && userFacing.contains(authority) ? 1 : 0;
    204                 }
    205             } else {
    206                 if (Log.isLoggable(TAG, Log.VERBOSE)) {
    207                     Log.v(TAG, "no syncadapters found for " + account);
    208                 }
    209             }
    210             int syncStatus = AccountPreference.SYNC_DISABLED;
    211             if (syncIsFailing) {
    212                 syncStatus = AccountPreference.SYNC_ERROR;
    213             } else if (syncCount == 0) {
    214                 syncStatus = AccountPreference.SYNC_DISABLED;
    215             } else if (syncCount > 0) {
    216                 syncStatus = AccountPreference.SYNC_ENABLED;
    217             }
    218             accountPref.setSyncStatus(syncStatus);
    219         }
    220 
    221         mErrorInfoView.setVisibility(anySyncFailed ? View.VISIBLE : View.GONE);
    222     }
    223 
    224     public void onAccountsUpdated(Account[] accounts) {
    225         mManageAccountsCategory.removeAll();
    226         for (int i = 0, n = accounts.length; i < n; i++) {
    227             final Account account = accounts[i];
    228             final ArrayList<String> auths = getAuthoritiesForAccountType(account.type);
    229 
    230             boolean showAccount = true;
    231             if (mAuthorities != null && auths != null) {
    232                 showAccount = false;
    233                 for (String requestedAuthority : mAuthorities) {
    234                     if (auths.contains(requestedAuthority)) {
    235                         showAccount = true;
    236                         break;
    237                     }
    238                 }
    239             }
    240 
    241             if (showAccount) {
    242                 Drawable icon = getDrawableForType(account.type);
    243                 AccountPreference preference = new AccountPreference(this, account, icon, auths);
    244                 mManageAccountsCategory.addPreference(preference);
    245             }
    246         }
    247         onSyncStateUpdated();
    248     }
    249 
    250     @Override
    251     protected void onAuthDescriptionsUpdated() {
    252         // Update account icons for all account preference items
    253         for (int i = 0; i < mManageAccountsCategory.getPreferenceCount(); i++) {
    254             AccountPreference pref = (AccountPreference) mManageAccountsCategory.getPreference(i);
    255             pref.setProviderIcon(getDrawableForType(pref.getAccount().type));
    256             pref.setSummary(getLabelForType(pref.getAccount().type));
    257         }
    258     }
    259 
    260     public void onClick(View v) {
    261         if (v == mAddAccountButton) {
    262             Intent intent = new Intent("android.settings.ADD_ACCOUNT_SETTINGS");
    263             intent.putExtra(AUTHORITIES_FILTER_KEY, mAuthorities);
    264             startActivity(intent);
    265         }
    266     }
    267 }
    268