OLD | NEW |
| (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.Context; | |
9 import android.os.Bundle; | |
10 import android.test.InstrumentationTestCase; | |
11 import android.test.suitebuilder.annotation.SmallTest; | |
12 | |
13 import org.chromium.base.ThreadUtils; | |
14 import org.chromium.base.test.util.DisabledTest; | |
15 import org.chromium.base.test.util.Feature; | |
16 import org.chromium.sync.AndroidSyncSettings.AndroidSyncSettingsObserver; | |
17 import org.chromium.sync.signin.AccountManagerHelper; | |
18 import org.chromium.sync.test.util.AccountHolder; | |
19 import org.chromium.sync.test.util.MockAccountManager; | |
20 import org.chromium.sync.test.util.MockSyncContentResolverDelegate; | |
21 | |
22 /** | |
23 * Tests for AndroidSyncSettings. | |
24 */ | |
25 @DisabledTest(message = "https://crbug.com/605567") | |
26 public class AndroidSyncSettingsTest extends InstrumentationTestCase { | |
27 | |
28 private static class CountingMockSyncContentResolverDelegate | |
29 extends MockSyncContentResolverDelegate { | |
30 private int mGetMasterSyncAutomaticallyCalls; | |
31 private int mGetSyncAutomaticallyCalls; | |
32 private int mGetIsSyncableCalls; | |
33 private int mSetIsSyncableCalls; | |
34 private int mSetSyncAutomaticallyCalls; | |
35 private int mRemovePeriodicSyncCalls; | |
36 | |
37 @Override | |
38 public boolean getMasterSyncAutomatically() { | |
39 mGetMasterSyncAutomaticallyCalls++; | |
40 return super.getMasterSyncAutomatically(); | |
41 } | |
42 | |
43 @Override | |
44 public boolean getSyncAutomatically(Account account, String authority) { | |
45 mGetSyncAutomaticallyCalls++; | |
46 return super.getSyncAutomatically(account, authority); | |
47 } | |
48 | |
49 @Override | |
50 public int getIsSyncable(Account account, String authority) { | |
51 mGetIsSyncableCalls++; | |
52 return super.getIsSyncable(account, authority); | |
53 } | |
54 | |
55 @Override | |
56 public void setIsSyncable(Account account, String authority, int syncabl
e) { | |
57 mSetIsSyncableCalls++; | |
58 super.setIsSyncable(account, authority, syncable); | |
59 } | |
60 | |
61 @Override | |
62 public void setSyncAutomatically(Account account, String authority, bool
ean sync) { | |
63 mSetSyncAutomaticallyCalls++; | |
64 super.setSyncAutomatically(account, authority, sync); | |
65 } | |
66 | |
67 @Override | |
68 public void removePeriodicSync(Account account, String authority, Bundle
extras) { | |
69 mRemovePeriodicSyncCalls++; | |
70 super.removePeriodicSync(account, authority, extras); | |
71 } | |
72 } | |
73 | |
74 private static class MockSyncSettingsObserver implements AndroidSyncSettings
Observer { | |
75 private boolean mReceivedNotification; | |
76 | |
77 public void clearNotification() { | |
78 mReceivedNotification = false; | |
79 } | |
80 | |
81 public boolean receivedNotification() { | |
82 return mReceivedNotification; | |
83 } | |
84 | |
85 @Override | |
86 public void androidSyncSettingsChanged() { | |
87 mReceivedNotification = true; | |
88 } | |
89 } | |
90 | |
91 private Context mContext; | |
92 private CountingMockSyncContentResolverDelegate mSyncContentResolverDelegate
; | |
93 private String mAuthority; | |
94 private Account mAccount; | |
95 private Account mAlternateAccount; | |
96 private MockSyncSettingsObserver mSyncSettingsObserver; | |
97 private MockAccountManager mAccountManager; | |
98 | |
99 @Override | |
100 protected void setUp() throws Exception { | |
101 mSyncContentResolverDelegate = new CountingMockSyncContentResolverDelega
te(); | |
102 mContext = getInstrumentation().getTargetContext(); | |
103 setupTestAccounts(mContext); | |
104 | |
105 AndroidSyncSettings.overrideForTests(mContext, mSyncContentResolverDeleg
ate); | |
106 mAuthority = AndroidSyncSettings.getContractAuthority(mContext); | |
107 AndroidSyncSettings.updateAccount(mContext, mAccount); | |
108 | |
109 mSyncSettingsObserver = new MockSyncSettingsObserver(); | |
110 AndroidSyncSettings.registerObserver(mContext, mSyncSettingsObserver); | |
111 | |
112 super.setUp(); | |
113 } | |
114 | |
115 private void setupTestAccounts(Context context) { | |
116 mAccountManager = new MockAccountManager(context, context); | |
117 AccountManagerHelper.overrideAccountManagerHelperForTests(context, mAcco
untManager); | |
118 mAccount = setupTestAccount("account@example.com"); | |
119 mAlternateAccount = setupTestAccount("alternate@example.com"); | |
120 } | |
121 | |
122 private Account setupTestAccount(String accountName) { | |
123 Account account = AccountManagerHelper.createAccountFromName(accountName
); | |
124 AccountHolder.Builder accountHolder = | |
125 AccountHolder.create().account(account).password("password").alw
aysAccept(true); | |
126 mAccountManager.addAccountHolderExplicitly(accountHolder.build()); | |
127 return account; | |
128 } | |
129 | |
130 private void enableChromeSyncOnUiThread() { | |
131 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
132 @Override | |
133 public void run() { | |
134 AndroidSyncSettings.enableChromeSync(mContext); | |
135 } | |
136 }); | |
137 } | |
138 | |
139 private void disableChromeSyncOnUiThread() { | |
140 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
141 @Override | |
142 public void run() { | |
143 AndroidSyncSettings.disableChromeSync(mContext); | |
144 } | |
145 }); | |
146 } | |
147 | |
148 @SmallTest | |
149 @Feature({"Sync"}) | |
150 public void testAccountInitialization() throws InterruptedException { | |
151 // mAccount was set to be syncable and not have periodic syncs. | |
152 assertEquals(1, mSyncContentResolverDelegate.mSetIsSyncableCalls); | |
153 assertEquals(1, mSyncContentResolverDelegate.mRemovePeriodicSyncCalls); | |
154 AndroidSyncSettings.updateAccount(mContext, null); | |
155 mAccountManager.waitForGetAccountsTask(); | |
156 // mAccount was set to be not syncable. | |
157 assertEquals(2, mSyncContentResolverDelegate.mSetIsSyncableCalls); | |
158 assertEquals(1, mSyncContentResolverDelegate.mRemovePeriodicSyncCalls); | |
159 AndroidSyncSettings.updateAccount(mContext, mAlternateAccount); | |
160 // mAlternateAccount was set to be syncable and not have periodic syncs. | |
161 assertEquals(3, mSyncContentResolverDelegate.mSetIsSyncableCalls); | |
162 assertEquals(2, mSyncContentResolverDelegate.mRemovePeriodicSyncCalls); | |
163 } | |
164 | |
165 @SmallTest | |
166 @Feature({"Sync"}) | |
167 public void testToggleMasterSyncFromSettings() throws InterruptedException { | |
168 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
169 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
170 assertTrue("master sync should be set", | |
171 AndroidSyncSettings.isMasterSyncEnabled(mContext)); | |
172 | |
173 mSyncContentResolverDelegate.setMasterSyncAutomatically(false); | |
174 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
175 assertFalse("master sync should be unset", | |
176 AndroidSyncSettings.isMasterSyncEnabled(mContext)); | |
177 } | |
178 | |
179 @SmallTest | |
180 @Feature({"Sync"}) | |
181 public void testToggleChromeSyncFromSettings() throws InterruptedException { | |
182 // Turn on syncability. | |
183 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
184 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
185 | |
186 // First sync | |
187 mSyncContentResolverDelegate.setIsSyncable(mAccount, mAuthority, 1); | |
188 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
189 mSyncContentResolverDelegate.setSyncAutomatically(mAccount, mAuthority,
true); | |
190 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
191 assertTrue("sync should be set", AndroidSyncSettings.isSyncEnabled(mCont
ext)); | |
192 assertTrue("sync should be set for chrome app", | |
193 AndroidSyncSettings.isChromeSyncEnabled(mContext)); | |
194 | |
195 // Disable sync automatically for the app | |
196 mSyncContentResolverDelegate.setSyncAutomatically(mAccount, mAuthority,
false); | |
197 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
198 assertFalse("sync should be unset", AndroidSyncSettings.isSyncEnabled(mC
ontext)); | |
199 assertFalse("sync should be unset for chrome app", | |
200 AndroidSyncSettings.isChromeSyncEnabled(mContext)); | |
201 | |
202 // Re-enable sync | |
203 mSyncContentResolverDelegate.setSyncAutomatically(mAccount, mAuthority,
true); | |
204 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
205 assertTrue("sync should be re-enabled", AndroidSyncSettings.isSyncEnable
d(mContext)); | |
206 assertTrue("sync should be set for chrome app", | |
207 AndroidSyncSettings.isChromeSyncEnabled(mContext)); | |
208 | |
209 // Disabled from master sync | |
210 mSyncContentResolverDelegate.setMasterSyncAutomatically(false); | |
211 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
212 assertFalse("sync should be disabled due to master sync", | |
213 AndroidSyncSettings.isSyncEnabled(mContext)); | |
214 assertFalse("master sync should be disabled", | |
215 AndroidSyncSettings.isMasterSyncEnabled(mContext)); | |
216 assertTrue("sync should be set for chrome app", | |
217 AndroidSyncSettings.isChromeSyncEnabled(mContext)); | |
218 } | |
219 | |
220 @SmallTest | |
221 @Feature({"Sync"}) | |
222 public void testToggleAccountSyncFromApplication() throws InterruptedExcepti
on { | |
223 // Turn on syncability. | |
224 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
225 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
226 | |
227 enableChromeSyncOnUiThread(); | |
228 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
229 assertTrue("account should be synced", AndroidSyncSettings.isSyncEnabled
(mContext)); | |
230 | |
231 disableChromeSyncOnUiThread(); | |
232 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
233 assertFalse("account should not be synced", AndroidSyncSettings.isSyncEn
abled(mContext)); | |
234 } | |
235 | |
236 @SmallTest | |
237 @Feature({"Sync"}) | |
238 public void testToggleSyncabilityForMultipleAccounts() throws InterruptedExc
eption { | |
239 // Turn on syncability. | |
240 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
241 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
242 | |
243 enableChromeSyncOnUiThread(); | |
244 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
245 assertTrue("account should be synced", AndroidSyncSettings.isSyncEnabled
(mContext)); | |
246 | |
247 AndroidSyncSettings.updateAccount(mContext, mAlternateAccount); | |
248 enableChromeSyncOnUiThread(); | |
249 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
250 assertTrue("alternate account should be synced", | |
251 AndroidSyncSettings.isSyncEnabled(mContext)); | |
252 | |
253 disableChromeSyncOnUiThread(); | |
254 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
255 assertFalse("alternate account should not be synced", | |
256 AndroidSyncSettings.isSyncEnabled(mContext)); | |
257 AndroidSyncSettings.updateAccount(mContext, mAccount); | |
258 assertTrue("account should still be synced", AndroidSyncSettings.isSyncE
nabled(mContext)); | |
259 | |
260 // Ensure we don't erroneously re-use cached data. | |
261 AndroidSyncSettings.updateAccount(mContext, null); | |
262 assertFalse("null account should not be synced", | |
263 AndroidSyncSettings.isSyncEnabled(mContext)); | |
264 } | |
265 | |
266 @SmallTest | |
267 @Feature({"Sync"}) | |
268 public void testSyncSettingsCaching() throws InterruptedException { | |
269 // Turn on syncability. | |
270 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
271 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
272 | |
273 enableChromeSyncOnUiThread(); | |
274 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
275 assertTrue("account should be synced", AndroidSyncSettings.isSyncEnabled
(mContext)); | |
276 | |
277 int masterSyncAutomaticallyCalls = | |
278 mSyncContentResolverDelegate.mGetMasterSyncAutomaticallyCalls; | |
279 int isSyncableCalls = mSyncContentResolverDelegate.mGetIsSyncableCalls; | |
280 int getSyncAutomaticallyAcalls = mSyncContentResolverDelegate.mGetSyncAu
tomaticallyCalls; | |
281 | |
282 // Do a bunch of reads. | |
283 AndroidSyncSettings.isMasterSyncEnabled(mContext); | |
284 AndroidSyncSettings.isSyncEnabled(mContext); | |
285 AndroidSyncSettings.isChromeSyncEnabled(mContext); | |
286 | |
287 // Ensure values were read from cache. | |
288 assertEquals(masterSyncAutomaticallyCalls, | |
289 mSyncContentResolverDelegate.mGetMasterSyncAutomaticallyCalls); | |
290 assertEquals(isSyncableCalls, mSyncContentResolverDelegate.mGetIsSyncabl
eCalls); | |
291 assertEquals(getSyncAutomaticallyAcalls, | |
292 mSyncContentResolverDelegate.mGetSyncAutomaticallyCalls); | |
293 | |
294 // Do a bunch of reads for alternate account. | |
295 AndroidSyncSettings.updateAccount(mContext, mAlternateAccount); | |
296 AndroidSyncSettings.isMasterSyncEnabled(mContext); | |
297 AndroidSyncSettings.isSyncEnabled(mContext); | |
298 AndroidSyncSettings.isChromeSyncEnabled(mContext); | |
299 | |
300 // Ensure settings were only fetched once. | |
301 assertEquals(masterSyncAutomaticallyCalls + 1, | |
302 mSyncContentResolverDelegate.mGetMasterSyncAutomaticallyCalls); | |
303 assertEquals(isSyncableCalls + 1, mSyncContentResolverDelegate.mGetIsSyn
cableCalls); | |
304 assertEquals(getSyncAutomaticallyAcalls + 1, | |
305 mSyncContentResolverDelegate.mGetSyncAutomaticallyCalls); | |
306 } | |
307 | |
308 @SmallTest | |
309 @Feature({"Sync"}) | |
310 public void testGetContractAuthority() throws Exception { | |
311 assertEquals("The contract authority should be the package name.", | |
312 getInstrumentation().getTargetContext().getPackageName(), | |
313 AndroidSyncSettings.getContractAuthority(mContext)); | |
314 } | |
315 | |
316 @SmallTest | |
317 @Feature({"Sync"}) | |
318 public void testAndroidSyncSettingsPostsNotifications() throws InterruptedEx
ception { | |
319 // Turn on syncability. | |
320 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
321 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
322 | |
323 mSyncSettingsObserver.clearNotification(); | |
324 AndroidSyncSettings.enableChromeSync(mContext); | |
325 assertTrue("enableChromeSync should trigger observers", | |
326 mSyncSettingsObserver.receivedNotification()); | |
327 | |
328 mSyncSettingsObserver.clearNotification(); | |
329 AndroidSyncSettings.updateAccount(mContext, mAlternateAccount); | |
330 assertTrue("switching to account with different settings should notify", | |
331 mSyncSettingsObserver.receivedNotification()); | |
332 | |
333 mSyncSettingsObserver.clearNotification(); | |
334 AndroidSyncSettings.updateAccount(mContext, mAccount); | |
335 assertTrue("switching to account with different settings should notify", | |
336 mSyncSettingsObserver.receivedNotification()); | |
337 | |
338 mSyncSettingsObserver.clearNotification(); | |
339 AndroidSyncSettings.enableChromeSync(mContext); | |
340 assertFalse("enableChromeSync shouldn't trigger observers", | |
341 mSyncSettingsObserver.receivedNotification()); | |
342 | |
343 mSyncSettingsObserver.clearNotification(); | |
344 AndroidSyncSettings.disableChromeSync(mContext); | |
345 assertTrue("disableChromeSync should trigger observers", | |
346 mSyncSettingsObserver.receivedNotification()); | |
347 | |
348 mSyncSettingsObserver.clearNotification(); | |
349 AndroidSyncSettings.disableChromeSync(mContext); | |
350 assertFalse("disableChromeSync shouldn't observers", | |
351 mSyncSettingsObserver.receivedNotification()); | |
352 } | |
353 | |
354 @SmallTest | |
355 @Feature({"Sync"}) | |
356 public void testIsSyncableOnSigninAndNotOnSignout() throws InterruptedExcept
ion { | |
357 assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthori
ty) == 1); | |
358 AndroidSyncSettings.updateAccount(mContext, null); | |
359 mAccountManager.waitForGetAccountsTask(); | |
360 assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthori
ty) == 0); | |
361 AndroidSyncSettings.updateAccount(mContext, mAccount); | |
362 assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthori
ty) == 1); | |
363 } | |
364 | |
365 /** | |
366 * Regression test for crbug.com/475299. | |
367 */ | |
368 @SmallTest | |
369 @Feature({"Sync"}) | |
370 public void testSyncableIsAlwaysSetWhenEnablingSync() throws InterruptedExce
ption { | |
371 // Setup bad state. | |
372 mSyncContentResolverDelegate.setMasterSyncAutomatically(true); | |
373 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
374 mSyncContentResolverDelegate.setIsSyncable(mAccount, mAuthority, 1); | |
375 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
376 mSyncContentResolverDelegate.setSyncAutomatically(mAccount, mAuthority,
true); | |
377 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
378 mSyncContentResolverDelegate.setIsSyncable(mAccount, mAuthority, 0); | |
379 mSyncContentResolverDelegate.waitForLastNotificationCompleted(); | |
380 assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthori
ty) == 0); | |
381 assertTrue(mSyncContentResolverDelegate.getSyncAutomatically(mAccount, m
Authority)); | |
382 | |
383 // Ensure bug is fixed. | |
384 AndroidSyncSettings.enableChromeSync(mContext); | |
385 assertTrue(mSyncContentResolverDelegate.getIsSyncable(mAccount, mAuthori
ty) == 1); | |
386 // Should still be enabled. | |
387 assertTrue(mSyncContentResolverDelegate.getSyncAutomatically(mAccount, m
Authority)); | |
388 } | |
389 } | |
OLD | NEW |