Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: sync/android/java/src/org/chromium/sync/AndroidSyncSettings.java

Issue 2130453004: [Sync] Move //sync to //components/sync. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « sync/android/OWNERS ('k') | sync/android/java/src/org/chromium/sync/ModelTypeHelper.java » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 package org.chromium.sync;
6
7 import android.accounts.Account;
8 import android.content.ContentResolver;
9 import android.content.Context;
10 import android.content.SyncStatusObserver;
11 import android.os.Bundle;
12 import android.os.StrictMode;
13
14 import org.chromium.base.Callback;
15 import org.chromium.base.ObserverList;
16 import org.chromium.base.VisibleForTesting;
17 import org.chromium.sync.signin.AccountManagerHelper;
18
19 import javax.annotation.concurrent.ThreadSafe;
20
21 /**
22 * A helper class to handle the current status of sync for Chrome in Android set tings.
23 *
24 * It also provides an observer to be used whenever Android sync settings change .
25 *
26 * This class is a collection of static methods so that no references to its obj ect can be
27 * stored. This is important because tests need to be able to overwrite the obje ct with a
28 * mock content resolver and know that no references to the old one are cached.
29 *
30 * This class must be initialized via updateAccount() on startup if the user is signed in.
31 */
32 @ThreadSafe
33 public class AndroidSyncSettings {
34
35 public static final String TAG = "AndroidSyncSettings";
36
37 /**
38 * Lock for ensuring singleton instantiation across threads.
39 */
40 private static final Object CLASS_LOCK = new Object();
41
42 private static AndroidSyncSettings sInstance;
43
44 private final Object mLock = new Object();
45
46 private final String mContractAuthority;
47
48 private final Context mApplicationContext;
49
50 private final SyncContentResolverDelegate mSyncContentResolverDelegate;
51
52 private Account mAccount = null;
53
54 private boolean mIsSyncable = false;
55
56 private boolean mChromeSyncEnabled = false;
57
58 private boolean mMasterSyncEnabled = false;
59
60 private final ObserverList<AndroidSyncSettingsObserver> mObservers =
61 new ObserverList<AndroidSyncSettingsObserver>();
62
63 /**
64 * Provides notifications when Android sync settings have changed.
65 */
66 public interface AndroidSyncSettingsObserver {
67 public void androidSyncSettingsChanged();
68 }
69
70 private static void ensureInitialized(Context context) {
71 synchronized (CLASS_LOCK) {
72 if (sInstance == null) {
73 SyncContentResolverDelegate contentResolver =
74 new SystemSyncContentResolverDelegate();
75 sInstance = new AndroidSyncSettings(context, contentResolver);
76 }
77 }
78 }
79
80 @VisibleForTesting
81 public static void overrideForTests(Context context,
82 SyncContentResolverDelegate contentResolver) {
83 synchronized (CLASS_LOCK) {
84 sInstance = new AndroidSyncSettings(context, contentResolver);
85 }
86 }
87
88 /**
89 * @param context the context the ApplicationContext will be retrieved from.
90 * @param syncContentResolverDelegate an implementation of {@link SyncConten tResolverDelegate}.
91 */
92 private AndroidSyncSettings(Context context,
93 SyncContentResolverDelegate syncContentResolverDelegate) {
94 mApplicationContext = context.getApplicationContext();
95 mSyncContentResolverDelegate = syncContentResolverDelegate;
96 mContractAuthority = getContractAuthority();
97
98 updateCachedSettings();
99
100 mSyncContentResolverDelegate.addStatusChangeListener(
101 ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
102 new AndroidSyncSettingsChangedObserver());
103 }
104
105 /**
106 * Checks whether sync is currently enabled from Chrome for the currently si gned in account.
107 *
108 * It checks both the master sync for the device, and Chrome sync setting fo r the given account.
109 * If no user is currently signed in it returns false.
110 *
111 * @return true if sync is on, false otherwise
112 */
113 public static boolean isSyncEnabled(Context context) {
114 ensureInitialized(context);
115 return sInstance.mMasterSyncEnabled && sInstance.mChromeSyncEnabled;
116 }
117
118 /**
119 * Checks whether sync is currently enabled from Chrome for a given account.
120 *
121 * It checks only Chrome sync setting for the given account,
122 * and ignores the master sync setting.
123 *
124 * @return true if sync is on, false otherwise
125 */
126 @VisibleForTesting
127 public static boolean isChromeSyncEnabled(Context context) {
128 ensureInitialized(context);
129 return sInstance.mChromeSyncEnabled;
130 }
131
132 /**
133 * Checks whether the master sync flag for Android is currently enabled.
134 */
135 public static boolean isMasterSyncEnabled(Context context) {
136 ensureInitialized(context);
137 return sInstance.mMasterSyncEnabled;
138 }
139
140 /**
141 * Make sure Chrome is syncable, and enable sync.
142 */
143 public static void enableChromeSync(Context context) {
144 ensureInitialized(context);
145 sInstance.setChromeSyncEnabled(true);
146 }
147
148 /**
149 * Disables Android Chrome sync
150 */
151 public static void disableChromeSync(Context context) {
152 ensureInitialized(context);
153 sInstance.setChromeSyncEnabled(false);
154 }
155
156 /**
157 * Must be called when a new account is signed in.
158 */
159 public static void updateAccount(Context context, Account account) {
160 ensureInitialized(context);
161 synchronized (sInstance.mLock) {
162 sInstance.mAccount = account;
163 sInstance.updateSyncability();
164 }
165 if (sInstance.updateCachedSettings()) {
166 sInstance.notifyObservers();
167 }
168 }
169
170 /**
171 * Returns the contract authority to use when requesting sync.
172 */
173 public static String getContractAuthority(Context context) {
174 ensureInitialized(context);
175 return sInstance.getContractAuthority();
176 }
177
178 /**
179 * Add a new AndroidSyncSettingsObserver.
180 */
181 public static void registerObserver(Context context, AndroidSyncSettingsObse rver observer) {
182 ensureInitialized(context);
183 synchronized (sInstance.mLock) {
184 sInstance.mObservers.addObserver(observer);
185 }
186 }
187
188 /**
189 * Remove an AndroidSyncSettingsObserver that was previously added.
190 */
191 public static void unregisterObserver(Context context, AndroidSyncSettingsOb server observer) {
192 ensureInitialized(context);
193 synchronized (sInstance.mLock) {
194 sInstance.mObservers.removeObserver(observer);
195 }
196 }
197
198 private void setChromeSyncEnabled(boolean value) {
199 synchronized (mLock) {
200 updateSyncability();
201 if (value == mChromeSyncEnabled || mAccount == null) return;
202 mChromeSyncEnabled = value;
203
204 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites ();
205 mSyncContentResolverDelegate.setSyncAutomatically(mAccount, mContrac tAuthority, value);
206 StrictMode.setThreadPolicy(oldPolicy);
207 }
208 notifyObservers();
209 }
210
211 /**
212 * Ensure Chrome is registered with the Android Sync Manager iff signed in.
213 *
214 * This is what causes the "Chrome" option to appear in Settings -> Accounts -> Sync .
215 * This function must be called within a synchronized block.
216 */
217 private void updateSyncability() {
218 boolean shouldBeSyncable = mAccount != null;
219 if (mIsSyncable == shouldBeSyncable) return;
220
221 mIsSyncable = shouldBeSyncable;
222
223 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
224 // Make account syncable if there is one.
225 if (shouldBeSyncable) {
226 mSyncContentResolverDelegate.setIsSyncable(mAccount, mContractAuthor ity, 1);
227 // This reduces unnecessary resource usage. See http://crbug.com/480 688 for details.
228 mSyncContentResolverDelegate.removePeriodicSync(
229 mAccount, mContractAuthority, Bundle.EMPTY);
230 }
231 StrictMode.setThreadPolicy(oldPolicy);
232
233 // Disable the syncability of Chrome for all other accounts.
234 AccountManagerHelper.get(mApplicationContext).getGoogleAccounts(new Call back<Account[]>() {
235 @Override
236 public void onResult(Account[] accounts) {
237 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWr ites();
238 for (Account account : accounts) {
239 if (!account.equals(mAccount) && mSyncContentResolverDelegat e.getIsSyncable(
240 account, mContractAuthority) > 0) {
241 mSyncContentResolverDelegate.setIsSyncable(account, mCon tractAuthority, 0);
242 }
243 }
244 StrictMode.setThreadPolicy(oldPolicy);
245 }
246 });
247 }
248
249 /**
250 * Helper class to be used by observers whenever sync settings change.
251 *
252 * To register the observer, call AndroidSyncSettings.registerObserver(...).
253 */
254 private class AndroidSyncSettingsChangedObserver implements SyncStatusObserv er {
255 @Override
256 public void onStatusChanged(int which) {
257 if (which == ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS) {
258 // Sync settings have changed; update our cached values.
259 if (updateCachedSettings()) {
260 // If something actually changed, tell our observers.
261 notifyObservers();
262 }
263 }
264 }
265 }
266
267 /**
268 * Update the three cached settings from the content resolver.
269 *
270 * @return Whether either chromeSyncEnabled or masterSyncEnabled changed.
271 */
272 private boolean updateCachedSettings() {
273 synchronized (mLock) {
274 boolean oldChromeSyncEnabled = mChromeSyncEnabled;
275 boolean oldMasterSyncEnabled = mMasterSyncEnabled;
276
277 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites ();
278 if (mAccount != null) {
279 mIsSyncable = mSyncContentResolverDelegate.getIsSyncable(
280 mAccount, mContractAuthority) == 1;
281 mChromeSyncEnabled = mSyncContentResolverDelegate.getSyncAutomat ically(
282 mAccount, mContractAuthority);
283 } else {
284 mIsSyncable = false;
285 mChromeSyncEnabled = false;
286 }
287 mMasterSyncEnabled = mSyncContentResolverDelegate.getMasterSyncAutom atically();
288 StrictMode.setThreadPolicy(oldPolicy);
289
290 return oldChromeSyncEnabled != mChromeSyncEnabled
291 || oldMasterSyncEnabled != mMasterSyncEnabled;
292 }
293 }
294
295 private void notifyObservers() {
296 for (AndroidSyncSettingsObserver observer : mObservers) {
297 observer.androidSyncSettingsChanged();
298 }
299 }
300
301 private String getContractAuthority() {
302 return mApplicationContext.getPackageName();
303 }
304 }
OLDNEW
« no previous file with comments | « sync/android/OWNERS ('k') | sync/android/java/src/org/chromium/sync/ModelTypeHelper.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698