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

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: Cleanup 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 "base/strings/utf_string_conversions.h"
10 #include "content/browser/background_sync/background_sync.pb.h"
11 #include "content/browser/service_worker/service_worker_cache_scheduler.h"
12 #include "content/browser/service_worker/service_worker_context_wrapper.h"
13 #include "content/browser/service_worker/service_worker_storage.h"
14 #include "content/public/browser/browser_thread.h"
15
16 namespace {
17 const char kBackgroundSyncUserDataKey[] = "BackgroundSyncUserData";
18 }
19
20 namespace content {
21
22 // static
23 scoped_ptr<BackgroundSyncManager> BackgroundSyncManager::Create(
24 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context) {
25 BackgroundSyncManager* sync_manager =
26 new BackgroundSyncManager(service_worker_context);
27 sync_manager->Init();
28 return make_scoped_ptr(sync_manager);
29 }
30
31 BackgroundSyncManager::~BackgroundSyncManager() {
32 }
33
34 void BackgroundSyncManager::Register(
35 const GURL& origin,
36 int64 sw_registration_id,
37 const BackgroundSyncRegistration& sync_registration,
38 const StatusAndRegistrationCallback& callback) {
39 DCHECK_CURRENTLY_ON(BrowserThread::IO);
40 DCHECK(initialized_ || initializing_);
41
42 StatusAndRegistrationCallback pending_callback =
43 base::Bind(&BackgroundSyncManager::PendingStatusAndRegistrationCallback,
44 weak_ptr_factory_.GetWeakPtr(), callback);
45
46 op_scheduler_->ScheduleOperation(base::Bind(
47 &BackgroundSyncManager::RegisterImpl, weak_ptr_factory_.GetWeakPtr(),
48 origin, sw_registration_id, sync_registration, pending_callback));
49 }
50
51 void BackgroundSyncManager::Unregister(
52 const GURL& origin,
53 int64 sw_registration_id,
54 const BackgroundSyncRegistration& sync_registration,
55 const StatusCallback& callback) {
56 DCHECK_CURRENTLY_ON(BrowserThread::IO);
57 DCHECK(initialized_ || initializing_);
58
59 StatusCallback pending_callback =
60 base::Bind(&BackgroundSyncManager::PendingStatusCallback,
61 weak_ptr_factory_.GetWeakPtr(), callback);
62
63 op_scheduler_->ScheduleOperation(base::Bind(
64 &BackgroundSyncManager::UnregisterImpl, weak_ptr_factory_.GetWeakPtr(),
65 origin, sw_registration_id, sync_registration, pending_callback));
66 }
67
68 void BackgroundSyncManager::GetRegistration(
69 const GURL& origin,
70 int64 sw_registration_id,
71 const base::string16 sync_registration_id,
72 const StatusAndRegistrationCallback& callback) {
73 DCHECK_CURRENTLY_ON(BrowserThread::IO);
74 DCHECK(initialized_ || initializing_);
75
76 StatusAndRegistrationCallback pending_callback =
77 base::Bind(&BackgroundSyncManager::PendingStatusAndRegistrationCallback,
78 weak_ptr_factory_.GetWeakPtr(), callback);
79
80 op_scheduler_->ScheduleOperation(
81 base::Bind(&BackgroundSyncManager::GetRegistrationImpl,
82 weak_ptr_factory_.GetWeakPtr(), origin, sw_registration_id,
83 sync_registration_id, pending_callback));
84 }
85
86 BackgroundSyncManager::BackgroundSyncManager(
87 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
88 : initialized_(false),
89 initializing_(false),
90 registration_map_(new IdToRegistrationMap()),
91 op_scheduler_(new ServiceWorkerCacheScheduler()),
92 service_worker_context_(service_worker_context),
93 weak_ptr_factory_(this) {
94 }
95
96 void BackgroundSyncManager::Init() {
97 DCHECK_CURRENTLY_ON(BrowserThread::IO);
98 DCHECK(!initialized_ && !initializing_);
99 DCHECK(op_scheduler_->Empty());
100
101 initializing_ = true;
102 op_scheduler_->ScheduleOperation(base::Bind(&BackgroundSyncManager::InitImpl,
103 weak_ptr_factory_.GetWeakPtr()));
104 }
105
106 void BackgroundSyncManager::InitImpl() {
107 DCHECK_CURRENTLY_ON(BrowserThread::IO);
108 DCHECK(!initialized_);
109 DCHECK(initializing_);
110
111 service_worker_context_->context()->storage()->GetUserDataForAllRegistrations(
112 kBackgroundSyncUserDataKey,
113 base::Bind(&BackgroundSyncManager::InitDidGetUserData,
114 weak_ptr_factory_.GetWeakPtr()));
115 }
116
117 void BackgroundSyncManager::InitDidGetUserData(
118 const std::vector<std::pair<int64, std::string>>& user_data,
119 ServiceWorkerStatusCode status) {
120 for (const std::pair<int64, std::string>& data : user_data) {
121 BackgroundSyncRegistrationsProto registrations_proto;
122 if (registrations_proto.ParseFromString(data.second)) {
123 for (int i = 0, max = registrations_proto.registration_size(); i < max;
124 ++i) {
125 const BackgroundSyncRegistrationProto& registration_proto =
126 registrations_proto.registration(i);
127 base::string16 id = base::UTF8ToUTF16(registration_proto.id());
128 (*registration_map_)[data.first].push_back(
129 BackgroundSyncRegistration(id));
130 }
131 }
132 }
133
134 initializing_ = false;
135 initialized_ = true;
136
137 // TODO(jkarlin): Call the scheduling algorithm here.
138
139 op_scheduler_->CompleteOperationAndRunNext();
140 }
141
142 void BackgroundSyncManager::RegisterImpl(
143 const GURL& origin,
144 int64 sw_registration_id,
145 const BackgroundSyncRegistration& sync_registration,
146 const StatusAndRegistrationCallback& callback) {
147 // TODO(jkarlin): Check for permission.
148
149 if (!AddRegistrationToMap(sw_registration_id, sync_registration)) {
150 callback.Run(ErrorTypeExists, BackgroundSyncRegistration(base::string16()));
151 return;
152 }
153
154 StoreRegistrations(
155 origin, sw_registration_id,
156 base::Bind(&BackgroundSyncManager::RegisterDidStore,
157 weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
158 sync_registration, callback));
159 }
160
161 bool BackgroundSyncManager::HasRegistration(
162 int64 sw_registration_id,
163 const BackgroundSyncRegistration& sync_registration) {
164 IdToRegistrationMap::iterator it =
165 registration_map_->find(sw_registration_id);
166 if (it == registration_map_->end())
167 return false;
168
169 for (const BackgroundSyncRegistration& reg : it->second) {
michaeln 2015/02/27 02:56:30 thnx for not using const auto everywhere (or anywh
jkarlin 2015/02/27 16:30:38 I'm so not a fan of auto..
170 if (sync_registration.id == reg.id)
171 return true;
172 }
173 return false;
174 }
175
176 void BackgroundSyncManager::StoreRegistrations(
177 const GURL& origin,
178 int64 sw_registration_id,
179 const ServiceWorkerStorage::StatusCallback& callback) {
180 // Serialize the data.
181 BackgroundSyncRegistrationsProto registrations_proto;
182 for (const BackgroundSyncRegistration& sync_registration :
183 (*registration_map_)[sw_registration_id]) {
184 BackgroundSyncRegistrationProto* registration_proto =
185 registrations_proto.add_registration();
186 // TODO(jkarlin): This UTF conversion is incompatible with DOMString, we
michaeln 2015/02/27 02:56:30 would it be reasonable for the spec to constrain i
jkarlin 2015/02/27 16:30:38 I've brought this up before. I'd much prefer utf8.
jkarlin 2015/03/02 14:41:03 Sticking with DOMString but WebString::utf8() will
187 // should store the string16 without conversion.
188 registration_proto->set_id(base::UTF16ToUTF8(sync_registration.id));
189 }
190 std::string serialized;
191 bool success = registrations_proto.SerializeToString(&serialized);
192 DCHECK(success);
193
194 // Store it.
195 service_worker_context_->context()->storage()->StoreUserData(
196 sw_registration_id, origin, kBackgroundSyncUserDataKey, serialized,
197 callback);
198 }
199
200 void BackgroundSyncManager::RegisterDidStore(
201 int64 sw_registration_id,
202 const BackgroundSyncRegistration& sync_registration,
203 const StatusAndRegistrationCallback& callback,
204 ServiceWorkerStatusCode status) {
205 if (status != SERVICE_WORKER_OK) {
206 // Restore the previous state.
207 RemoveRegistrationFromMap(sw_registration_id, sync_registration);
208 callback.Run(ErrorTypeStorage, BackgroundSyncRegistration());
209 return;
210 }
211 // TODO(jkarlin): Run the registration algorithm.
212 callback.Run(ErrorTypeOK, sync_registration);
213 }
214
215 bool BackgroundSyncManager::RemoveRegistrationFromMap(
216 int64 sw_registration_id,
217 const BackgroundSyncRegistration& sync_registration) {
218 IdToRegistrationMap::iterator it =
219 registration_map_->find(sw_registration_id);
220
221 if (it == registration_map_->end())
222 return false;
223
224 std::list<BackgroundSyncRegistration>* registrations = &(it->second);
225 for (std::list<BackgroundSyncRegistration>::iterator reg_iter =
226 registrations->begin();
227 reg_iter != registrations->end(); ++reg_iter) {
michaeln 2015/02/27 02:56:30 does a fancy for (const BackgroundSyncRegistration
jkarlin 2015/02/27 16:30:38 The foreach loop doesn't work because I need an it
michaeln 2015/02/28 00:34:23 awwww, no love for lambdas :)
228 if (reg_iter->id == sync_registration.id) {
229 registrations->erase(reg_iter);
230 return true;
231 }
232 }
233
234 return false;
235 }
236
237 bool BackgroundSyncManager::AddRegistrationToMap(
238 int64 sw_registration_id,
239 const BackgroundSyncRegistration& sync_registration) {
240 if (HasRegistration(sw_registration_id, sync_registration))
241 return false;
242
243 (*registration_map_)[sw_registration_id].push_back(sync_registration);
244 return true;
245 }
246
247 void BackgroundSyncManager::UnregisterImpl(
248 const GURL& origin,
249 int64 sw_registration_id,
250 const BackgroundSyncRegistration& sync_registration,
251 const StatusCallback& callback) {
252 if (!RemoveRegistrationFromMap(sw_registration_id, sync_registration)) {
253 callback.Run(ErrorTypeNotFound);
254 return;
255 }
256
257 StoreRegistrations(
258 origin, sw_registration_id,
259 base::Bind(&BackgroundSyncManager::UnregisterDidStore,
260 weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
261 sync_registration, callback));
262 }
263
264 void BackgroundSyncManager::UnregisterDidStore(
265 int64 sw_registration_id,
266 const BackgroundSyncRegistration& sync_registration,
267 const StatusCallback& callback,
268 ServiceWorkerStatusCode status) {
269 if (status != SERVICE_WORKER_OK) {
270 // Restore the previous state.
271 AddRegistrationToMap(sw_registration_id, sync_registration);
272 callback.Run(ErrorTypeStorage);
273 return;
274 }
275
276 // TODO(jkarlin): Run the registration algorithm.
277 callback.Run(ErrorTypeOK);
278 }
279
280 void BackgroundSyncManager::GetRegistrationImpl(
281 const GURL& origin,
282 int64 sw_registration_id,
283 const base::string16 sync_registration_id,
284 const StatusAndRegistrationCallback& callback) {
285 IdToRegistrationMap::iterator it =
286 registration_map_->find(sw_registration_id);
287
288 if (it == registration_map_->end()) {
289 callback.Run(ErrorTypeNotFound, BackgroundSyncRegistration());
290 return;
291 }
292
293 std::list<BackgroundSyncRegistration>* registrations = &(it->second);
294 for (std::list<BackgroundSyncRegistration>::iterator reg_iter =
295 registrations->begin();
296 reg_iter != registrations->end(); ++reg_iter) {
297 if (reg_iter->id == sync_registration_id) {
298 callback.Run(ErrorTypeOK, *reg_iter);
299 return;
300 }
301 }
302
303 callback.Run(ErrorTypeNotFound, BackgroundSyncRegistration());
304 }
305
306 void BackgroundSyncManager::PendingStatusAndRegistrationCallback(
307 const StatusAndRegistrationCallback& callback,
308 ErrorType error,
309 const BackgroundSyncRegistration& sync_registration) {
310 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
311 callback.Run(error, sync_registration);
312 if (manager)
313 op_scheduler_->CompleteOperationAndRunNext();
314 }
315
316 void BackgroundSyncManager::PendingStatusCallback(
317 const StatusCallback& callback,
318 ErrorType error) {
319 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
320 callback.Run(error);
321 if (manager)
322 op_scheduler_->CompleteOperationAndRunNext();
323 }
324
325 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698