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

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

Powered by Google App Engine
This is Rietveld 408576698