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

Side by Side Diff: sync/test/android/javatests/src/org/chromium/sync/test/util/MockSyncContentResolverDelegate.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
OLDNEW
(Empty)
1 // Copyright 2013 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.test.util;
6
7
8 import android.accounts.Account;
9 import android.content.ContentResolver;
10 import android.content.SyncStatusObserver;
11 import android.os.AsyncTask;
12 import android.os.Bundle;
13
14 import junit.framework.Assert;
15
16 import org.chromium.base.ThreadUtils;
17 import org.chromium.base.VisibleForTesting;
18 import org.chromium.sync.SyncContentResolverDelegate;
19
20 import java.util.HashMap;
21 import java.util.HashSet;
22 import java.util.Map;
23 import java.util.Set;
24 import java.util.concurrent.Semaphore;
25 import java.util.concurrent.TimeUnit;
26
27
28 /**
29 * Mock implementation of the {@link SyncContentResolverDelegate}.
30 *
31 * This implementation only supports status change listeners for the type
32 * SYNC_OBSERVER_TYPE_SETTINGS.
33 */
34 public class MockSyncContentResolverDelegate implements SyncContentResolverDeleg ate {
35
36 private final Set<String> mSyncAutomaticallySet;
37 private final Map<String, Boolean> mIsSyncableMap;
38 private final Object mSyncableMapLock = new Object();
39
40 private final Set<AsyncSyncStatusObserver> mObservers;
41
42 private boolean mMasterSyncAutomatically;
43 private boolean mDisableObserverNotifications;
44
45 private Semaphore mPendingObserverCount;
46
47 public MockSyncContentResolverDelegate() {
48 mSyncAutomaticallySet = new HashSet<String>();
49 mIsSyncableMap = new HashMap<String, Boolean>();
50 mObservers = new HashSet<AsyncSyncStatusObserver>();
51 }
52
53 @Override
54 public Object addStatusChangeListener(int mask, SyncStatusObserver callback) {
55 if (mask != ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS) {
56 throw new IllegalArgumentException("This implementation only support s "
57 + "ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS as the mask") ;
58 }
59 AsyncSyncStatusObserver asyncSyncStatusObserver = new AsyncSyncStatusObs erver(callback);
60 synchronized (mObservers) {
61 mObservers.add(asyncSyncStatusObserver);
62 }
63 return asyncSyncStatusObserver;
64 }
65
66 @Override
67 public void removeStatusChangeListener(Object handle) {
68 synchronized (mObservers) {
69 mObservers.remove(handle);
70 }
71 }
72
73 @Override
74 @VisibleForTesting
75 public void setMasterSyncAutomatically(boolean sync) {
76 if (mMasterSyncAutomatically == sync) return;
77
78 mMasterSyncAutomatically = sync;
79 notifyObservers();
80 }
81
82 @Override
83 public boolean getMasterSyncAutomatically() {
84 return mMasterSyncAutomatically;
85 }
86
87 @Override
88 public boolean getSyncAutomatically(Account account, String authority) {
89 String key = createKey(account, authority);
90 synchronized (mSyncableMapLock) {
91 return mSyncAutomaticallySet.contains(key);
92 }
93 }
94
95 @Override
96 public void setSyncAutomatically(Account account, String authority, boolean sync) {
97 String key = createKey(account, authority);
98 synchronized (mSyncableMapLock) {
99 if (!mIsSyncableMap.containsKey(key) || !mIsSyncableMap.get(key)) {
100 throw new IllegalArgumentException("Account " + account
101 + " is not syncable for authority " + authority
102 + ". Can not set sync state to " + sync);
103 }
104 if (sync) {
105 mSyncAutomaticallySet.add(key);
106 } else if (mSyncAutomaticallySet.contains(key)) {
107 mSyncAutomaticallySet.remove(key);
108 }
109 }
110 notifyObservers();
111 }
112
113 @Override
114 public void setIsSyncable(Account account, String authority, int syncable) {
115 String key = createKey(account, authority);
116
117 synchronized (mSyncableMapLock) {
118 switch (syncable) {
119 case 0:
120 mIsSyncableMap.put(key, false);
121 break;
122 case 1:
123 mIsSyncableMap.put(key, true);
124 break;
125 case -1:
126 if (mIsSyncableMap.containsKey(key)) {
127 mIsSyncableMap.remove(key);
128 }
129 break;
130 default:
131 throw new IllegalArgumentException("Unable to understand syn cable argument: "
132 + syncable);
133 }
134 }
135 notifyObservers();
136 }
137
138 @Override
139 public int getIsSyncable(Account account, String authority) {
140 String key = createKey(account, authority);
141 synchronized (mSyncableMapLock) {
142 if (mIsSyncableMap.containsKey(key)) {
143 return mIsSyncableMap.get(key) ? 1 : 0;
144 } else {
145 return -1;
146 }
147 }
148 }
149
150 @Override
151 public void removePeriodicSync(Account account, String authority, Bundle ext ras) {
152 }
153
154 private static String createKey(Account account, String authority) {
155 return account.name + "@@@" + account.type + "@@@" + authority;
156 }
157
158 private void notifyObservers() {
159 if (mDisableObserverNotifications) return;
160 synchronized (mObservers) {
161 mPendingObserverCount = new Semaphore(1 - mObservers.size());
162 for (AsyncSyncStatusObserver observer : mObservers) {
163 observer.notifyObserverAsync(mPendingObserverCount);
164 }
165 }
166 }
167
168 /**
169 * Blocks until the last notification has been issued to all registered obse rvers.
170 * Note that if an observer is removed while a notification is being handled this can
171 * fail to return correctly.
172 *
173 * @throws InterruptedException
174 */
175 @VisibleForTesting
176 public void waitForLastNotificationCompleted() throws InterruptedException {
177 Assert.assertTrue("Timed out waiting for notifications to complete.",
178 mPendingObserverCount.tryAcquire(5, TimeUnit.SECONDS));
179 }
180
181 public void disableObserverNotifications() {
182 mDisableObserverNotifications = true;
183 }
184
185 /**
186 * Simulate an account rename, which copies settings to the new account.
187 */
188 public void renameAccounts(Account oldAccount, Account newAccount, String au thority) {
189 int oldIsSyncable = getIsSyncable(oldAccount, authority);
190 setIsSyncable(newAccount, authority, oldIsSyncable);
191 if (oldIsSyncable == 1) {
192 setSyncAutomatically(
193 newAccount, authority, getSyncAutomatically(oldAccount, auth ority));
194 }
195 }
196
197 private static class AsyncSyncStatusObserver {
198
199 private final SyncStatusObserver mSyncStatusObserver;
200
201 private AsyncSyncStatusObserver(SyncStatusObserver syncStatusObserver) {
202 mSyncStatusObserver = syncStatusObserver;
203 }
204
205 private void notifyObserverAsync(final Semaphore pendingObserverCount) {
206 if (ThreadUtils.runningOnUiThread()) {
207 new AsyncTask<Void, Void, Void>() {
208 @Override
209 protected Void doInBackground(Void... params) {
210 mSyncStatusObserver.onStatusChanged(
211 ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
212 return null;
213 }
214
215 @Override
216 protected void onPostExecute(Void result) {
217 pendingObserverCount.release();
218 }
219 }.execute();
220 } else {
221 mSyncStatusObserver.onStatusChanged(
222 ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS);
223 pendingObserverCount.release();
224 }
225 }
226 }
227 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698