Chromium Code Reviews| 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 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 | |
| OLD | NEW |