Add back a SYNC_SETTINGS screen

Revive the old Accounts&Sync screen as a dialog with the auto-sync
checkbox and a list of accounts. This will be launched when Apps
request a SYNC_SETTINGS page for controlling account and master sync.

Auto-sync data checkbox will also continue to exist in Data Usage.

Minor fixes to account list and account update monitoring.

Bug: 6614013
Bug: 6622995
Bug: 6610247
Change-Id: I35c0919a29c6bc7e5edf64f2734a3ef4f5ae5e7a
This commit is contained in:
Amith Yamasani
2012-06-06 20:23:08 -07:00
parent 6a5e0252ce
commit 86708a8a6d
8 changed files with 287 additions and 23 deletions

View File

@@ -1366,6 +1366,7 @@
<activity android:name="Settings$AccountSyncSettingsActivity" <activity android:name="Settings$AccountSyncSettingsActivity"
android:label="@string/account_sync_settings_title" android:label="@string/account_sync_settings_title"
android:parentActivityName="Settings"
android:uiOptions="none"> android:uiOptions="none">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
@@ -1378,6 +1379,16 @@
android:resource="@id/account_settings" /> android:resource="@id/account_settings" />
</activity> </activity>
<activity android:name=".accounts.SyncSettingsActivity"
android:label="@string/account_sync_settings_title"
android:theme="@android:style/Theme.Holo.Dialog">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.SYNC_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name="com.android.settings.accounts.AddAccountSettings" <activity android:name="com.android.settings.accounts.AddAccountSettings"
android:theme="@android:style/Theme.Translucent.NoTitleBar" android:theme="@android:style/Theme.Translucent.NoTitleBar"
android:configChanges="orientation|keyboardHidden|screenSize" android:configChanges="orientation|keyboardHidden|screenSize"
@@ -1441,7 +1452,6 @@
android:parentActivityName="Settings"> android:parentActivityName="Settings">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.SYNC_SETTINGS" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />
<category android:name="com.android.settings.SHORTCUT" /> <category android:name="com.android.settings.SHORTCUT" />
</intent-filter> </intent-filter>

View File

@@ -48,7 +48,7 @@
<dimen name="divider_margin_bottom">7dip</dimen> <dimen name="divider_margin_bottom">7dip</dimen>
<!-- Size of icons in the top-level of settings --> <!-- Size of icons in the top-level of settings -->
<dimen name="header_icon_width">32dp</dimen> <dimen name="header_icon_width">28dp</dimen>
<dimen name="appwidget_min_width">260dip</dimen> <dimen name="appwidget_min_width">260dip</dimen>
<dimen name="appwidget_min_height">40dip</dimen> <dimen name="appwidget_min_height">40dip</dimen>
</resources> </resources>

21
res/xml/sync_settings.xml Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="sync_switch"
android:title="@string/sync_automatically" />
</PreferenceScreen>

View File

@@ -39,16 +39,24 @@ public class AccountPreference extends Preference {
private int mStatus; private int mStatus;
private Account mAccount; private Account mAccount;
private ArrayList<String> mAuthorities; private ArrayList<String> mAuthorities;
private ImageView mSyncStatusIcon;
private boolean mShowTypeIcon;
public AccountPreference(Context context, Account account, Drawable icon, public AccountPreference(Context context, Account account, Drawable icon,
ArrayList<String> authorities) { ArrayList<String> authorities, boolean showTypeIcon) {
super(context); super(context);
mAccount = account; mAccount = account;
mAuthorities = authorities; mAuthorities = authorities;
mShowTypeIcon = showTypeIcon;
if (showTypeIcon) {
setIcon(icon);
} else {
setIcon(getSyncStatusIcon(SYNC_DISABLED));
}
setTitle(mAccount.name); setTitle(mAccount.name);
setSummary(""); setSummary("");
setPersistent(false); setPersistent(false);
setSyncStatus(SYNC_DISABLED); setSyncStatus(SYNC_DISABLED, false);
} }
public Account getAccount() { public Account getAccount() {
@@ -62,17 +70,23 @@ public class AccountPreference extends Preference {
@Override @Override
protected void onBindView(View view) { protected void onBindView(View view) {
super.onBindView(view); super.onBindView(view);
setSummary(getSyncStatusMessage(mStatus)); if (!mShowTypeIcon) {
ImageView iconView = (ImageView) view.findViewById(android.R.id.icon); mSyncStatusIcon = (ImageView) view.findViewById(android.R.id.icon);
iconView.setImageResource(getSyncStatusIcon(mStatus)); mSyncStatusIcon.setImageResource(getSyncStatusIcon(mStatus));
iconView.setContentDescription(getSyncContentDescription(mStatus)); mSyncStatusIcon.setContentDescription(getSyncContentDescription(mStatus));
}
} }
public void setSyncStatus(int status) { public void setSyncStatus(int status, boolean updateSummary) {
mStatus = status; mStatus = status;
setIcon(getSyncStatusIcon(status)); if (!mShowTypeIcon && mSyncStatusIcon != null) {
mSyncStatusIcon.setImageResource(getSyncStatusIcon(status));
mSyncStatusIcon.setContentDescription(getSyncContentDescription(mStatus));
}
if (updateSummary) {
setSummary(getSyncStatusMessage(status)); setSummary(getSyncStatusMessage(status));
} }
}
private int getSyncStatusMessage(int status) { private int getSyncStatusMessage(int status) {
int res; int res;
@@ -109,7 +123,7 @@ public class AccountPreference extends Preference {
res = R.drawable.ic_sync_red_holo; res = R.drawable.ic_sync_red_holo;
break; break;
case SYNC_IN_PROGRESS: case SYNC_IN_PROGRESS:
res = R.drawable.ic_sync_grey_holo; res = R.drawable.ic_sync_green_holo;
break; break;
default: default:
res = R.drawable.ic_sync_red_holo; res = R.drawable.ic_sync_red_holo;

View File

@@ -112,6 +112,7 @@ public class Settings extends PreferenceActivity
private AuthenticatorHelper mAuthenticatorHelper; private AuthenticatorHelper mAuthenticatorHelper;
private Header mLastHeader; private Header mLastHeader;
private boolean mListeningToAccountUpdates;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@@ -187,7 +188,6 @@ public class Settings extends PreferenceActivity
ListAdapter listAdapter = getListAdapter(); ListAdapter listAdapter = getListAdapter();
if (listAdapter instanceof HeaderAdapter) { if (listAdapter instanceof HeaderAdapter) {
((HeaderAdapter) listAdapter).resume(); ((HeaderAdapter) listAdapter).resume();
AccountManager.get(this).addOnAccountsUpdatedListener(this, null, true);
} }
} }
@@ -198,6 +198,13 @@ public class Settings extends PreferenceActivity
ListAdapter listAdapter = getListAdapter(); ListAdapter listAdapter = getListAdapter();
if (listAdapter instanceof HeaderAdapter) { if (listAdapter instanceof HeaderAdapter) {
((HeaderAdapter) listAdapter).pause(); ((HeaderAdapter) listAdapter).pause();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mListeningToAccountUpdates) {
AccountManager.get(this).removeOnAccountsUpdatedListener(this); AccountManager.get(this).removeOnAccountsUpdatedListener(this);
} }
} }
@@ -462,6 +469,10 @@ public class Settings extends PreferenceActivity
for (Header header : accountHeaders) { for (Header header : accountHeaders) {
target.add(headerIndex++, header); target.add(headerIndex++, header);
} }
if (!mListeningToAccountUpdates) {
AccountManager.get(this).addOnAccountsUpdatedListener(this, null, true);
mListeningToAccountUpdates = true;
}
return headerIndex; return headerIndex;
} }

View File

@@ -166,8 +166,8 @@ public class ManageAccountsSettings extends AccountPreferenceBase
public void onPrepareOptionsMenu(Menu menu) { public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu); super.onPrepareOptionsMenu(menu);
boolean syncActive = ContentResolver.getCurrentSync() != null; boolean syncActive = ContentResolver.getCurrentSync() != null;
menu.findItem(MENU_SYNC_NOW_ID).setVisible(!syncActive); menu.findItem(MENU_SYNC_NOW_ID).setVisible(!syncActive && mFirstAccount != null);
menu.findItem(MENU_SYNC_CANCEL_ID).setVisible(syncActive); menu.findItem(MENU_SYNC_CANCEL_ID).setVisible(syncActive && mFirstAccount != null);
} }
@Override @Override
@@ -274,16 +274,16 @@ public class ManageAccountsSettings extends AccountPreferenceBase
} }
} }
if (syncIsFailing) { if (syncIsFailing) {
accountPref.setSyncStatus(AccountPreference.SYNC_ERROR); accountPref.setSyncStatus(AccountPreference.SYNC_ERROR, true);
} else if (syncCount == 0) { } else if (syncCount == 0) {
accountPref.setSyncStatus(AccountPreference.SYNC_DISABLED); accountPref.setSyncStatus(AccountPreference.SYNC_DISABLED, true);
} else if (syncCount > 0) { } else if (syncCount > 0) {
if (syncingNow) { if (syncingNow) {
accountPref.setSyncStatus(AccountPreference.SYNC_IN_PROGRESS); accountPref.setSyncStatus(AccountPreference.SYNC_IN_PROGRESS, true);
} else { } else {
accountPref.setSyncStatus(AccountPreference.SYNC_ENABLED); accountPref.setSyncStatus(AccountPreference.SYNC_ENABLED, true);
if (lastSuccessTime > 0) { if (lastSuccessTime > 0) {
accountPref.setSyncStatus(AccountPreference.SYNC_ENABLED); accountPref.setSyncStatus(AccountPreference.SYNC_ENABLED, false);
date.setTime(lastSuccessTime); date.setTime(lastSuccessTime);
final String timeString = formatSyncDate(date); final String timeString = formatSyncDate(date);
accountPref.setSummary(getResources().getString( accountPref.setSummary(getResources().getString(
@@ -291,7 +291,7 @@ public class ManageAccountsSettings extends AccountPreferenceBase
} }
} }
} else { } else {
accountPref.setSyncStatus(AccountPreference.SYNC_DISABLED); accountPref.setSyncStatus(AccountPreference.SYNC_DISABLED, true);
} }
} }
@@ -324,14 +324,14 @@ public class ManageAccountsSettings extends AccountPreferenceBase
if (showAccount) { if (showAccount) {
final Drawable icon = getDrawableForType(account.type); final Drawable icon = getDrawableForType(account.type);
final AccountPreference preference = final AccountPreference preference =
new AccountPreference(getActivity(), account, icon, auths); new AccountPreference(getActivity(), account, icon, auths, false);
getPreferenceScreen().addPreference(preference); getPreferenceScreen().addPreference(preference);
if (mFirstAccount == null) { if (mFirstAccount == null) {
mFirstAccount = account; mFirstAccount = account;
} }
} }
} }
if (mAccountType != null) { if (mAccountType != null && mFirstAccount != null) {
addAuthenticatorSettings(); addAuthenticatorSettings();
} }
onSyncStateUpdated(); onSyncStateUpdated();

View File

@@ -0,0 +1,174 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accounts;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.OnAccountsUpdateListener;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceScreen;
import android.util.Log;
import com.android.settings.AccountPreference;
import com.android.settings.DialogCreatable;
import com.android.settings.R;
import java.util.ArrayList;
public class SyncSettings extends AccountPreferenceBase
implements OnAccountsUpdateListener, DialogCreatable {
private static final String KEY_SYNC_SWITCH = "sync_switch";
private String[] mAuthorities;
private SettingsDialogFragment mDialogFragment;
private CheckBoxPreference mAutoSyncPreference;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
addPreferencesFromResource(R.xml.sync_settings);
mAutoSyncPreference =
(CheckBoxPreference) getPreferenceScreen().findPreference(KEY_SYNC_SWITCH);
mAutoSyncPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
ContentResolver.setMasterSyncAutomatically((Boolean) newValue);
return true;
}
});
setHasOptionsMenu(true);
}
@Override
public void onStart() {
super.onStart();
Activity activity = getActivity();
AccountManager.get(activity).addOnAccountsUpdatedListener(this, null, true);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
final Activity activity = getActivity();
mAutoSyncPreference.setChecked(ContentResolver.getMasterSyncAutomatically());
mAuthorities = activity.getIntent().getStringArrayExtra(AUTHORITIES_FILTER_KEY);
updateAuthDescriptions();
}
@Override
public void onStop() {
super.onStop();
final Activity activity = getActivity();
AccountManager.get(activity).removeOnAccountsUpdatedListener(this);
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferences, Preference preference) {
if (preference instanceof AccountPreference) {
startAccountSettings((AccountPreference) preference);
} else {
return false;
}
return true;
}
private void startAccountSettings(AccountPreference acctPref) {
Intent intent = new Intent("android.settings.ACCOUNT_SYNC_SETTINGS");
intent.putExtra(AccountSyncSettings.ACCOUNT_KEY, acctPref.getAccount());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
@Override
public void showDialog(int dialogId) {
if (mDialogFragment != null) {
Log.e(TAG, "Old dialog fragment not null!");
}
mDialogFragment = new SettingsDialogFragment(this, dialogId);
mDialogFragment.show(getActivity().getFragmentManager(), Integer.toString(dialogId));
}
private void removeAccountPreferences() {
PreferenceScreen parent = getPreferenceScreen();
for (int i = 0; i < parent.getPreferenceCount(); ) {
if (parent.getPreference(i) instanceof AccountPreference) {
parent.removePreference(parent.getPreference(i));
} else {
i++;
}
}
}
@Override
public void onAccountsUpdated(Account[] accounts) {
if (getActivity() == null) return;
removeAccountPreferences();
for (int i = 0, n = accounts.length; i < n; i++) {
final Account account = accounts[i];
final ArrayList<String> auths = getAuthoritiesForAccountType(account.type);
boolean showAccount = true;
if (mAuthorities != null && auths != null) {
showAccount = false;
for (String requestedAuthority : mAuthorities) {
if (auths.contains(requestedAuthority)) {
showAccount = true;
break;
}
}
}
if (showAccount) {
final Drawable icon = getDrawableForType(account.type);
final AccountPreference preference =
new AccountPreference(getActivity(), account, icon, auths, true);
getPreferenceScreen().addPreference(preference);
preference.setSummary(getLabelForType(account.type));
}
}
onSyncStateUpdated();
}
@Override
protected void onAuthDescriptionsUpdated() {
// Update account icons for all account preference items
for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
Preference pref = getPreferenceScreen().getPreference(i);
if (pref instanceof AccountPreference) {
AccountPreference accPref = (AccountPreference)
getPreferenceScreen().getPreference(i);
accPref.setIcon(getDrawableForType(accPref.getAccount().type));
accPref.setSummary(getLabelForType(accPref.getAccount().type));
}
}
}
}

View File

@@ -0,0 +1,34 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.accounts;
import android.content.Intent;
import android.preference.PreferenceActivity;
/**
* Launcher activity for the SyncSettings fragment.
*
*/
public class SyncSettingsActivity extends PreferenceActivity {
@Override
public Intent getIntent() {
Intent modIntent = new Intent(super.getIntent());
modIntent.putExtra(EXTRA_SHOW_FRAGMENT, SyncSettings.class.getName());
modIntent.putExtra(EXTRA_NO_HEADERS, true);
return modIntent;
}
}