This source file includes following definitions.
- ensureSettingsAreForAccount
- clearUpdateStatus
- getDidUpdateStatus
- getSyncAutomatically
- updateSyncSettingsForAccount
- setIsSyncable
- setSyncAutomatically
- updateSyncSettingsForAccountInternal
- setIsSyncableInternal
- setSyncAutomaticallyInternal
- syncSettingsChanged
- updateMasterSyncAutomaticallySetting
- get
- overrideSyncStatusHelperForTests
- overrideSyncStatusHelperForTests
- getContractAuthority
- registerSyncSettingsChangedObserver
- unregisterSyncSettingsChangedObserver
- isSyncEnabled
- isSyncEnabled
- isSyncEnabledForChrome
- isMasterSyncAutomaticallyEnabled
- enableAndroidSync
- disableAndroidSync
- makeSyncable
- onStatusChanged
- temporarilyAllowDiskWritesAndDiskReads
- getAndClearDidUpdateStatus
- notifyObserversIfAccountSettingsChanged
- notifyObservers
package org.chromium.sync.notifier;
import android.accounts.Account;
import android.content.ContentResolver;
import android.content.Context;
import android.content.SyncStatusObserver;
import android.os.StrictMode;
import com.google.common.annotations.VisibleForTesting;
import org.chromium.base.ObserverList;
import org.chromium.sync.signin.AccountManagerHelper;
import org.chromium.sync.signin.ChromeSigninController;
import javax.annotation.concurrent.NotThreadSafe;
import javax.annotation.concurrent.ThreadSafe;
@ThreadSafe
public class SyncStatusHelper {
@NotThreadSafe
@VisibleForTesting
public static class CachedAccountSyncSettings {
private final String mContractAuthority;
private final SyncContentResolverDelegate mSyncContentResolverDelegate;
private Account mAccount;
private boolean mDidUpdate;
private boolean mSyncAutomatically;
private int mIsSyncable;
public CachedAccountSyncSettings(String contractAuthority,
SyncContentResolverDelegate contentResolverWrapper) {
mContractAuthority = contractAuthority;
mSyncContentResolverDelegate = contentResolverWrapper;
}
private void ensureSettingsAreForAccount(Account account) {
assert account != null;
if (account.equals(mAccount)) return;
updateSyncSettingsForAccount(account);
mDidUpdate = true;
}
public void clearUpdateStatus() {
mDidUpdate = false;
}
public boolean getDidUpdateStatus() {
return mDidUpdate;
}
public boolean getSyncAutomatically(Account account) {
ensureSettingsAreForAccount(account);
return mSyncAutomatically;
}
public void updateSyncSettingsForAccount(Account account) {
if (account == null) return;
updateSyncSettingsForAccountInternal(account);
}
public void setIsSyncable(Account account) {
ensureSettingsAreForAccount(account);
if (mIsSyncable == 1) return;
setIsSyncableInternal(account);
}
public void setSyncAutomatically(Account account, boolean value) {
ensureSettingsAreForAccount(account);
if (mSyncAutomatically == value) return;
setSyncAutomaticallyInternal(account, value);
}
@VisibleForTesting
protected void updateSyncSettingsForAccountInternal(Account account) {
if (account == null) return;
boolean oldSyncAutomatically = mSyncAutomatically;
int oldIsSyncable = mIsSyncable;
Account oldAccount = mAccount;
mAccount = account;
StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
mSyncAutomatically = mSyncContentResolverDelegate.getSyncAutomatically(
account, mContractAuthority);
mIsSyncable = mSyncContentResolverDelegate.getIsSyncable(account, mContractAuthority);
StrictMode.setThreadPolicy(oldPolicy);
mDidUpdate = (oldIsSyncable != mIsSyncable)
|| (oldSyncAutomatically != mSyncAutomatically)
|| (!account.equals(oldAccount));
}
@VisibleForTesting
protected void setIsSyncableInternal(Account account) {
mIsSyncable = 1;
StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
mSyncContentResolverDelegate.setIsSyncable(account, mContractAuthority, 1);
StrictMode.setThreadPolicy(oldPolicy);
mDidUpdate = true;
}
@VisibleForTesting
protected void setSyncAutomaticallyInternal(Account account, boolean value) {
mSyncAutomatically = value;
StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
mSyncContentResolverDelegate.setSyncAutomatically(account, mContractAuthority, value);
StrictMode.setThreadPolicy(oldPolicy);
mDidUpdate = true;
}
}
public static final String CHROME_SYNC_OAUTH2_SCOPE =
"https://www.googleapis.com/auth/chromesync";
public static final String TAG = "SyncStatusHelper";
private static final Object INSTANCE_LOCK = new Object();
private static SyncStatusHelper sSyncStatusHelper;
private final String mContractAuthority;
private final Context mApplicationContext;
private final SyncContentResolverDelegate mSyncContentResolverDelegate;
private boolean mCachedMasterSyncAutomatically;
private CachedAccountSyncSettings mCachedSettings;
private final ObserverList<SyncSettingsChangedObserver> mObservers =
new ObserverList<SyncSettingsChangedObserver>();
public interface SyncSettingsChangedObserver {
public void syncSettingsChanged();
}
private SyncStatusHelper(Context context,
SyncContentResolverDelegate syncContentResolverDelegate,
CachedAccountSyncSettings cachedAccountSettings) {
mApplicationContext = context.getApplicationContext();
mSyncContentResolverDelegate = syncContentResolverDelegate;
mContractAuthority = getContractAuthority();
mCachedSettings = cachedAccountSettings;
updateMasterSyncAutomaticallySetting();
mSyncContentResolverDelegate.addStatusChangeListener(
ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
new AndroidSyncSettingsChangedObserver());
}
private void updateMasterSyncAutomaticallySetting() {
StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
synchronized (mCachedSettings) {
mCachedMasterSyncAutomatically = mSyncContentResolverDelegate
.getMasterSyncAutomatically();
}
StrictMode.setThreadPolicy(oldPolicy);
}
public static SyncStatusHelper get(Context context) {
synchronized (INSTANCE_LOCK) {
if (sSyncStatusHelper == null) {
SyncContentResolverDelegate contentResolverDelegate =
new SystemSyncContentResolverDelegate();
CachedAccountSyncSettings cache = new CachedAccountSyncSettings(
context.getPackageName(), contentResolverDelegate);
sSyncStatusHelper = new SyncStatusHelper(context, contentResolverDelegate, cache);
}
}
return sSyncStatusHelper;
}
@VisibleForTesting
public static void overrideSyncStatusHelperForTests(Context context,
SyncContentResolverDelegate syncContentResolverDelegate,
CachedAccountSyncSettings cachedAccountSettings) {
synchronized (INSTANCE_LOCK) {
if (sSyncStatusHelper != null) {
throw new IllegalStateException("SyncStatusHelper already exists");
}
sSyncStatusHelper = new SyncStatusHelper(context, syncContentResolverDelegate,
cachedAccountSettings);
}
}
@VisibleForTesting
public static void overrideSyncStatusHelperForTests(Context context,
SyncContentResolverDelegate syncContentResolverDelegate) {
CachedAccountSyncSettings cachedAccountSettings = new CachedAccountSyncSettings(
context.getPackageName(), syncContentResolverDelegate);
overrideSyncStatusHelperForTests(context, syncContentResolverDelegate,
cachedAccountSettings);
}
public String getContractAuthority() {
return mApplicationContext.getPackageName();
}
public void registerSyncSettingsChangedObserver(SyncSettingsChangedObserver observer) {
mObservers.addObserver(observer);
}
public void unregisterSyncSettingsChangedObserver(SyncSettingsChangedObserver observer) {
mObservers.removeObserver(observer);
}
public boolean isSyncEnabled(Account account) {
if (account == null) return false;
boolean returnValue;
synchronized (mCachedSettings) {
returnValue = mCachedMasterSyncAutomatically &&
mCachedSettings.getSyncAutomatically(account);
}
notifyObserversIfAccountSettingsChanged();
return returnValue;
}
public boolean isSyncEnabled() {
return isSyncEnabled(ChromeSigninController.get(mApplicationContext).getSignedInUser());
}
public boolean isSyncEnabledForChrome(Account account) {
if (account == null) return false;
boolean returnValue;
synchronized (mCachedSettings) {
returnValue = mCachedSettings.getSyncAutomatically(account);
}
notifyObserversIfAccountSettingsChanged();
return returnValue;
}
public boolean isMasterSyncAutomaticallyEnabled() {
synchronized (mCachedSettings) {
return mCachedMasterSyncAutomatically;
}
}
public void enableAndroidSync(Account account) {
makeSyncable(account);
synchronized (mCachedSettings) {
mCachedSettings.setSyncAutomatically(account, true);
}
notifyObserversIfAccountSettingsChanged();
}
public void disableAndroidSync(Account account) {
synchronized (mCachedSettings) {
mCachedSettings.setSyncAutomatically(account, false);
}
notifyObserversIfAccountSettingsChanged();
}
private void makeSyncable(Account account) {
synchronized (mCachedSettings) {
mCachedSettings.setIsSyncable(account);
}
StrictMode.ThreadPolicy oldPolicy = temporarilyAllowDiskWritesAndDiskReads();
Account[] googleAccounts = AccountManagerHelper.get(mApplicationContext).
getGoogleAccounts();
for (Account accountToSetNotSyncable : googleAccounts) {
if (!accountToSetNotSyncable.equals(account) &&
mSyncContentResolverDelegate.getIsSyncable(
accountToSetNotSyncable, mContractAuthority) > 0) {
mSyncContentResolverDelegate.setIsSyncable(accountToSetNotSyncable,
mContractAuthority, 0);
}
}
StrictMode.setThreadPolicy(oldPolicy);
}
private class AndroidSyncSettingsChangedObserver implements SyncStatusObserver {
@Override
public void onStatusChanged(int which) {
if (ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS == which) {
synchronized (mCachedSettings) {
mCachedSettings.updateSyncSettingsForAccount(
ChromeSigninController.get(mApplicationContext).getSignedInUser());
}
boolean oldMasterSyncEnabled = isMasterSyncAutomaticallyEnabled();
updateMasterSyncAutomaticallySetting();
boolean didMasterSyncChanged =
oldMasterSyncEnabled != isMasterSyncAutomaticallyEnabled();
if (didMasterSyncChanged || getAndClearDidUpdateStatus())
notifyObservers();
}
}
}
private static StrictMode.ThreadPolicy temporarilyAllowDiskWritesAndDiskReads() {
StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
StrictMode.ThreadPolicy.Builder newPolicy =
new StrictMode.ThreadPolicy.Builder(oldPolicy);
newPolicy.permitDiskReads();
newPolicy.permitDiskWrites();
StrictMode.setThreadPolicy(newPolicy.build());
return oldPolicy;
}
private boolean getAndClearDidUpdateStatus() {
boolean didGetStatusUpdate;
synchronized (mCachedSettings) {
didGetStatusUpdate = mCachedSettings.getDidUpdateStatus();
mCachedSettings.clearUpdateStatus();
}
return didGetStatusUpdate;
}
private void notifyObserversIfAccountSettingsChanged() {
if (getAndClearDidUpdateStatus()) {
notifyObservers();
}
}
private void notifyObservers() {
for (SyncSettingsChangedObserver observer : mObservers) {
observer.syncSettingsChanged();
}
}
}