OLD | NEW |
---|---|
(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 | |
OLD | NEW |