| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 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 "webkit/browser/appcache/appcache_service_impl.h" | |
| 6 | |
| 7 #include <functional> | |
| 8 | |
| 9 #include "base/bind.h" | |
| 10 #include "base/bind_helpers.h" | |
| 11 #include "base/logging.h" | |
| 12 #include "base/message_loop/message_loop.h" | |
| 13 #include "base/stl_util.h" | |
| 14 #include "net/base/completion_callback.h" | |
| 15 #include "net/base/io_buffer.h" | |
| 16 #include "webkit/browser/appcache/appcache.h" | |
| 17 #include "webkit/browser/appcache/appcache_backend_impl.h" | |
| 18 #include "webkit/browser/appcache/appcache_entry.h" | |
| 19 #include "webkit/browser/appcache/appcache_executable_handler.h" | |
| 20 #include "webkit/browser/appcache/appcache_histograms.h" | |
| 21 #include "webkit/browser/appcache/appcache_policy.h" | |
| 22 #include "webkit/browser/appcache/appcache_quota_client.h" | |
| 23 #include "webkit/browser/appcache/appcache_response.h" | |
| 24 #include "webkit/browser/appcache/appcache_service_impl.h" | |
| 25 #include "webkit/browser/appcache/appcache_storage_impl.h" | |
| 26 #include "webkit/browser/quota/special_storage_policy.h" | |
| 27 | |
| 28 namespace appcache { | |
| 29 | |
| 30 namespace { | |
| 31 | |
| 32 void DeferredCallback(const net::CompletionCallback& callback, int rv) { | |
| 33 callback.Run(rv); | |
| 34 } | |
| 35 | |
| 36 } // namespace | |
| 37 | |
| 38 AppCacheInfoCollection::AppCacheInfoCollection() {} | |
| 39 | |
| 40 AppCacheInfoCollection::~AppCacheInfoCollection() {} | |
| 41 | |
| 42 // AsyncHelper ------- | |
| 43 | |
| 44 class AppCacheServiceImpl::AsyncHelper | |
| 45 : public AppCacheStorage::Delegate { | |
| 46 public: | |
| 47 AsyncHelper(AppCacheServiceImpl* service, | |
| 48 const net::CompletionCallback& callback) | |
| 49 : service_(service), callback_(callback) { | |
| 50 service_->pending_helpers_.insert(this); | |
| 51 } | |
| 52 | |
| 53 virtual ~AsyncHelper() { | |
| 54 if (service_) | |
| 55 service_->pending_helpers_.erase(this); | |
| 56 } | |
| 57 | |
| 58 virtual void Start() = 0; | |
| 59 virtual void Cancel(); | |
| 60 | |
| 61 protected: | |
| 62 void CallCallback(int rv) { | |
| 63 if (!callback_.is_null()) { | |
| 64 // Defer to guarantee async completion. | |
| 65 base::MessageLoop::current()->PostTask( | |
| 66 FROM_HERE, base::Bind(&DeferredCallback, callback_, rv)); | |
| 67 } | |
| 68 callback_.Reset(); | |
| 69 } | |
| 70 | |
| 71 AppCacheServiceImpl* service_; | |
| 72 net::CompletionCallback callback_; | |
| 73 }; | |
| 74 | |
| 75 void AppCacheServiceImpl::AsyncHelper::Cancel() { | |
| 76 if (!callback_.is_null()) { | |
| 77 callback_.Run(net::ERR_ABORTED); | |
| 78 callback_.Reset(); | |
| 79 } | |
| 80 service_->storage()->CancelDelegateCallbacks(this); | |
| 81 service_ = NULL; | |
| 82 } | |
| 83 | |
| 84 // CanHandleOfflineHelper ------- | |
| 85 | |
| 86 class AppCacheServiceImpl::CanHandleOfflineHelper : AsyncHelper { | |
| 87 public: | |
| 88 CanHandleOfflineHelper( | |
| 89 AppCacheServiceImpl* service, const GURL& url, | |
| 90 const GURL& first_party, const net::CompletionCallback& callback) | |
| 91 : AsyncHelper(service, callback), | |
| 92 url_(url), | |
| 93 first_party_(first_party) { | |
| 94 } | |
| 95 | |
| 96 virtual void Start() OVERRIDE { | |
| 97 AppCachePolicy* policy = service_->appcache_policy(); | |
| 98 if (policy && !policy->CanLoadAppCache(url_, first_party_)) { | |
| 99 CallCallback(net::ERR_FAILED); | |
| 100 delete this; | |
| 101 return; | |
| 102 } | |
| 103 | |
| 104 service_->storage()->FindResponseForMainRequest(url_, GURL(), this); | |
| 105 } | |
| 106 | |
| 107 private: | |
| 108 // AppCacheStorage::Delegate implementation. | |
| 109 virtual void OnMainResponseFound( | |
| 110 const GURL& url, const AppCacheEntry& entry, | |
| 111 const GURL& fallback_url, const AppCacheEntry& fallback_entry, | |
| 112 int64 cache_id, int64 group_id, const GURL& mainfest_url) OVERRIDE; | |
| 113 | |
| 114 GURL url_; | |
| 115 GURL first_party_; | |
| 116 | |
| 117 DISALLOW_COPY_AND_ASSIGN(CanHandleOfflineHelper); | |
| 118 }; | |
| 119 | |
| 120 void AppCacheServiceImpl::CanHandleOfflineHelper::OnMainResponseFound( | |
| 121 const GURL& url, const AppCacheEntry& entry, | |
| 122 const GURL& fallback_url, const AppCacheEntry& fallback_entry, | |
| 123 int64 cache_id, int64 group_id, const GURL& manifest_url) { | |
| 124 bool can = (entry.has_response_id() || fallback_entry.has_response_id()); | |
| 125 CallCallback(can ? net::OK : net::ERR_FAILED); | |
| 126 delete this; | |
| 127 } | |
| 128 | |
| 129 // DeleteHelper ------- | |
| 130 | |
| 131 class AppCacheServiceImpl::DeleteHelper : public AsyncHelper { | |
| 132 public: | |
| 133 DeleteHelper( | |
| 134 AppCacheServiceImpl* service, const GURL& manifest_url, | |
| 135 const net::CompletionCallback& callback) | |
| 136 : AsyncHelper(service, callback), manifest_url_(manifest_url) { | |
| 137 } | |
| 138 | |
| 139 virtual void Start() OVERRIDE { | |
| 140 service_->storage()->LoadOrCreateGroup(manifest_url_, this); | |
| 141 } | |
| 142 | |
| 143 private: | |
| 144 // AppCacheStorage::Delegate implementation. | |
| 145 virtual void OnGroupLoaded( | |
| 146 appcache::AppCacheGroup* group, const GURL& manifest_url) OVERRIDE; | |
| 147 virtual void OnGroupMadeObsolete(appcache::AppCacheGroup* group, | |
| 148 bool success, | |
| 149 int response_code) OVERRIDE; | |
| 150 | |
| 151 GURL manifest_url_; | |
| 152 DISALLOW_COPY_AND_ASSIGN(DeleteHelper); | |
| 153 }; | |
| 154 | |
| 155 void AppCacheServiceImpl::DeleteHelper::OnGroupLoaded( | |
| 156 appcache::AppCacheGroup* group, const GURL& manifest_url) { | |
| 157 if (group) { | |
| 158 group->set_being_deleted(true); | |
| 159 group->CancelUpdate(); | |
| 160 service_->storage()->MakeGroupObsolete(group, this, 0); | |
| 161 } else { | |
| 162 CallCallback(net::ERR_FAILED); | |
| 163 delete this; | |
| 164 } | |
| 165 } | |
| 166 | |
| 167 void AppCacheServiceImpl::DeleteHelper::OnGroupMadeObsolete( | |
| 168 appcache::AppCacheGroup* group, | |
| 169 bool success, | |
| 170 int response_code) { | |
| 171 CallCallback(success ? net::OK : net::ERR_FAILED); | |
| 172 delete this; | |
| 173 } | |
| 174 | |
| 175 // DeleteOriginHelper ------- | |
| 176 | |
| 177 class AppCacheServiceImpl::DeleteOriginHelper : public AsyncHelper { | |
| 178 public: | |
| 179 DeleteOriginHelper( | |
| 180 AppCacheServiceImpl* service, const GURL& origin, | |
| 181 const net::CompletionCallback& callback) | |
| 182 : AsyncHelper(service, callback), origin_(origin), | |
| 183 num_caches_to_delete_(0), successes_(0), failures_(0) { | |
| 184 } | |
| 185 | |
| 186 virtual void Start() OVERRIDE { | |
| 187 // We start by listing all caches, continues in OnAllInfo(). | |
| 188 service_->storage()->GetAllInfo(this); | |
| 189 } | |
| 190 | |
| 191 private: | |
| 192 // AppCacheStorage::Delegate implementation. | |
| 193 virtual void OnAllInfo(AppCacheInfoCollection* collection) OVERRIDE; | |
| 194 virtual void OnGroupLoaded( | |
| 195 appcache::AppCacheGroup* group, const GURL& manifest_url) OVERRIDE; | |
| 196 virtual void OnGroupMadeObsolete(appcache::AppCacheGroup* group, | |
| 197 bool success, | |
| 198 int response_code) OVERRIDE; | |
| 199 | |
| 200 void CacheCompleted(bool success); | |
| 201 | |
| 202 GURL origin_; | |
| 203 int num_caches_to_delete_; | |
| 204 int successes_; | |
| 205 int failures_; | |
| 206 | |
| 207 DISALLOW_COPY_AND_ASSIGN(DeleteOriginHelper); | |
| 208 }; | |
| 209 | |
| 210 void AppCacheServiceImpl::DeleteOriginHelper::OnAllInfo( | |
| 211 AppCacheInfoCollection* collection) { | |
| 212 if (!collection) { | |
| 213 // Failed to get a listing. | |
| 214 CallCallback(net::ERR_FAILED); | |
| 215 delete this; | |
| 216 return; | |
| 217 } | |
| 218 | |
| 219 std::map<GURL, AppCacheInfoVector>::iterator found = | |
| 220 collection->infos_by_origin.find(origin_); | |
| 221 if (found == collection->infos_by_origin.end() || found->second.empty()) { | |
| 222 // No caches for this origin. | |
| 223 CallCallback(net::OK); | |
| 224 delete this; | |
| 225 return; | |
| 226 } | |
| 227 | |
| 228 // We have some caches to delete. | |
| 229 const AppCacheInfoVector& caches_to_delete = found->second; | |
| 230 successes_ = 0; | |
| 231 failures_ = 0; | |
| 232 num_caches_to_delete_ = static_cast<int>(caches_to_delete.size()); | |
| 233 for (AppCacheInfoVector::const_iterator iter = caches_to_delete.begin(); | |
| 234 iter != caches_to_delete.end(); ++iter) { | |
| 235 service_->storage()->LoadOrCreateGroup(iter->manifest_url, this); | |
| 236 } | |
| 237 } | |
| 238 | |
| 239 void AppCacheServiceImpl::DeleteOriginHelper::OnGroupLoaded( | |
| 240 appcache::AppCacheGroup* group, const GURL& manifest_url) { | |
| 241 if (group) { | |
| 242 group->set_being_deleted(true); | |
| 243 group->CancelUpdate(); | |
| 244 service_->storage()->MakeGroupObsolete(group, this, 0); | |
| 245 } else { | |
| 246 CacheCompleted(false); | |
| 247 } | |
| 248 } | |
| 249 | |
| 250 void AppCacheServiceImpl::DeleteOriginHelper::OnGroupMadeObsolete( | |
| 251 appcache::AppCacheGroup* group, | |
| 252 bool success, | |
| 253 int response_code) { | |
| 254 CacheCompleted(success); | |
| 255 } | |
| 256 | |
| 257 void AppCacheServiceImpl::DeleteOriginHelper::CacheCompleted(bool success) { | |
| 258 if (success) | |
| 259 ++successes_; | |
| 260 else | |
| 261 ++failures_; | |
| 262 if ((successes_ + failures_) < num_caches_to_delete_) | |
| 263 return; | |
| 264 | |
| 265 CallCallback(!failures_ ? net::OK : net::ERR_FAILED); | |
| 266 delete this; | |
| 267 } | |
| 268 | |
| 269 | |
| 270 // GetInfoHelper ------- | |
| 271 | |
| 272 class AppCacheServiceImpl::GetInfoHelper : AsyncHelper { | |
| 273 public: | |
| 274 GetInfoHelper( | |
| 275 AppCacheServiceImpl* service, AppCacheInfoCollection* collection, | |
| 276 const net::CompletionCallback& callback) | |
| 277 : AsyncHelper(service, callback), collection_(collection) { | |
| 278 } | |
| 279 | |
| 280 virtual void Start() OVERRIDE { | |
| 281 service_->storage()->GetAllInfo(this); | |
| 282 } | |
| 283 | |
| 284 private: | |
| 285 // AppCacheStorage::Delegate implementation. | |
| 286 virtual void OnAllInfo(AppCacheInfoCollection* collection) OVERRIDE; | |
| 287 | |
| 288 scoped_refptr<AppCacheInfoCollection> collection_; | |
| 289 | |
| 290 DISALLOW_COPY_AND_ASSIGN(GetInfoHelper); | |
| 291 }; | |
| 292 | |
| 293 void AppCacheServiceImpl::GetInfoHelper::OnAllInfo( | |
| 294 AppCacheInfoCollection* collection) { | |
| 295 if (collection) | |
| 296 collection->infos_by_origin.swap(collection_->infos_by_origin); | |
| 297 CallCallback(collection ? net::OK : net::ERR_FAILED); | |
| 298 delete this; | |
| 299 } | |
| 300 | |
| 301 // CheckResponseHelper ------- | |
| 302 | |
| 303 class AppCacheServiceImpl::CheckResponseHelper : AsyncHelper { | |
| 304 public: | |
| 305 CheckResponseHelper( | |
| 306 AppCacheServiceImpl* service, const GURL& manifest_url, int64 cache_id, | |
| 307 int64 response_id) | |
| 308 : AsyncHelper(service, net::CompletionCallback()), | |
| 309 manifest_url_(manifest_url), | |
| 310 cache_id_(cache_id), | |
| 311 response_id_(response_id), | |
| 312 kIOBufferSize(32 * 1024), | |
| 313 expected_total_size_(0), | |
| 314 amount_headers_read_(0), | |
| 315 amount_data_read_(0) { | |
| 316 } | |
| 317 | |
| 318 virtual void Start() OVERRIDE { | |
| 319 service_->storage()->LoadOrCreateGroup(manifest_url_, this); | |
| 320 } | |
| 321 | |
| 322 virtual void Cancel() OVERRIDE { | |
| 323 AppCacheHistograms::CountCheckResponseResult( | |
| 324 AppCacheHistograms::CHECK_CANCELED); | |
| 325 response_reader_.reset(); | |
| 326 AsyncHelper::Cancel(); | |
| 327 } | |
| 328 | |
| 329 private: | |
| 330 virtual void OnGroupLoaded(AppCacheGroup* group, | |
| 331 const GURL& manifest_url) OVERRIDE; | |
| 332 void OnReadInfoComplete(int result); | |
| 333 void OnReadDataComplete(int result); | |
| 334 | |
| 335 // Inputs describing what to check. | |
| 336 GURL manifest_url_; | |
| 337 int64 cache_id_; | |
| 338 int64 response_id_; | |
| 339 | |
| 340 // Internals used to perform the checks. | |
| 341 const int kIOBufferSize; | |
| 342 scoped_refptr<AppCache> cache_; | |
| 343 scoped_ptr<AppCacheResponseReader> response_reader_; | |
| 344 scoped_refptr<HttpResponseInfoIOBuffer> info_buffer_; | |
| 345 scoped_refptr<net::IOBuffer> data_buffer_; | |
| 346 int64 expected_total_size_; | |
| 347 int amount_headers_read_; | |
| 348 int amount_data_read_; | |
| 349 DISALLOW_COPY_AND_ASSIGN(CheckResponseHelper); | |
| 350 }; | |
| 351 | |
| 352 void AppCacheServiceImpl::CheckResponseHelper::OnGroupLoaded( | |
| 353 AppCacheGroup* group, const GURL& manifest_url) { | |
| 354 DCHECK_EQ(manifest_url_, manifest_url); | |
| 355 if (!group || !group->newest_complete_cache() || group->is_being_deleted() || | |
| 356 group->is_obsolete()) { | |
| 357 AppCacheHistograms::CountCheckResponseResult( | |
| 358 AppCacheHistograms::MANIFEST_OUT_OF_DATE); | |
| 359 delete this; | |
| 360 return; | |
| 361 } | |
| 362 | |
| 363 cache_ = group->newest_complete_cache(); | |
| 364 const AppCacheEntry* entry = cache_->GetEntryWithResponseId(response_id_); | |
| 365 if (!entry) { | |
| 366 if (cache_->cache_id() == cache_id_) { | |
| 367 AppCacheHistograms::CountCheckResponseResult( | |
| 368 AppCacheHistograms::ENTRY_NOT_FOUND); | |
| 369 service_->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); | |
| 370 } else { | |
| 371 AppCacheHistograms::CountCheckResponseResult( | |
| 372 AppCacheHistograms::RESPONSE_OUT_OF_DATE); | |
| 373 } | |
| 374 delete this; | |
| 375 return; | |
| 376 } | |
| 377 | |
| 378 // Verify that we can read the response info and data. | |
| 379 expected_total_size_ = entry->response_size(); | |
| 380 response_reader_.reset(service_->storage()->CreateResponseReader( | |
| 381 manifest_url_, group->group_id(), response_id_)); | |
| 382 info_buffer_ = new HttpResponseInfoIOBuffer(); | |
| 383 response_reader_->ReadInfo( | |
| 384 info_buffer_.get(), | |
| 385 base::Bind(&CheckResponseHelper::OnReadInfoComplete, | |
| 386 base::Unretained(this))); | |
| 387 } | |
| 388 | |
| 389 void AppCacheServiceImpl::CheckResponseHelper::OnReadInfoComplete(int result) { | |
| 390 if (result < 0) { | |
| 391 AppCacheHistograms::CountCheckResponseResult( | |
| 392 AppCacheHistograms::READ_HEADERS_ERROR); | |
| 393 service_->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); | |
| 394 delete this; | |
| 395 return; | |
| 396 } | |
| 397 amount_headers_read_ = result; | |
| 398 | |
| 399 // Start reading the data. | |
| 400 data_buffer_ = new net::IOBuffer(kIOBufferSize); | |
| 401 response_reader_->ReadData( | |
| 402 data_buffer_.get(), | |
| 403 kIOBufferSize, | |
| 404 base::Bind(&CheckResponseHelper::OnReadDataComplete, | |
| 405 base::Unretained(this))); | |
| 406 } | |
| 407 | |
| 408 void AppCacheServiceImpl::CheckResponseHelper::OnReadDataComplete(int result) { | |
| 409 if (result > 0) { | |
| 410 // Keep reading until we've read thru everything or failed to read. | |
| 411 amount_data_read_ += result; | |
| 412 response_reader_->ReadData( | |
| 413 data_buffer_.get(), | |
| 414 kIOBufferSize, | |
| 415 base::Bind(&CheckResponseHelper::OnReadDataComplete, | |
| 416 base::Unretained(this))); | |
| 417 return; | |
| 418 } | |
| 419 | |
| 420 AppCacheHistograms::CheckResponseResultType check_result; | |
| 421 if (result < 0) | |
| 422 check_result = AppCacheHistograms::READ_DATA_ERROR; | |
| 423 else if (info_buffer_->response_data_size != amount_data_read_ || | |
| 424 expected_total_size_ != amount_data_read_ + amount_headers_read_) | |
| 425 check_result = AppCacheHistograms::UNEXPECTED_DATA_SIZE; | |
| 426 else | |
| 427 check_result = AppCacheHistograms::RESPONSE_OK; | |
| 428 AppCacheHistograms::CountCheckResponseResult(check_result); | |
| 429 | |
| 430 if (check_result != AppCacheHistograms::RESPONSE_OK) | |
| 431 service_->DeleteAppCacheGroup(manifest_url_, net::CompletionCallback()); | |
| 432 delete this; | |
| 433 } | |
| 434 | |
| 435 // AppCacheStorageReference ------ | |
| 436 | |
| 437 AppCacheStorageReference::AppCacheStorageReference( | |
| 438 scoped_ptr<AppCacheStorage> storage) | |
| 439 : storage_(storage.Pass()) {} | |
| 440 AppCacheStorageReference::~AppCacheStorageReference() {} | |
| 441 | |
| 442 // AppCacheServiceImpl ------- | |
| 443 | |
| 444 AppCacheServiceImpl::AppCacheServiceImpl(quota::QuotaManagerProxy* | |
| 445 quota_manager_proxy) | |
| 446 : appcache_policy_(NULL), quota_client_(NULL), handler_factory_(NULL), | |
| 447 quota_manager_proxy_(quota_manager_proxy), | |
| 448 request_context_(NULL), | |
| 449 force_keep_session_state_(false) { | |
| 450 if (quota_manager_proxy_.get()) { | |
| 451 quota_client_ = new AppCacheQuotaClient(this); | |
| 452 quota_manager_proxy_->RegisterClient(quota_client_); | |
| 453 } | |
| 454 } | |
| 455 | |
| 456 AppCacheServiceImpl::~AppCacheServiceImpl() { | |
| 457 DCHECK(backends_.empty()); | |
| 458 std::for_each(pending_helpers_.begin(), | |
| 459 pending_helpers_.end(), | |
| 460 std::mem_fun(&AsyncHelper::Cancel)); | |
| 461 STLDeleteElements(&pending_helpers_); | |
| 462 if (quota_client_) | |
| 463 quota_client_->NotifyAppCacheDestroyed(); | |
| 464 | |
| 465 // Destroy storage_ first; ~AppCacheStorageImpl accesses other data members | |
| 466 // (special_storage_policy_). | |
| 467 storage_.reset(); | |
| 468 } | |
| 469 | |
| 470 void AppCacheServiceImpl::Initialize(const base::FilePath& cache_directory, | |
| 471 base::MessageLoopProxy* db_thread, | |
| 472 base::MessageLoopProxy* cache_thread) { | |
| 473 DCHECK(!storage_.get()); | |
| 474 cache_directory_ = cache_directory; | |
| 475 db_thread_ = db_thread; | |
| 476 cache_thread_ = cache_thread; | |
| 477 AppCacheStorageImpl* storage = new AppCacheStorageImpl(this); | |
| 478 storage->Initialize(cache_directory, db_thread, cache_thread); | |
| 479 storage_.reset(storage); | |
| 480 } | |
| 481 | |
| 482 void AppCacheServiceImpl::ScheduleReinitialize() { | |
| 483 if (reinit_timer_.IsRunning()) | |
| 484 return; | |
| 485 | |
| 486 // Reinitialization only happens when corruption has been noticed. | |
| 487 // We don't want to thrash the disk but we also don't want to | |
| 488 // leave the appcache disabled for an indefinite period of time. Some | |
| 489 // users never shutdown the browser. | |
| 490 | |
| 491 const base::TimeDelta kZeroDelta; | |
| 492 const base::TimeDelta kOneHour(base::TimeDelta::FromHours(1)); | |
| 493 const base::TimeDelta k30Seconds(base::TimeDelta::FromSeconds(30)); | |
| 494 | |
| 495 // If the system managed to stay up for long enough, reset the | |
| 496 // delay so a new failure won't incur a long wait to get going again. | |
| 497 base::TimeDelta up_time = base::Time::Now() - last_reinit_time_; | |
| 498 if (next_reinit_delay_ != kZeroDelta && up_time > kOneHour) | |
| 499 next_reinit_delay_ = kZeroDelta; | |
| 500 | |
| 501 reinit_timer_.Start(FROM_HERE, next_reinit_delay_, | |
| 502 this, &AppCacheServiceImpl::Reinitialize); | |
| 503 | |
| 504 // Adjust the delay for next time. | |
| 505 base::TimeDelta increment = std::max(k30Seconds, next_reinit_delay_); | |
| 506 next_reinit_delay_ = std::min(next_reinit_delay_ + increment, kOneHour); | |
| 507 } | |
| 508 | |
| 509 void AppCacheServiceImpl::Reinitialize() { | |
| 510 AppCacheHistograms::CountReinitAttempt(!last_reinit_time_.is_null()); | |
| 511 last_reinit_time_ = base::Time::Now(); | |
| 512 | |
| 513 // Inform observers of about this and give them a chance to | |
| 514 // defer deletion of the old storage object. | |
| 515 scoped_refptr<AppCacheStorageReference> | |
| 516 old_storage_ref(new AppCacheStorageReference(storage_.Pass())); | |
| 517 FOR_EACH_OBSERVER(Observer, observers_, | |
| 518 OnServiceReinitialized(old_storage_ref.get())); | |
| 519 | |
| 520 Initialize(cache_directory_, db_thread_, cache_thread_); | |
| 521 } | |
| 522 | |
| 523 void AppCacheServiceImpl::CanHandleMainResourceOffline( | |
| 524 const GURL& url, | |
| 525 const GURL& first_party, | |
| 526 const net::CompletionCallback& callback) { | |
| 527 CanHandleOfflineHelper* helper = | |
| 528 new CanHandleOfflineHelper(this, url, first_party, callback); | |
| 529 helper->Start(); | |
| 530 } | |
| 531 | |
| 532 void AppCacheServiceImpl::GetAllAppCacheInfo( | |
| 533 AppCacheInfoCollection* collection, | |
| 534 const net::CompletionCallback& callback) { | |
| 535 DCHECK(collection); | |
| 536 GetInfoHelper* helper = new GetInfoHelper(this, collection, callback); | |
| 537 helper->Start(); | |
| 538 } | |
| 539 | |
| 540 void AppCacheServiceImpl::DeleteAppCacheGroup( | |
| 541 const GURL& manifest_url, | |
| 542 const net::CompletionCallback& callback) { | |
| 543 DeleteHelper* helper = new DeleteHelper(this, manifest_url, callback); | |
| 544 helper->Start(); | |
| 545 } | |
| 546 | |
| 547 void AppCacheServiceImpl::DeleteAppCachesForOrigin( | |
| 548 const GURL& origin, const net::CompletionCallback& callback) { | |
| 549 DeleteOriginHelper* helper = new DeleteOriginHelper(this, origin, callback); | |
| 550 helper->Start(); | |
| 551 } | |
| 552 | |
| 553 void AppCacheServiceImpl::CheckAppCacheResponse(const GURL& manifest_url, | |
| 554 int64 cache_id, | |
| 555 int64 response_id) { | |
| 556 CheckResponseHelper* helper = new CheckResponseHelper( | |
| 557 this, manifest_url, cache_id, response_id); | |
| 558 helper->Start(); | |
| 559 } | |
| 560 | |
| 561 void AppCacheServiceImpl::set_special_storage_policy( | |
| 562 quota::SpecialStoragePolicy* policy) { | |
| 563 special_storage_policy_ = policy; | |
| 564 } | |
| 565 | |
| 566 void AppCacheServiceImpl::RegisterBackend( | |
| 567 AppCacheBackendImpl* backend_impl) { | |
| 568 DCHECK(backends_.find(backend_impl->process_id()) == backends_.end()); | |
| 569 backends_.insert( | |
| 570 BackendMap::value_type(backend_impl->process_id(), backend_impl)); | |
| 571 } | |
| 572 | |
| 573 void AppCacheServiceImpl::UnregisterBackend( | |
| 574 AppCacheBackendImpl* backend_impl) { | |
| 575 backends_.erase(backend_impl->process_id()); | |
| 576 } | |
| 577 | |
| 578 } // namespace appcache | |
| OLD | NEW |