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

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

Issue 1138013008: [Sync] Make it impossible to get a reference to AndroidSyncSettings. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase and address nit. Created 5 years, 7 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.sync; 5 package org.chromium.sync;
6 6
7 import android.accounts.Account; 7 import android.accounts.Account;
8 import android.content.ContentResolver; 8 import android.content.ContentResolver;
9 import android.content.Context; 9 import android.content.Context;
10 import android.content.SyncStatusObserver; 10 import android.content.SyncStatusObserver;
11 import android.os.StrictMode; 11 import android.os.StrictMode;
12 12
13 import org.chromium.base.ObserverList; 13 import org.chromium.base.ObserverList;
14 import org.chromium.base.VisibleForTesting; 14 import org.chromium.base.VisibleForTesting;
15 import org.chromium.sync.signin.AccountManagerHelper; 15 import org.chromium.sync.signin.AccountManagerHelper;
16 16
17 import javax.annotation.concurrent.ThreadSafe; 17 import javax.annotation.concurrent.ThreadSafe;
18 18
19 /** 19 /**
20 * A helper class to handle the current status of sync for Chrome in Android set tings. 20 * A helper class to handle the current status of sync for Chrome in Android set tings.
21 * 21 *
22 * It also provides an observer to be used whenever Android sync settings change . 22 * It also provides an observer to be used whenever Android sync settings change .
23 * 23 *
24 * To retrieve an instance of this class, call AndroidSyncSettings.get(someConte xt). 24 * This class is a collection of static methods so that no references to its obj ect can be
25 * stored. This is important because tests need to be able to overwrite the obje ct with a
26 * mock content resolver and know that no references to the old one are cached.
25 * 27 *
26 * This class must be initialized via updateAccount() on startup if the user is signed in. 28 * This class must be initialized via updateAccount() on startup if the user is signed in.
27 */ 29 */
28 @ThreadSafe 30 @ThreadSafe
29 public class AndroidSyncSettings { 31 public class AndroidSyncSettings {
30 32
31 public static final String TAG = "AndroidSyncSettings"; 33 public static final String TAG = "AndroidSyncSettings";
32 34
33 /** 35 /**
34 * Lock for ensuring singleton instantiation across threads. 36 * Lock for ensuring singleton instantiation across threads.
35 */ 37 */
36 private static final Object CLASS_LOCK = new Object(); 38 private static final Object CLASS_LOCK = new Object();
37 39
38 private static AndroidSyncSettings sAndroidSyncSettings; 40 private static AndroidSyncSettings sInstance;
39 41
40 private final Object mLock = new Object(); 42 private final Object mLock = new Object();
41 43
42 private final String mContractAuthority; 44 private final String mContractAuthority;
43 45
44 private final Context mApplicationContext; 46 private final Context mApplicationContext;
45 47
46 private final SyncContentResolverDelegate mSyncContentResolverDelegate; 48 private final SyncContentResolverDelegate mSyncContentResolverDelegate;
47 49
48 private Account mAccount = null; 50 private Account mAccount = null;
49 51
50 private boolean mIsSyncable = false; 52 private boolean mIsSyncable = false;
51 53
52 private boolean mChromeSyncEnabled = false; 54 private boolean mChromeSyncEnabled = false;
53 55
54 private boolean mMasterSyncEnabled = false; 56 private boolean mMasterSyncEnabled = false;
55 57
56 private final ObserverList<AndroidSyncSettingsObserver> mObservers = 58 private final ObserverList<AndroidSyncSettingsObserver> mObservers =
57 new ObserverList<AndroidSyncSettingsObserver>(); 59 new ObserverList<AndroidSyncSettingsObserver>();
58 60
59 /** 61 /**
60 * Provides notifications when Android sync settings have changed. 62 * Provides notifications when Android sync settings have changed.
61 */ 63 */
62 public interface AndroidSyncSettingsObserver { 64 public interface AndroidSyncSettingsObserver {
63 public void androidSyncSettingsChanged(); 65 public void androidSyncSettingsChanged();
64 } 66 }
65 67
66 /** 68 private static void ensureInitialized(Context context) {
67 * A factory method for the AndroidSyncSettings.
68 *
69 * It is possible to override the {@link SyncContentResolverDelegate} to use in tests for the
70 * instance of the AndroidSyncSettings by calling overrideForTests(...) with
71 * your {@link SyncContentResolverDelegate}.
72 *
73 * @param context the ApplicationContext is retrieved from the context used as an argument.
74 * @return a singleton instance of the AndroidSyncSettings
75 */
76 public static AndroidSyncSettings get(Context context) {
77 synchronized (CLASS_LOCK) { 69 synchronized (CLASS_LOCK) {
78 if (sAndroidSyncSettings == null) { 70 if (sInstance == null) {
79 SyncContentResolverDelegate contentResolver = 71 SyncContentResolverDelegate contentResolver =
80 new SystemSyncContentResolverDelegate(); 72 new SystemSyncContentResolverDelegate();
81 sAndroidSyncSettings = new AndroidSyncSettings(context, contentR esolver); 73 sInstance = new AndroidSyncSettings(context, contentResolver);
82 } 74 }
83 } 75 }
84 return sAndroidSyncSettings;
85 } 76 }
86 77
87 @VisibleForTesting 78 @VisibleForTesting
88 public static void overrideForTests(Context context, 79 public static void overrideForTests(Context context,
89 SyncContentResolverDelegate contentResolver) { 80 SyncContentResolverDelegate contentResolver) {
90 synchronized (CLASS_LOCK) { 81 synchronized (CLASS_LOCK) {
91 sAndroidSyncSettings = new AndroidSyncSettings(context, contentResol ver); 82 sInstance = new AndroidSyncSettings(context, contentResolver);
92 } 83 }
93 } 84 }
94 85
95 /** 86 /**
96 * @param context the context 87 * @param context the context the ApplicationContext will be retrieved from.
97 * @param syncContentResolverDelegate an implementation of {@link SyncConten tResolverDelegate}. 88 * @param syncContentResolverDelegate an implementation of {@link SyncConten tResolverDelegate}.
98 */ 89 */
99 private AndroidSyncSettings(Context context, 90 private AndroidSyncSettings(Context context,
100 SyncContentResolverDelegate syncContentResolverDelegate) { 91 SyncContentResolverDelegate syncContentResolverDelegate) {
101 mApplicationContext = context.getApplicationContext(); 92 mApplicationContext = context.getApplicationContext();
102 mSyncContentResolverDelegate = syncContentResolverDelegate; 93 mSyncContentResolverDelegate = syncContentResolverDelegate;
103 mContractAuthority = getContractAuthority(); 94 mContractAuthority = getContractAuthority();
104 95
105 updateCachedSettings(); 96 updateCachedSettings();
106 97
107 mSyncContentResolverDelegate.addStatusChangeListener( 98 mSyncContentResolverDelegate.addStatusChangeListener(
108 ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, 99 ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS,
109 new AndroidSyncSettingsChangedObserver()); 100 new AndroidSyncSettingsChangedObserver());
110 } 101 }
111 102
112 /** 103 /**
113 * Checks whether sync is currently enabled from Chrome for the currently si gned in account. 104 * Checks whether sync is currently enabled from Chrome for the currently si gned in account.
114 * 105 *
115 * It checks both the master sync for the device, and Chrome sync setting fo r the given account. 106 * It checks both the master sync for the device, and Chrome sync setting fo r the given account.
116 * If no user is currently signed in it returns false. 107 * If no user is currently signed in it returns false.
117 * 108 *
118 * @return true if sync is on, false otherwise 109 * @return true if sync is on, false otherwise
119 */ 110 */
120 public boolean isSyncEnabled() { 111 public static boolean isSyncEnabled(Context context) {
121 return mMasterSyncEnabled && mChromeSyncEnabled; 112 ensureInitialized(context);
113 return sInstance.mMasterSyncEnabled && sInstance.mChromeSyncEnabled;
122 } 114 }
123 115
124 /** 116 /**
125 * Checks whether sync is currently enabled from Chrome for a given account. 117 * Checks whether sync is currently enabled from Chrome for a given account.
126 * 118 *
127 * It checks only Chrome sync setting for the given account, 119 * It checks only Chrome sync setting for the given account,
128 * and ignores the master sync setting. 120 * and ignores the master sync setting.
129 * 121 *
130 * @return true if sync is on, false otherwise 122 * @return true if sync is on, false otherwise
131 */ 123 */
132 public boolean isChromeSyncEnabled() { 124 public static boolean isChromeSyncEnabled(Context context) {
133 return mChromeSyncEnabled; 125 ensureInitialized(context);
126 return sInstance.mChromeSyncEnabled;
134 } 127 }
135 128
136 /** 129 /**
137 * Checks whether the master sync flag for Android is currently enabled. 130 * Checks whether the master sync flag for Android is currently enabled.
138 */ 131 */
139 public boolean isMasterSyncEnabled() { 132 public static boolean isMasterSyncEnabled(Context context) {
140 return mMasterSyncEnabled; 133 ensureInitialized(context);
134 return sInstance.mMasterSyncEnabled;
141 } 135 }
142 136
143 /** 137 /**
144 * Make sure Chrome is syncable, and enable sync. 138 * Make sure Chrome is syncable, and enable sync.
145 */ 139 */
146 public void enableChromeSync() { 140 public static void enableChromeSync(Context context) {
147 setChromeSyncEnabled(true); 141 ensureInitialized(context);
142 sInstance.setChromeSyncEnabled(true);
148 } 143 }
149 144
150 /** 145 /**
151 * Disables Android Chrome sync 146 * Disables Android Chrome sync
152 */ 147 */
153 public void disableChromeSync() { 148 public static void disableChromeSync(Context context) {
154 setChromeSyncEnabled(false); 149 ensureInitialized(context);
150 sInstance.setChromeSyncEnabled(false);
155 } 151 }
156 152
157 /** 153 /**
158 * Must be called when a new account is signed in. 154 * Must be called when a new account is signed in.
159 */ 155 */
160 public void updateAccount(Account account) { 156 public static void updateAccount(Context context, Account account) {
161 synchronized (mLock) { 157 ensureInitialized(context);
162 mAccount = account; 158 synchronized (sInstance.mLock) {
163 updateSyncability(); 159 sInstance.mAccount = account;
160 sInstance.updateSyncability();
164 } 161 }
165 if (updateCachedSettings()) { 162 if (sInstance.updateCachedSettings()) {
166 notifyObservers(); 163 sInstance.notifyObservers();
167 } 164 }
168 } 165 }
169 166
170 /** 167 /**
171 * Returns the contract authority to use when requesting sync. 168 * Returns the contract authority to use when requesting sync.
172 */ 169 */
173 public String getContractAuthority() { 170 public static String getContractAuthority(Context context) {
174 return mApplicationContext.getPackageName(); 171 ensureInitialized(context);
172 return sInstance.getContractAuthority();
175 } 173 }
176 174
177 /** 175 /**
178 * Add a new AndroidSyncSettingsObserver. 176 * Add a new AndroidSyncSettingsObserver.
179 */ 177 */
180 public void registerObserver(AndroidSyncSettingsObserver observer) { 178 public static void registerObserver(Context context, AndroidSyncSettingsObse rver observer) {
181 synchronized (mLock) { 179 ensureInitialized(context);
182 mObservers.addObserver(observer); 180 synchronized (sInstance.mLock) {
181 sInstance.mObservers.addObserver(observer);
183 } 182 }
184 } 183 }
185 184
186 /** 185 /**
187 * Remove an AndroidSyncSettingsObserver that was previously added. 186 * Remove an AndroidSyncSettingsObserver that was previously added.
188 */ 187 */
189 public void unregisterObserver(AndroidSyncSettingsObserver observer) { 188 public static void unregisterObserver(Context context, AndroidSyncSettingsOb server observer) {
190 synchronized (mLock) { 189 ensureInitialized(context);
191 mObservers.removeObserver(observer); 190 synchronized (sInstance.mLock) {
191 sInstance.mObservers.removeObserver(observer);
192 } 192 }
193 } 193 }
194 194
195 private void setChromeSyncEnabled(boolean value) { 195 private void setChromeSyncEnabled(boolean value) {
196 synchronized (mLock) { 196 synchronized (mLock) {
197 updateSyncability(); 197 updateSyncability();
198 if (value == mChromeSyncEnabled || mAccount == null) return; 198 if (value == mChromeSyncEnabled || mAccount == null) return;
199 mChromeSyncEnabled = value; 199 mChromeSyncEnabled = value;
200 200
201 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites (); 201 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites ();
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 return oldChromeSyncEnabled != mChromeSyncEnabled 283 return oldChromeSyncEnabled != mChromeSyncEnabled
284 || oldMasterSyncEnabled != mMasterSyncEnabled; 284 || oldMasterSyncEnabled != mMasterSyncEnabled;
285 } 285 }
286 } 286 }
287 287
288 private void notifyObservers() { 288 private void notifyObservers() {
289 for (AndroidSyncSettingsObserver observer : mObservers) { 289 for (AndroidSyncSettingsObserver observer : mObservers) {
290 observer.androidSyncSettingsChanged(); 290 observer.androidSyncSettingsChanged();
291 } 291 }
292 } 292 }
293
294 // TODO(maxbogue): make private once downstream uses are removed.
295 @Deprecated
296 public String getContractAuthority() {
297 return mApplicationContext.getPackageName();
298 }
299
300 // Deprecated section; to be removed once downstream no longer uses them.
301
302 @Deprecated
303 public static AndroidSyncSettings get(Context context) {
304 ensureInitialized(context);
305 return sInstance;
306 }
307
308 @Deprecated
309 public boolean isSyncEnabled() {
310 return mMasterSyncEnabled && mChromeSyncEnabled;
311 }
312
313 @Deprecated
314 public boolean isChromeSyncEnabled() {
315 return mChromeSyncEnabled;
316 }
317
318 @Deprecated
319 public boolean isMasterSyncEnabled() {
320 return mMasterSyncEnabled;
321 }
322
323 @Deprecated
324 public void enableChromeSync() {
325 setChromeSyncEnabled(true);
326 }
327
328 @Deprecated
329 public void disableChromeSync() {
330 setChromeSyncEnabled(false);
331 }
332
333 @Deprecated
334 public void updateAccount(Account account) {
335 synchronized (mLock) {
336 mAccount = account;
337 updateSyncability();
338 }
339 if (updateCachedSettings()) {
340 notifyObservers();
341 }
342 }
343
344 @Deprecated
345 public void registerObserver(AndroidSyncSettingsObserver observer) {
346 synchronized (mLock) {
347 mObservers.addObserver(observer);
348 }
349 }
350
351 @Deprecated
352 public void unregisterObserver(AndroidSyncSettingsObserver observer) {
353 synchronized (mLock) {
354 mObservers.removeObserver(observer);
355 }
356 }
293 } 357 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698