| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2011 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_host.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/strings/string_util.h" | |
| 9 #include "base/strings/stringprintf.h" | |
| 10 #include "net/url_request/url_request.h" | |
| 11 #include "webkit/browser/appcache/appcache.h" | |
| 12 #include "webkit/browser/appcache/appcache_backend_impl.h" | |
| 13 #include "webkit/browser/appcache/appcache_policy.h" | |
| 14 #include "webkit/browser/appcache/appcache_request_handler.h" | |
| 15 #include "webkit/browser/quota/quota_manager_proxy.h" | |
| 16 | |
| 17 namespace appcache { | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 void FillCacheInfo(const AppCache* cache, | |
| 22 const GURL& manifest_url, | |
| 23 AppCacheStatus status, AppCacheInfo* info) { | |
| 24 info->manifest_url = manifest_url; | |
| 25 info->status = status; | |
| 26 | |
| 27 if (!cache) | |
| 28 return; | |
| 29 | |
| 30 info->cache_id = cache->cache_id(); | |
| 31 | |
| 32 if (!cache->is_complete()) | |
| 33 return; | |
| 34 | |
| 35 DCHECK(cache->owning_group()); | |
| 36 info->is_complete = true; | |
| 37 info->group_id = cache->owning_group()->group_id(); | |
| 38 info->last_update_time = cache->update_time(); | |
| 39 info->creation_time = cache->owning_group()->creation_time(); | |
| 40 info->size = cache->cache_size(); | |
| 41 } | |
| 42 | |
| 43 } // Anonymous namespace | |
| 44 | |
| 45 AppCacheHost::AppCacheHost(int host_id, AppCacheFrontend* frontend, | |
| 46 AppCacheServiceImpl* service) | |
| 47 : host_id_(host_id), | |
| 48 spawning_host_id_(kAppCacheNoHostId), spawning_process_id_(0), | |
| 49 parent_host_id_(kAppCacheNoHostId), parent_process_id_(0), | |
| 50 pending_main_resource_cache_id_(kAppCacheNoCacheId), | |
| 51 pending_selected_cache_id_(kAppCacheNoCacheId), | |
| 52 frontend_(frontend), service_(service), | |
| 53 storage_(service->storage()), | |
| 54 pending_callback_param_(NULL), | |
| 55 main_resource_was_namespace_entry_(false), | |
| 56 main_resource_blocked_(false), | |
| 57 associated_cache_info_pending_(false) { | |
| 58 service_->AddObserver(this); | |
| 59 } | |
| 60 | |
| 61 AppCacheHost::~AppCacheHost() { | |
| 62 service_->RemoveObserver(this); | |
| 63 FOR_EACH_OBSERVER(Observer, observers_, OnDestructionImminent(this)); | |
| 64 if (associated_cache_.get()) | |
| 65 associated_cache_->UnassociateHost(this); | |
| 66 if (group_being_updated_.get()) | |
| 67 group_being_updated_->RemoveUpdateObserver(this); | |
| 68 storage()->CancelDelegateCallbacks(this); | |
| 69 if (service()->quota_manager_proxy() && !origin_in_use_.is_empty()) | |
| 70 service()->quota_manager_proxy()->NotifyOriginNoLongerInUse(origin_in_use_); | |
| 71 } | |
| 72 | |
| 73 void AppCacheHost::AddObserver(Observer* observer) { | |
| 74 observers_.AddObserver(observer); | |
| 75 } | |
| 76 | |
| 77 void AppCacheHost::RemoveObserver(Observer* observer) { | |
| 78 observers_.RemoveObserver(observer); | |
| 79 } | |
| 80 | |
| 81 void AppCacheHost::SelectCache(const GURL& document_url, | |
| 82 const int64 cache_document_was_loaded_from, | |
| 83 const GURL& manifest_url) { | |
| 84 DCHECK(pending_start_update_callback_.is_null() && | |
| 85 pending_swap_cache_callback_.is_null() && | |
| 86 pending_get_status_callback_.is_null() && | |
| 87 !is_selection_pending()); | |
| 88 | |
| 89 origin_in_use_ = document_url.GetOrigin(); | |
| 90 if (service()->quota_manager_proxy() && !origin_in_use_.is_empty()) | |
| 91 service()->quota_manager_proxy()->NotifyOriginInUse(origin_in_use_); | |
| 92 | |
| 93 if (main_resource_blocked_) | |
| 94 frontend_->OnContentBlocked(host_id_, | |
| 95 blocked_manifest_url_); | |
| 96 | |
| 97 // 6.9.6 The application cache selection algorithm. | |
| 98 // The algorithm is started here and continues in FinishCacheSelection, | |
| 99 // after cache or group loading is complete. | |
| 100 // Note: Foreign entries are detected on the client side and | |
| 101 // MarkAsForeignEntry is called in that case, so that detection | |
| 102 // step is skipped here. See WebApplicationCacheHostImpl.cc | |
| 103 | |
| 104 if (cache_document_was_loaded_from != kAppCacheNoCacheId) { | |
| 105 LoadSelectedCache(cache_document_was_loaded_from); | |
| 106 return; | |
| 107 } | |
| 108 | |
| 109 if (!manifest_url.is_empty() && | |
| 110 (manifest_url.GetOrigin() == document_url.GetOrigin())) { | |
| 111 DCHECK(!first_party_url_.is_empty()); | |
| 112 AppCachePolicy* policy = service()->appcache_policy(); | |
| 113 if (policy && | |
| 114 !policy->CanCreateAppCache(manifest_url, first_party_url_)) { | |
| 115 FinishCacheSelection(NULL, NULL); | |
| 116 std::vector<int> host_ids(1, host_id_); | |
| 117 frontend_->OnEventRaised(host_ids, APPCACHE_CHECKING_EVENT); | |
| 118 frontend_->OnErrorEventRaised( | |
| 119 host_ids, | |
| 120 AppCacheErrorDetails( | |
| 121 "Cache creation was blocked by the content policy", | |
| 122 APPCACHE_POLICY_ERROR, | |
| 123 GURL(), | |
| 124 0, | |
| 125 false /*is_cross_origin*/)); | |
| 126 frontend_->OnContentBlocked(host_id_, manifest_url); | |
| 127 return; | |
| 128 } | |
| 129 | |
| 130 // Note: The client detects if the document was not loaded using HTTP GET | |
| 131 // and invokes SelectCache without a manifest url, so that detection step | |
| 132 // is also skipped here. See WebApplicationCacheHostImpl.cc | |
| 133 set_preferred_manifest_url(manifest_url); | |
| 134 new_master_entry_url_ = document_url; | |
| 135 LoadOrCreateGroup(manifest_url); | |
| 136 return; | |
| 137 } | |
| 138 | |
| 139 // TODO(michaeln): If there was a manifest URL, the user agent may report | |
| 140 // to the user that it was ignored, to aid in application development. | |
| 141 FinishCacheSelection(NULL, NULL); | |
| 142 } | |
| 143 | |
| 144 void AppCacheHost::SelectCacheForWorker(int parent_process_id, | |
| 145 int parent_host_id) { | |
| 146 DCHECK(pending_start_update_callback_.is_null() && | |
| 147 pending_swap_cache_callback_.is_null() && | |
| 148 pending_get_status_callback_.is_null() && | |
| 149 !is_selection_pending()); | |
| 150 | |
| 151 parent_process_id_ = parent_process_id; | |
| 152 parent_host_id_ = parent_host_id; | |
| 153 FinishCacheSelection(NULL, NULL); | |
| 154 } | |
| 155 | |
| 156 void AppCacheHost::SelectCacheForSharedWorker(int64 appcache_id) { | |
| 157 DCHECK(pending_start_update_callback_.is_null() && | |
| 158 pending_swap_cache_callback_.is_null() && | |
| 159 pending_get_status_callback_.is_null() && | |
| 160 !is_selection_pending()); | |
| 161 | |
| 162 if (appcache_id != kAppCacheNoCacheId) { | |
| 163 LoadSelectedCache(appcache_id); | |
| 164 return; | |
| 165 } | |
| 166 FinishCacheSelection(NULL, NULL); | |
| 167 } | |
| 168 | |
| 169 // TODO(michaeln): change method name to MarkEntryAsForeign for consistency | |
| 170 void AppCacheHost::MarkAsForeignEntry(const GURL& document_url, | |
| 171 int64 cache_document_was_loaded_from) { | |
| 172 // The document url is not the resource url in the fallback case. | |
| 173 storage()->MarkEntryAsForeign( | |
| 174 main_resource_was_namespace_entry_ ? namespace_entry_url_ : document_url, | |
| 175 cache_document_was_loaded_from); | |
| 176 SelectCache(document_url, kAppCacheNoCacheId, GURL()); | |
| 177 } | |
| 178 | |
| 179 void AppCacheHost::GetStatusWithCallback(const GetStatusCallback& callback, | |
| 180 void* callback_param) { | |
| 181 DCHECK(pending_start_update_callback_.is_null() && | |
| 182 pending_swap_cache_callback_.is_null() && | |
| 183 pending_get_status_callback_.is_null()); | |
| 184 | |
| 185 pending_get_status_callback_ = callback; | |
| 186 pending_callback_param_ = callback_param; | |
| 187 if (is_selection_pending()) | |
| 188 return; | |
| 189 | |
| 190 DoPendingGetStatus(); | |
| 191 } | |
| 192 | |
| 193 void AppCacheHost::DoPendingGetStatus() { | |
| 194 DCHECK_EQ(false, pending_get_status_callback_.is_null()); | |
| 195 | |
| 196 pending_get_status_callback_.Run(GetStatus(), pending_callback_param_); | |
| 197 pending_get_status_callback_.Reset(); | |
| 198 pending_callback_param_ = NULL; | |
| 199 } | |
| 200 | |
| 201 void AppCacheHost::StartUpdateWithCallback(const StartUpdateCallback& callback, | |
| 202 void* callback_param) { | |
| 203 DCHECK(pending_start_update_callback_.is_null() && | |
| 204 pending_swap_cache_callback_.is_null() && | |
| 205 pending_get_status_callback_.is_null()); | |
| 206 | |
| 207 pending_start_update_callback_ = callback; | |
| 208 pending_callback_param_ = callback_param; | |
| 209 if (is_selection_pending()) | |
| 210 return; | |
| 211 | |
| 212 DoPendingStartUpdate(); | |
| 213 } | |
| 214 | |
| 215 void AppCacheHost::DoPendingStartUpdate() { | |
| 216 DCHECK_EQ(false, pending_start_update_callback_.is_null()); | |
| 217 | |
| 218 // 6.9.8 Application cache API | |
| 219 bool success = false; | |
| 220 if (associated_cache_.get() && associated_cache_->owning_group()) { | |
| 221 AppCacheGroup* group = associated_cache_->owning_group(); | |
| 222 if (!group->is_obsolete() && !group->is_being_deleted()) { | |
| 223 success = true; | |
| 224 group->StartUpdate(); | |
| 225 } | |
| 226 } | |
| 227 | |
| 228 pending_start_update_callback_.Run(success, pending_callback_param_); | |
| 229 pending_start_update_callback_.Reset(); | |
| 230 pending_callback_param_ = NULL; | |
| 231 } | |
| 232 | |
| 233 void AppCacheHost::SwapCacheWithCallback(const SwapCacheCallback& callback, | |
| 234 void* callback_param) { | |
| 235 DCHECK(pending_start_update_callback_.is_null() && | |
| 236 pending_swap_cache_callback_.is_null() && | |
| 237 pending_get_status_callback_.is_null()); | |
| 238 | |
| 239 pending_swap_cache_callback_ = callback; | |
| 240 pending_callback_param_ = callback_param; | |
| 241 if (is_selection_pending()) | |
| 242 return; | |
| 243 | |
| 244 DoPendingSwapCache(); | |
| 245 } | |
| 246 | |
| 247 void AppCacheHost::DoPendingSwapCache() { | |
| 248 DCHECK_EQ(false, pending_swap_cache_callback_.is_null()); | |
| 249 | |
| 250 // 6.9.8 Application cache API | |
| 251 bool success = false; | |
| 252 if (associated_cache_.get() && associated_cache_->owning_group()) { | |
| 253 if (associated_cache_->owning_group()->is_obsolete()) { | |
| 254 success = true; | |
| 255 AssociateNoCache(GURL()); | |
| 256 } else if (swappable_cache_.get()) { | |
| 257 DCHECK(swappable_cache_.get() == | |
| 258 swappable_cache_->owning_group()->newest_complete_cache()); | |
| 259 success = true; | |
| 260 AssociateCompleteCache(swappable_cache_.get()); | |
| 261 } | |
| 262 } | |
| 263 | |
| 264 pending_swap_cache_callback_.Run(success, pending_callback_param_); | |
| 265 pending_swap_cache_callback_.Reset(); | |
| 266 pending_callback_param_ = NULL; | |
| 267 } | |
| 268 | |
| 269 void AppCacheHost::SetSpawningHostId( | |
| 270 int spawning_process_id, int spawning_host_id) { | |
| 271 spawning_process_id_ = spawning_process_id; | |
| 272 spawning_host_id_ = spawning_host_id; | |
| 273 } | |
| 274 | |
| 275 const AppCacheHost* AppCacheHost::GetSpawningHost() const { | |
| 276 AppCacheBackendImpl* backend = service_->GetBackend(spawning_process_id_); | |
| 277 return backend ? backend->GetHost(spawning_host_id_) : NULL; | |
| 278 } | |
| 279 | |
| 280 AppCacheHost* AppCacheHost::GetParentAppCacheHost() const { | |
| 281 DCHECK(is_for_dedicated_worker()); | |
| 282 AppCacheBackendImpl* backend = service_->GetBackend(parent_process_id_); | |
| 283 return backend ? backend->GetHost(parent_host_id_) : NULL; | |
| 284 } | |
| 285 | |
| 286 AppCacheRequestHandler* AppCacheHost::CreateRequestHandler( | |
| 287 net::URLRequest* request, | |
| 288 ResourceType::Type resource_type) { | |
| 289 if (is_for_dedicated_worker()) { | |
| 290 AppCacheHost* parent_host = GetParentAppCacheHost(); | |
| 291 if (parent_host) | |
| 292 return parent_host->CreateRequestHandler(request, resource_type); | |
| 293 return NULL; | |
| 294 } | |
| 295 | |
| 296 if (AppCacheRequestHandler::IsMainResourceType(resource_type)) { | |
| 297 // Store the first party origin so that it can be used later in SelectCache | |
| 298 // for checking whether the creation of the appcache is allowed. | |
| 299 first_party_url_ = request->first_party_for_cookies(); | |
| 300 return new AppCacheRequestHandler(this, resource_type); | |
| 301 } | |
| 302 | |
| 303 if ((associated_cache() && associated_cache()->is_complete()) || | |
| 304 is_selection_pending()) { | |
| 305 return new AppCacheRequestHandler(this, resource_type); | |
| 306 } | |
| 307 return NULL; | |
| 308 } | |
| 309 | |
| 310 void AppCacheHost::GetResourceList( | |
| 311 AppCacheResourceInfoVector* resource_infos) { | |
| 312 if (associated_cache_.get() && associated_cache_->is_complete()) | |
| 313 associated_cache_->ToResourceInfoVector(resource_infos); | |
| 314 } | |
| 315 | |
| 316 AppCacheStatus AppCacheHost::GetStatus() { | |
| 317 // 6.9.8 Application cache API | |
| 318 AppCache* cache = associated_cache(); | |
| 319 if (!cache) | |
| 320 return APPCACHE_STATUS_UNCACHED; | |
| 321 | |
| 322 // A cache without an owning group represents the cache being constructed | |
| 323 // during the application cache update process. | |
| 324 if (!cache->owning_group()) | |
| 325 return APPCACHE_STATUS_DOWNLOADING; | |
| 326 | |
| 327 if (cache->owning_group()->is_obsolete()) | |
| 328 return APPCACHE_STATUS_OBSOLETE; | |
| 329 if (cache->owning_group()->update_status() == AppCacheGroup::CHECKING) | |
| 330 return APPCACHE_STATUS_CHECKING; | |
| 331 if (cache->owning_group()->update_status() == AppCacheGroup::DOWNLOADING) | |
| 332 return APPCACHE_STATUS_DOWNLOADING; | |
| 333 if (swappable_cache_.get()) | |
| 334 return APPCACHE_STATUS_UPDATE_READY; | |
| 335 return APPCACHE_STATUS_IDLE; | |
| 336 } | |
| 337 | |
| 338 void AppCacheHost::LoadOrCreateGroup(const GURL& manifest_url) { | |
| 339 DCHECK(manifest_url.is_valid()); | |
| 340 pending_selected_manifest_url_ = manifest_url; | |
| 341 storage()->LoadOrCreateGroup(manifest_url, this); | |
| 342 } | |
| 343 | |
| 344 void AppCacheHost::OnGroupLoaded(AppCacheGroup* group, | |
| 345 const GURL& manifest_url) { | |
| 346 DCHECK(manifest_url == pending_selected_manifest_url_); | |
| 347 pending_selected_manifest_url_ = GURL(); | |
| 348 FinishCacheSelection(NULL, group); | |
| 349 } | |
| 350 | |
| 351 void AppCacheHost::LoadSelectedCache(int64 cache_id) { | |
| 352 DCHECK(cache_id != kAppCacheNoCacheId); | |
| 353 pending_selected_cache_id_ = cache_id; | |
| 354 storage()->LoadCache(cache_id, this); | |
| 355 } | |
| 356 | |
| 357 void AppCacheHost::OnCacheLoaded(AppCache* cache, int64 cache_id) { | |
| 358 if (cache_id == pending_main_resource_cache_id_) { | |
| 359 pending_main_resource_cache_id_ = kAppCacheNoCacheId; | |
| 360 main_resource_cache_ = cache; | |
| 361 } else if (cache_id == pending_selected_cache_id_) { | |
| 362 pending_selected_cache_id_ = kAppCacheNoCacheId; | |
| 363 FinishCacheSelection(cache, NULL); | |
| 364 } | |
| 365 } | |
| 366 | |
| 367 void AppCacheHost::FinishCacheSelection( | |
| 368 AppCache *cache, AppCacheGroup* group) { | |
| 369 DCHECK(!associated_cache()); | |
| 370 | |
| 371 // 6.9.6 The application cache selection algorithm | |
| 372 if (cache) { | |
| 373 // If document was loaded from an application cache, Associate document | |
| 374 // with the application cache from which it was loaded. Invoke the | |
| 375 // application cache update process for that cache and with the browsing | |
| 376 // context being navigated. | |
| 377 DCHECK(cache->owning_group()); | |
| 378 DCHECK(new_master_entry_url_.is_empty()); | |
| 379 DCHECK_EQ(cache->owning_group()->manifest_url(), preferred_manifest_url_); | |
| 380 AppCacheGroup* owing_group = cache->owning_group(); | |
| 381 const char* kFormatString = | |
| 382 "Document was loaded from Application Cache with manifest %s"; | |
| 383 frontend_->OnLogMessage( | |
| 384 host_id_, APPCACHE_LOG_INFO, | |
| 385 base::StringPrintf( | |
| 386 kFormatString, owing_group->manifest_url().spec().c_str())); | |
| 387 AssociateCompleteCache(cache); | |
| 388 if (!owing_group->is_obsolete() && !owing_group->is_being_deleted()) { | |
| 389 owing_group->StartUpdateWithHost(this); | |
| 390 ObserveGroupBeingUpdated(owing_group); | |
| 391 } | |
| 392 } else if (group && !group->is_being_deleted()) { | |
| 393 // If document was loaded using HTTP GET or equivalent, and, there is a | |
| 394 // manifest URL, and manifest URL has the same origin as document. | |
| 395 // Invoke the application cache update process for manifest URL, with | |
| 396 // the browsing context being navigated, and with document and the | |
| 397 // resource from which document was loaded as the new master resourse. | |
| 398 DCHECK(!group->is_obsolete()); | |
| 399 DCHECK(new_master_entry_url_.is_valid()); | |
| 400 DCHECK_EQ(group->manifest_url(), preferred_manifest_url_); | |
| 401 const char* kFormatString = group->HasCache() ? | |
| 402 "Adding master entry to Application Cache with manifest %s" : | |
| 403 "Creating Application Cache with manifest %s"; | |
| 404 frontend_->OnLogMessage( | |
| 405 host_id_, APPCACHE_LOG_INFO, | |
| 406 base::StringPrintf(kFormatString, | |
| 407 group->manifest_url().spec().c_str())); | |
| 408 // The UpdateJob may produce one for us later. | |
| 409 AssociateNoCache(preferred_manifest_url_); | |
| 410 group->StartUpdateWithNewMasterEntry(this, new_master_entry_url_); | |
| 411 ObserveGroupBeingUpdated(group); | |
| 412 } else { | |
| 413 // Otherwise, the Document is not associated with any application cache. | |
| 414 new_master_entry_url_ = GURL(); | |
| 415 AssociateNoCache(GURL()); | |
| 416 } | |
| 417 | |
| 418 // Respond to pending callbacks now that we have a selection. | |
| 419 if (!pending_get_status_callback_.is_null()) | |
| 420 DoPendingGetStatus(); | |
| 421 else if (!pending_start_update_callback_.is_null()) | |
| 422 DoPendingStartUpdate(); | |
| 423 else if (!pending_swap_cache_callback_.is_null()) | |
| 424 DoPendingSwapCache(); | |
| 425 | |
| 426 FOR_EACH_OBSERVER(Observer, observers_, OnCacheSelectionComplete(this)); | |
| 427 } | |
| 428 | |
| 429 void AppCacheHost::OnServiceReinitialized( | |
| 430 AppCacheStorageReference* old_storage_ref) { | |
| 431 // We continue to use the disabled instance, but arrange for its | |
| 432 // deletion when its no longer needed. | |
| 433 if (old_storage_ref->storage() == storage()) | |
| 434 disabled_storage_reference_ = old_storage_ref; | |
| 435 } | |
| 436 | |
| 437 void AppCacheHost::ObserveGroupBeingUpdated(AppCacheGroup* group) { | |
| 438 DCHECK(!group_being_updated_.get()); | |
| 439 group_being_updated_ = group; | |
| 440 newest_cache_of_group_being_updated_ = group->newest_complete_cache(); | |
| 441 group->AddUpdateObserver(this); | |
| 442 } | |
| 443 | |
| 444 void AppCacheHost::OnUpdateComplete(AppCacheGroup* group) { | |
| 445 DCHECK_EQ(group, group_being_updated_); | |
| 446 group->RemoveUpdateObserver(this); | |
| 447 | |
| 448 // Add a reference to the newest complete cache. | |
| 449 SetSwappableCache(group); | |
| 450 | |
| 451 group_being_updated_ = NULL; | |
| 452 newest_cache_of_group_being_updated_ = NULL; | |
| 453 | |
| 454 if (associated_cache_info_pending_ && associated_cache_.get() && | |
| 455 associated_cache_->is_complete()) { | |
| 456 AppCacheInfo info; | |
| 457 FillCacheInfo( | |
| 458 associated_cache_.get(), preferred_manifest_url_, GetStatus(), &info); | |
| 459 associated_cache_info_pending_ = false; | |
| 460 frontend_->OnCacheSelected(host_id_, info); | |
| 461 } | |
| 462 } | |
| 463 | |
| 464 void AppCacheHost::SetSwappableCache(AppCacheGroup* group) { | |
| 465 if (!group) { | |
| 466 swappable_cache_ = NULL; | |
| 467 } else { | |
| 468 AppCache* new_cache = group->newest_complete_cache(); | |
| 469 if (new_cache != associated_cache_.get()) | |
| 470 swappable_cache_ = new_cache; | |
| 471 else | |
| 472 swappable_cache_ = NULL; | |
| 473 } | |
| 474 } | |
| 475 | |
| 476 void AppCacheHost::LoadMainResourceCache(int64 cache_id) { | |
| 477 DCHECK(cache_id != kAppCacheNoCacheId); | |
| 478 if (pending_main_resource_cache_id_ == cache_id || | |
| 479 (main_resource_cache_.get() && | |
| 480 main_resource_cache_->cache_id() == cache_id)) { | |
| 481 return; | |
| 482 } | |
| 483 pending_main_resource_cache_id_ = cache_id; | |
| 484 storage()->LoadCache(cache_id, this); | |
| 485 } | |
| 486 | |
| 487 void AppCacheHost::NotifyMainResourceIsNamespaceEntry( | |
| 488 const GURL& namespace_entry_url) { | |
| 489 main_resource_was_namespace_entry_ = true; | |
| 490 namespace_entry_url_ = namespace_entry_url; | |
| 491 } | |
| 492 | |
| 493 void AppCacheHost::NotifyMainResourceBlocked(const GURL& manifest_url) { | |
| 494 main_resource_blocked_ = true; | |
| 495 blocked_manifest_url_ = manifest_url; | |
| 496 } | |
| 497 | |
| 498 void AppCacheHost::PrepareForTransfer() { | |
| 499 // This can only happen prior to the document having been loaded. | |
| 500 DCHECK(!associated_cache()); | |
| 501 DCHECK(!is_selection_pending()); | |
| 502 DCHECK(!group_being_updated_); | |
| 503 host_id_ = kAppCacheNoHostId; | |
| 504 frontend_ = NULL; | |
| 505 } | |
| 506 | |
| 507 void AppCacheHost::CompleteTransfer(int host_id, AppCacheFrontend* frontend) { | |
| 508 host_id_ = host_id; | |
| 509 frontend_ = frontend; | |
| 510 } | |
| 511 | |
| 512 void AppCacheHost::AssociateNoCache(const GURL& manifest_url) { | |
| 513 // manifest url can be empty. | |
| 514 AssociateCacheHelper(NULL, manifest_url); | |
| 515 } | |
| 516 | |
| 517 void AppCacheHost::AssociateIncompleteCache(AppCache* cache, | |
| 518 const GURL& manifest_url) { | |
| 519 DCHECK(cache && !cache->is_complete()); | |
| 520 DCHECK(!manifest_url.is_empty()); | |
| 521 AssociateCacheHelper(cache, manifest_url); | |
| 522 } | |
| 523 | |
| 524 void AppCacheHost::AssociateCompleteCache(AppCache* cache) { | |
| 525 DCHECK(cache && cache->is_complete()); | |
| 526 AssociateCacheHelper(cache, cache->owning_group()->manifest_url()); | |
| 527 } | |
| 528 | |
| 529 void AppCacheHost::AssociateCacheHelper(AppCache* cache, | |
| 530 const GURL& manifest_url) { | |
| 531 if (associated_cache_.get()) { | |
| 532 associated_cache_->UnassociateHost(this); | |
| 533 } | |
| 534 | |
| 535 associated_cache_ = cache; | |
| 536 SetSwappableCache(cache ? cache->owning_group() : NULL); | |
| 537 associated_cache_info_pending_ = cache && !cache->is_complete(); | |
| 538 AppCacheInfo info; | |
| 539 if (cache) | |
| 540 cache->AssociateHost(this); | |
| 541 | |
| 542 FillCacheInfo(cache, manifest_url, GetStatus(), &info); | |
| 543 frontend_->OnCacheSelected(host_id_, info); | |
| 544 } | |
| 545 | |
| 546 } // namespace appcache | |
| OLD | NEW |