Refactors gesture conversion functions to ui/events/blink
[chromium-blink-merge.git] / content / browser / background_sync / background_sync_manager.cc
blob7ea194f1af92dd463d56a59fbc1527c99842d81f
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.
5 #include "content/browser/background_sync/background_sync_manager.h"
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"
14 namespace {
15 const char kBackgroundSyncUserDataKey[] = "BackgroundSyncUserData";
18 namespace content {
20 const BackgroundSyncManager::BackgroundSyncRegistration::RegistrationId
21 BackgroundSyncManager::BackgroundSyncRegistration::kInvalidRegistrationId =
22 -1;
24 const BackgroundSyncManager::BackgroundSyncRegistration::RegistrationId
25 BackgroundSyncManager::BackgroundSyncRegistrations::kInitialId = 0;
27 BackgroundSyncManager::BackgroundSyncRegistrations::
28 BackgroundSyncRegistrations()
29 : next_id(kInitialId) {
31 BackgroundSyncManager::BackgroundSyncRegistrations::BackgroundSyncRegistrations(
32 BackgroundSyncRegistration::RegistrationId next_id)
33 : next_id(next_id) {
35 BackgroundSyncManager::BackgroundSyncRegistrations::
36 ~BackgroundSyncRegistrations() {
39 // static
40 scoped_ptr<BackgroundSyncManager> BackgroundSyncManager::Create(
41 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context) {
42 BackgroundSyncManager* sync_manager =
43 new BackgroundSyncManager(service_worker_context);
44 sync_manager->Init();
45 return make_scoped_ptr(sync_manager);
48 BackgroundSyncManager::~BackgroundSyncManager() {
51 void BackgroundSyncManager::Register(
52 const GURL& origin,
53 int64 sw_registration_id,
54 const BackgroundSyncRegistration& sync_registration,
55 const StatusAndRegistrationCallback& callback) {
56 DCHECK_CURRENTLY_ON(BrowserThread::IO);
57 DCHECK_EQ(BackgroundSyncRegistration::kInvalidRegistrationId,
58 sync_registration.id);
60 StatusAndRegistrationCallback pending_callback =
61 base::Bind(&BackgroundSyncManager::PendingStatusAndRegistrationCallback,
62 weak_ptr_factory_.GetWeakPtr(), callback);
64 op_scheduler_.ScheduleOperation(base::Bind(
65 &BackgroundSyncManager::RegisterImpl, weak_ptr_factory_.GetWeakPtr(),
66 origin, sw_registration_id, sync_registration, pending_callback));
69 void BackgroundSyncManager::Unregister(
70 const GURL& origin,
71 int64 sw_registration_id,
72 const std::string& sync_registration_name,
73 BackgroundSyncRegistration::RegistrationId sync_registration_id,
74 const StatusCallback& callback) {
75 DCHECK_CURRENTLY_ON(BrowserThread::IO);
77 StatusCallback pending_callback =
78 base::Bind(&BackgroundSyncManager::PendingStatusCallback,
79 weak_ptr_factory_.GetWeakPtr(), callback);
81 op_scheduler_.ScheduleOperation(base::Bind(
82 &BackgroundSyncManager::UnregisterImpl, weak_ptr_factory_.GetWeakPtr(),
83 origin, sw_registration_id, sync_registration_name, sync_registration_id,
84 pending_callback));
87 void BackgroundSyncManager::GetRegistration(
88 const GURL& origin,
89 int64 sw_registration_id,
90 const std::string sync_registration_name,
91 const StatusAndRegistrationCallback& callback) {
92 DCHECK_CURRENTLY_ON(BrowserThread::IO);
94 StatusAndRegistrationCallback pending_callback =
95 base::Bind(&BackgroundSyncManager::PendingStatusAndRegistrationCallback,
96 weak_ptr_factory_.GetWeakPtr(), callback);
98 op_scheduler_.ScheduleOperation(
99 base::Bind(&BackgroundSyncManager::GetRegistrationImpl,
100 weak_ptr_factory_.GetWeakPtr(), origin, sw_registration_id,
101 sync_registration_name, pending_callback));
104 BackgroundSyncManager::BackgroundSyncManager(
105 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
106 : service_worker_context_(service_worker_context), weak_ptr_factory_(this) {
109 void BackgroundSyncManager::Init() {
110 DCHECK_CURRENTLY_ON(BrowserThread::IO);
111 DCHECK(!op_scheduler_.ScheduledOperations());
113 op_scheduler_.ScheduleOperation(base::Bind(&BackgroundSyncManager::InitImpl,
114 weak_ptr_factory_.GetWeakPtr()));
117 void BackgroundSyncManager::InitImpl() {
118 DCHECK_CURRENTLY_ON(BrowserThread::IO);
120 GetDataFromBackend(
121 kBackgroundSyncUserDataKey,
122 base::Bind(&BackgroundSyncManager::InitDidGetDataFromBackend,
123 weak_ptr_factory_.GetWeakPtr()));
126 void BackgroundSyncManager::InitDidGetDataFromBackend(
127 const std::vector<std::pair<int64, std::string>>& user_data,
128 ServiceWorkerStatusCode status) {
129 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND)
130 LOG(ERROR) << "Background Sync Failed to load from backend.";
132 bool corruption_detected = false;
133 for (const std::pair<int64, std::string>& data : user_data) {
134 BackgroundSyncRegistrationsProto registrations_proto;
135 if (registrations_proto.ParseFromString(data.second)) {
136 sw_to_registrations_map_[data.first] = BackgroundSyncRegistrations(
137 registrations_proto.next_registration_id());
138 BackgroundSyncRegistrations* registrations =
139 &sw_to_registrations_map_[data.first];
141 for (int i = 0, max = registrations_proto.registration_size(); i < max;
142 ++i) {
143 const BackgroundSyncRegistrationProto& registration_proto =
144 registrations_proto.registration(i);
146 if (registration_proto.id() >= registrations->next_id) {
147 corruption_detected = true;
148 break;
151 BackgroundSyncRegistration registration(registration_proto.id(),
152 registration_proto.name());
153 if (registration_proto.has_min_period())
154 registration.min_period = registration_proto.min_period();
155 registrations->name_to_registration_map[registration_proto.name()] =
156 registration;
160 if (corruption_detected)
161 break;
164 if (corruption_detected) {
165 LOG(ERROR) << "Corruption detected in background sync backend";
166 sw_to_registrations_map_.clear();
169 // TODO(jkarlin): Call the scheduling algorithm here.
171 op_scheduler_.CompleteOperationAndRunNext();
174 void BackgroundSyncManager::RegisterImpl(
175 const GURL& origin,
176 int64 sw_registration_id,
177 const BackgroundSyncRegistration& sync_registration,
178 const StatusAndRegistrationCallback& callback) {
179 BackgroundSyncRegistration existing_registration;
180 if (LookupRegistration(sw_registration_id, sync_registration.name,
181 &existing_registration)) {
182 if (existing_registration.Equals(sync_registration)) {
183 base::MessageLoop::current()->PostTask(
184 FROM_HERE,
185 base::Bind(callback, ERROR_TYPE_OK, existing_registration));
186 return;
190 BackgroundSyncRegistration new_registration = sync_registration;
191 BackgroundSyncRegistrations* registrations =
192 &sw_to_registrations_map_[sw_registration_id];
193 new_registration.id = registrations->next_id++;
195 AddRegistrationToMap(sw_registration_id, new_registration);
197 StoreRegistrations(
198 origin, sw_registration_id,
199 base::Bind(&BackgroundSyncManager::RegisterDidStore,
200 weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
201 new_registration, existing_registration, callback));
204 bool BackgroundSyncManager::LookupRegistration(
205 int64 sw_registration_id,
206 const std::string& sync_registration_name,
207 BackgroundSyncRegistration* existing_registration) {
208 SWIdToRegistrationsMap::iterator it =
209 sw_to_registrations_map_.find(sw_registration_id);
210 if (it == sw_to_registrations_map_.end())
211 return false;
213 const BackgroundSyncRegistrations& registrations = it->second;
214 const auto name_and_registration_iter =
215 registrations.name_to_registration_map.find(sync_registration_name);
216 if (name_and_registration_iter ==
217 registrations.name_to_registration_map.end())
218 return false;
220 if (existing_registration)
221 *existing_registration = name_and_registration_iter->second;
223 return true;
226 void BackgroundSyncManager::StoreRegistrations(
227 const GURL& origin,
228 int64 sw_registration_id,
229 const ServiceWorkerStorage::StatusCallback& callback) {
230 // Serialize the data.
231 const BackgroundSyncRegistrations& registrations =
232 sw_to_registrations_map_[sw_registration_id];
233 BackgroundSyncRegistrationsProto registrations_proto;
234 registrations_proto.set_next_registration_id(registrations.next_id);
236 for (const auto& name_and_registration :
237 registrations.name_to_registration_map) {
238 const BackgroundSyncRegistration& registration =
239 name_and_registration.second;
240 BackgroundSyncRegistrationProto* registration_proto =
241 registrations_proto.add_registration();
242 registration_proto->set_id(registration.id);
243 registration_proto->set_name(registration.name);
244 if (registration.min_period != 0)
245 registration_proto->set_min_period(registration.min_period);
247 std::string serialized;
248 bool success = registrations_proto.SerializeToString(&serialized);
249 DCHECK(success);
251 StoreDataInBackend(sw_registration_id, origin, kBackgroundSyncUserDataKey,
252 serialized, callback);
255 void BackgroundSyncManager::RegisterDidStore(
256 int64 sw_registration_id,
257 const BackgroundSyncRegistration& new_registration,
258 const BackgroundSyncRegistration& previous_registration,
259 const StatusAndRegistrationCallback& callback,
260 ServiceWorkerStatusCode status) {
261 if (status != SERVICE_WORKER_OK) {
262 // Restore the previous state.
263 if (previous_registration.id !=
264 BackgroundSyncRegistration::kInvalidRegistrationId) {
265 AddRegistrationToMap(sw_registration_id, previous_registration);
266 } else {
267 RemoveRegistrationFromMap(sw_registration_id, new_registration.name,
268 nullptr);
270 base::MessageLoop::current()->PostTask(
271 FROM_HERE,
272 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration()));
273 return;
276 // TODO(jkarlin): Run the registration algorithm.
277 base::MessageLoop::current()->PostTask(
278 FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, new_registration));
281 void BackgroundSyncManager::RemoveRegistrationFromMap(
282 int64 sw_registration_id,
283 const std::string& sync_registration_name,
284 BackgroundSyncRegistration* old_registration) {
285 DCHECK(
286 LookupRegistration(sw_registration_id, sync_registration_name, nullptr));
288 BackgroundSyncRegistrations* registrations =
289 &sw_to_registrations_map_[sw_registration_id];
291 const auto name_and_registration_iter =
292 registrations->name_to_registration_map.find(sync_registration_name);
293 if (old_registration)
294 *old_registration = name_and_registration_iter->second;
296 registrations->name_to_registration_map.erase(name_and_registration_iter);
299 void BackgroundSyncManager::AddRegistrationToMap(
300 int64 sw_registration_id,
301 const BackgroundSyncRegistration& sync_registration) {
302 DCHECK_NE(BackgroundSyncRegistration::kInvalidRegistrationId,
303 sw_registration_id);
305 BackgroundSyncRegistrations* registrations =
306 &sw_to_registrations_map_[sw_registration_id];
307 registrations->name_to_registration_map[sync_registration.name] =
308 sync_registration;
311 void BackgroundSyncManager::StoreDataInBackend(
312 int64 sw_registration_id,
313 const GURL& origin,
314 const std::string& key,
315 const std::string& data,
316 const ServiceWorkerStorage::StatusCallback& callback) {
317 service_worker_context_->context()->storage()->StoreUserData(
318 sw_registration_id, origin, key, data, callback);
321 void BackgroundSyncManager::GetDataFromBackend(
322 const std::string& key,
323 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback&
324 callback) {
325 DCHECK_CURRENTLY_ON(BrowserThread::IO);
327 service_worker_context_->context()->storage()->GetUserDataForAllRegistrations(
328 key, callback);
331 void BackgroundSyncManager::UnregisterImpl(
332 const GURL& origin,
333 int64 sw_registration_id,
334 const std::string& sync_registration_name,
335 BackgroundSyncRegistration::RegistrationId sync_registration_id,
336 const StatusCallback& callback) {
337 BackgroundSyncRegistration existing_registration;
338 if (!LookupRegistration(sw_registration_id, sync_registration_name,
339 &existing_registration) ||
340 existing_registration.id != sync_registration_id) {
341 base::MessageLoop::current()->PostTask(
342 FROM_HERE, base::Bind(callback, ERROR_TYPE_NOT_FOUND));
343 return;
346 BackgroundSyncRegistration old_sync_registration;
347 RemoveRegistrationFromMap(sw_registration_id, sync_registration_name,
348 &old_sync_registration);
350 StoreRegistrations(
351 origin, sw_registration_id,
352 base::Bind(&BackgroundSyncManager::UnregisterDidStore,
353 weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
354 old_sync_registration, callback));
357 void BackgroundSyncManager::UnregisterDidStore(
358 int64 sw_registration_id,
359 const BackgroundSyncRegistration& old_sync_registration,
360 const StatusCallback& callback,
361 ServiceWorkerStatusCode status) {
362 if (status != SERVICE_WORKER_OK) {
363 // Restore the previous state.
364 AddRegistrationToMap(sw_registration_id, old_sync_registration);
365 base::MessageLoop::current()->PostTask(
366 FROM_HERE, base::Bind(callback, ERROR_TYPE_STORAGE));
367 return;
370 // TODO(jkarlin): Run the registration algorithm.
371 base::MessageLoop::current()->PostTask(FROM_HERE,
372 base::Bind(callback, ERROR_TYPE_OK));
375 void BackgroundSyncManager::GetRegistrationImpl(
376 const GURL& origin,
377 int64 sw_registration_id,
378 const std::string sync_registration_name,
379 const StatusAndRegistrationCallback& callback) {
380 BackgroundSyncRegistration out_registration;
381 if (!LookupRegistration(sw_registration_id, sync_registration_name,
382 &out_registration)) {
383 base::MessageLoop::current()->PostTask(
384 FROM_HERE, base::Bind(callback, ERROR_TYPE_NOT_FOUND,
385 BackgroundSyncRegistration()));
386 return;
389 base::MessageLoop::current()->PostTask(
390 FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, out_registration));
393 void BackgroundSyncManager::PendingStatusAndRegistrationCallback(
394 const StatusAndRegistrationCallback& callback,
395 ErrorType error,
396 const BackgroundSyncRegistration& sync_registration) {
397 // The callback might delete this object, so hang onto a weak ptr to find out.
398 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
399 callback.Run(error, sync_registration);
400 if (manager)
401 op_scheduler_.CompleteOperationAndRunNext();
404 void BackgroundSyncManager::PendingStatusCallback(
405 const StatusCallback& callback,
406 ErrorType error) {
407 // The callback might delete this object, so hang onto a weak ptr to find out.
408 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
409 callback.Run(error);
410 if (manager)
411 op_scheduler_.CompleteOperationAndRunNext();
414 } // namespace content