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

Side by Side Diff: content/browser/background_sync/background_sync_manager.cc

Issue 950343006: [BackgroundSync] Initial land of the BackgroundSyncManager (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 9 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 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 #include "content/browser/background_sync/background_sync_manager.h"
6
7 #include "base/barrier_closure.h"
8 #include "base/bind.h"
9 #include "content/browser/background_sync/background_sync.pb.h"
10 #include "content/browser/service_worker/service_worker_cache_scheduler.h"
11 #include "content/browser/service_worker/service_worker_context_wrapper.h"
12 #include "content/browser/service_worker/service_worker_storage.h"
13 #include "content/public/browser/browser_thread.h"
14
15 namespace {
16 const char kBackgroundSyncUserDataKey[] = "BackgroundSyncUserData";
17 }
18
19 namespace content {
20
21 // static
22 scoped_ptr<BackgroundSyncManager> BackgroundSyncManager::Create(
23 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context) {
24 BackgroundSyncManager* sync_manager =
25 new BackgroundSyncManager(service_worker_context);
26 sync_manager->Init();
27 return make_scoped_ptr(sync_manager);
28 }
29
30 BackgroundSyncManager::~BackgroundSyncManager() {
31 }
32
33 void BackgroundSyncManager::Register(
34 const GURL& origin,
35 int64 sw_registration_id,
36 const BackgroundSyncRegistration& sync_registration,
37 const StatusAndRegistrationCallback& callback) {
38 DCHECK_CURRENTLY_ON(BrowserThread::IO);
39 DCHECK(initialized_ || initializing_);
40
41 StatusAndRegistrationCallback pending_callback =
42 base::Bind(&BackgroundSyncManager::PendingStatusAndRegistrationCallback,
43 weak_ptr_factory_.GetWeakPtr(), callback);
44
45 op_scheduler_->ScheduleOperation(base::Bind(
46 &BackgroundSyncManager::RegisterImpl, weak_ptr_factory_.GetWeakPtr(),
47 origin, sw_registration_id, sync_registration, pending_callback));
48 }
49
50 void BackgroundSyncManager::Unregister(
51 const GURL& origin,
52 int64 sw_registration_id,
53 const BackgroundSyncRegistration& sync_registration,
54 const StatusCallback& callback) {
55 DCHECK_CURRENTLY_ON(BrowserThread::IO);
56 DCHECK(initialized_ || initializing_);
57
58 StatusCallback pending_callback =
59 base::Bind(&BackgroundSyncManager::PendingStatusCallback,
60 weak_ptr_factory_.GetWeakPtr(), callback);
61
62 op_scheduler_->ScheduleOperation(base::Bind(
63 &BackgroundSyncManager::UnregisterImpl, weak_ptr_factory_.GetWeakPtr(),
64 origin, sw_registration_id, sync_registration, pending_callback));
65 }
66
67 void BackgroundSyncManager::GetRegistration(
68 const GURL& origin,
69 int64 sw_registration_id,
70 const std::string sync_registration_id,
71 const StatusAndRegistrationCallback& callback) {
72 DCHECK_CURRENTLY_ON(BrowserThread::IO);
73 DCHECK(initialized_ || initializing_);
74
75 StatusAndRegistrationCallback pending_callback =
76 base::Bind(&BackgroundSyncManager::PendingStatusAndRegistrationCallback,
77 weak_ptr_factory_.GetWeakPtr(), callback);
78
79 op_scheduler_->ScheduleOperation(
80 base::Bind(&BackgroundSyncManager::GetRegistrationImpl,
81 weak_ptr_factory_.GetWeakPtr(), origin, sw_registration_id,
82 sync_registration_id, pending_callback));
83 }
84
85 BackgroundSyncManager::BackgroundSyncManager(
86 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
87 : initialized_(false),
88 initializing_(false),
89 registration_map_(new IdToRegistrationMap()),
90 op_scheduler_(new ServiceWorkerCacheScheduler()),
91 service_worker_context_(service_worker_context),
92 weak_ptr_factory_(this) {
93 }
94
95 void BackgroundSyncManager::Init() {
96 DCHECK_CURRENTLY_ON(BrowserThread::IO);
97 DCHECK(!initialized_ && !initializing_);
98 DCHECK(op_scheduler_->Empty());
99
100 initializing_ = true;
101 op_scheduler_->ScheduleOperation(base::Bind(&BackgroundSyncManager::InitImpl,
102 weak_ptr_factory_.GetWeakPtr()));
103 }
104
105 void BackgroundSyncManager::InitImpl() {
106 DCHECK_CURRENTLY_ON(BrowserThread::IO);
107 DCHECK(!initialized_);
108 DCHECK(initializing_);
109
110 service_worker_context_->context()->storage()->GetUserDataForAllRegistrations(
111 kBackgroundSyncUserDataKey,
112 base::Bind(&BackgroundSyncManager::InitDidGetUserData,
113 weak_ptr_factory_.GetWeakPtr()));
114 }
115
116 void BackgroundSyncManager::InitDidGetUserData(
117 const std::vector<std::pair<int64, std::string>>& user_data,
118 ServiceWorkerStatusCode status) {
119 for (const std::pair<int64, std::string>& data : user_data) {
120 BackgroundSyncRegistrationsProto registrations_proto;
121 if (registrations_proto.ParseFromString(data.second)) {
122 for (int i = 0, max = registrations_proto.registration_size(); i < max;
123 ++i) {
124 const BackgroundSyncRegistrationProto& registration_proto =
125 registrations_proto.registration(i);
126 (*registration_map_)[data.first].push_back(
127 BackgroundSyncRegistration(registration_proto.id()));
128 }
129 }
130 }
131
132 initializing_ = false;
133 initialized_ = true;
134
135 // TODO(jkarlin): Call the scheduling algorithm here.
136
137 op_scheduler_->CompleteOperationAndRunNext();
138 }
139
140 void BackgroundSyncManager::RegisterImpl(
141 const GURL& origin,
142 int64 sw_registration_id,
143 const BackgroundSyncRegistration& sync_registration,
144 const StatusAndRegistrationCallback& callback) {
145 // TODO(jkarlin): Check for permission.
davidben 2015/03/13 22:05:43 (Seems an important thing to do. :-P)
jkarlin 2015/03/14 01:17:27 Yes, though we're protected by (two) command line
146
147 if (!AddRegistrationToMap(sw_registration_id, sync_registration)) {
148 callback.Run(ErrorTypeExists, BackgroundSyncRegistration(""));
davidben 2015/03/13 22:05:43 Between this and everyone futher up the stack, it
jkarlin 2015/03/14 01:17:27 RunSoon is a good idea, done.
149 return;
150 }
151
152 StoreRegistrations(
153 origin, sw_registration_id,
154 base::Bind(&BackgroundSyncManager::RegisterDidStore,
155 weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
156 sync_registration, callback));
157 }
158
159 bool BackgroundSyncManager::HasRegistration(
160 int64 sw_registration_id,
161 const BackgroundSyncRegistration& sync_registration) {
162 IdToRegistrationMap::iterator it =
163 registration_map_->find(sw_registration_id);
164 if (it == registration_map_->end())
165 return false;
166
167 for (const BackgroundSyncRegistration& reg : it->second) {
168 if (sync_registration.id == reg.id)
169 return true;
170 }
171 return false;
172 }
173
174 void BackgroundSyncManager::StoreRegistrations(
175 const GURL& origin,
176 int64 sw_registration_id,
177 const ServiceWorkerStorage::StatusCallback& callback) {
178 // Serialize the data.
179 BackgroundSyncRegistrationsProto registrations_proto;
180 for (const BackgroundSyncRegistration& sync_registration :
181 (*registration_map_)[sw_registration_id]) {
182 BackgroundSyncRegistrationProto* registration_proto =
183 registrations_proto.add_registration();
184 registration_proto->set_id(sync_registration.id);
185 }
davidben 2015/03/13 22:05:43 Writing N registrations takes O(N^2). Is this a pr
jkarlin 2015/03/14 01:17:27 The thought is that the lists will be small. In w
186 std::string serialized;
187 bool success = registrations_proto.SerializeToString(&serialized);
188 DCHECK(success);
189
190 // Store it.
191 service_worker_context_->context()->storage()->StoreUserData(
192 sw_registration_id, origin, kBackgroundSyncUserDataKey, serialized,
193 callback);
194 }
195
196 void BackgroundSyncManager::RegisterDidStore(
197 int64 sw_registration_id,
198 const BackgroundSyncRegistration& sync_registration,
199 const StatusAndRegistrationCallback& callback,
200 ServiceWorkerStatusCode status) {
201 if (status != SERVICE_WORKER_OK) {
202 // Restore the previous state.
203 RemoveRegistrationFromMap(sw_registration_id, sync_registration);
204 callback.Run(ErrorTypeStorage, BackgroundSyncRegistration());
205 return;
206 }
207 // TODO(jkarlin): Run the registration algorithm.
208 callback.Run(ErrorTypeOK, sync_registration);
209 }
210
211 bool BackgroundSyncManager::RemoveRegistrationFromMap(
212 int64 sw_registration_id,
213 const BackgroundSyncRegistration& sync_registration) {
214 IdToRegistrationMap::iterator it =
215 registration_map_->find(sw_registration_id);
216
217 if (it == registration_map_->end())
218 return false;
219
220 std::list<BackgroundSyncRegistration>* registrations = &(it->second);
221 for (std::list<BackgroundSyncRegistration>::iterator reg_iter =
222 registrations->begin();
223 reg_iter != registrations->end(); ++reg_iter) {
224 if (reg_iter->id == sync_registration.id) {
225 registrations->erase(reg_iter);
226 return true;
227 }
228 }
229
230 return false;
231 }
232
233 bool BackgroundSyncManager::AddRegistrationToMap(
234 int64 sw_registration_id,
235 const BackgroundSyncRegistration& sync_registration) {
236 if (HasRegistration(sw_registration_id, sync_registration))
237 return false;
238
239 (*registration_map_)[sw_registration_id].push_back(sync_registration);
240 return true;
241 }
242
243 void BackgroundSyncManager::UnregisterImpl(
244 const GURL& origin,
245 int64 sw_registration_id,
246 const BackgroundSyncRegistration& sync_registration,
247 const StatusCallback& callback) {
248 if (!RemoveRegistrationFromMap(sw_registration_id, sync_registration)) {
249 callback.Run(ErrorTypeNotFound);
250 return;
251 }
252
253 StoreRegistrations(
254 origin, sw_registration_id,
255 base::Bind(&BackgroundSyncManager::UnregisterDidStore,
256 weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
257 sync_registration, callback));
258 }
259
260 void BackgroundSyncManager::UnregisterDidStore(
261 int64 sw_registration_id,
262 const BackgroundSyncRegistration& sync_registration,
263 const StatusCallback& callback,
264 ServiceWorkerStatusCode status) {
265 if (status != SERVICE_WORKER_OK) {
266 // Restore the previous state.
267 AddRegistrationToMap(sw_registration_id, sync_registration);
268 callback.Run(ErrorTypeStorage);
269 return;
270 }
271
272 // TODO(jkarlin): Run the registration algorithm.
273 callback.Run(ErrorTypeOK);
274 }
275
276 void BackgroundSyncManager::GetRegistrationImpl(
277 const GURL& origin,
278 int64 sw_registration_id,
279 const std::string sync_registration_id,
280 const StatusAndRegistrationCallback& callback) {
281 IdToRegistrationMap::iterator it =
282 registration_map_->find(sw_registration_id);
283
284 if (it == registration_map_->end()) {
285 callback.Run(ErrorTypeNotFound, BackgroundSyncRegistration());
286 return;
287 }
288
289 std::list<BackgroundSyncRegistration>* registrations = &(it->second);
290 for (std::list<BackgroundSyncRegistration>::iterator reg_iter =
291 registrations->begin();
292 reg_iter != registrations->end(); ++reg_iter) {
davidben 2015/03/13 22:05:43 for-each loop?
jkarlin 2015/03/14 01:17:27 Done.
293 if (reg_iter->id == sync_registration_id) {
294 callback.Run(ErrorTypeOK, *reg_iter);
295 return;
296 }
297 }
298
299 callback.Run(ErrorTypeNotFound, BackgroundSyncRegistration());
300 }
301
302 void BackgroundSyncManager::PendingStatusAndRegistrationCallback(
303 const StatusAndRegistrationCallback& callback,
304 ErrorType error,
305 const BackgroundSyncRegistration& sync_registration) {
306 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
davidben 2015/03/13 22:05:43 Worth a comment explaining what's going on here? (
jkarlin 2015/03/14 01:17:27 Added comments. The callback is from outside of th
307 callback.Run(error, sync_registration);
308 if (manager)
309 op_scheduler_->CompleteOperationAndRunNext();
310 }
311
312 void BackgroundSyncManager::PendingStatusCallback(
313 const StatusCallback& callback,
314 ErrorType error) {
315 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
316 callback.Run(error);
317 if (manager)
318 op_scheduler_->CompleteOperationAndRunNext();
319 }
320
321 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698