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

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

Powered by Google App Engine
This is Rietveld 408576698